基础 ⭐️⭐️⭐️
1. 如何修改闭包中的对象?
如何在不修改下面代码的情况下, 修改 obj 对象
js
var o = (function () {
var obj = {
a: 1,
b: 2
};
return {
get: function (k) {
return obj[k];
}
};
})();参考答案
闭包代码的提权漏洞@必修课 DDD
js
Object.defineProperty(Object.prototype, 'getThis', {
get() {
return this;
}
});
const obj = o.get('getThis');
obj.a = 'new a';
console.log(obj);
// { a: 'new a', b: 2 }注意: 不能直接通过访问原型上的 valueOf 方法获取原对象 obj, 会出现 this 指向问题, 只能通过访问自定义属性(不是方法)的方式
修补漏洞方法
断开原型链
js
Object.setPrototypeOf(obj, null);
// 或者定义的时候指定原型为 null
var obj = Object.create(null);修改 get 方法
js
get: function (k) {
if (obj.hasOwnProperty(k)) {
return obj[k];
}
}2. 让以下的代码成立?
js
var [a, b] = { a: 1, b: 2 };参考答案
一道解构的面试题@必修课 DDD
js
Object.prototype[Symbol.iterator] = function () {
const arr = Object.values(this);
return arr[Symbol.iterator]();
};
// 或者使用生成器
Object.prototype[Symbol.iterator] = function* () {
return yield* Object.values(this);
};3. 下面的代码输出什么?
js
var foo = { bar: 1 };
var arr1 = [1, 2, foo];
var arr2 = arr1.slice(1);
arr2[0]++;
arr2[1].bar++;
foo.bar++;
arr1[2].bar++;
console.log(arr1[1] === arr2[0]);
console.log(arr1[2] === arr2[1]);
console.log(foo.bar);参考答案
值和引用的终极面试题@每日进阶 CCC
js
// false
// true
// 4引用类型的数据在内存中都是按照堆(heap)的方式存储, 依次划出每一步的结构:
var foo = { bar: 1 }, 在堆上创建一个对象{ bar:1 }, 标记其存储地址为A; 把堆上的地址A赋值给变量foo,foo中保存的就是地址Avar arr1 = [1, 2, foo], 在堆上创建数组[1, 2, foo], 其中foo保存的是地址A, 标记新的数组地址为B; 同样的赋值后,arr1中保存的是地址B
js
foo: A
arr1: B
A -> { bar:1 }
B -> [1, 2, A ]var arr2 = arr1.slice(1),slice创建一个新数组, 从下标为1的位置开始截取, 标记新数组地址为C, 赋值给arr2
js
foo: A
arr1: B
arr2: C
A -> { bar:1 }
B -> [1, 2, A ]
C -> [2, A] arr2[0]++, 找到arr2对应的地址C, 然后将对应下标位置的 2 --> 3
js
foo: A
arr1: B
arr2: C
A -> { bar:1 }
B -> [1, 2, A ]
C -> [2, A]
C -> [3, A] arr2[1].bar++, 找到arr2对应地址C, 找到对应下标位置的A, 将A对应的bar1 --> 2
js
foo: A
arr1: B
arr2: C
A -> { bar:1 }
A -> { bar:2 }
B -> [1, 2, A ]
C -> [3, A]foo.bar++, 找到foo对应地址A, 将对应的bar2 --> 3
js
foo: A
arr1: B
arr2: C
A -> { bar:2 }
A -> { bar:3 }
B -> [1, 2, A ]
C -> [3, A]arr1[2].bar++, 找到arr1对应地址B, 找到对应下标位置的地址A, 将对应的bar3 --> 4
js
foo: A
arr1: B
arr2: C
A -> { bar:3 }
A -> { bar:4 }
B -> [1, 2, A ]
C -> [3, A]4. 判断函数是否标记了 async
js
function isAsyncFunction(func) {}参考答案
判断函数是否标记为 async@每日进阶 CCC
js
function isAsyncFunction(func) {
const stringTag = Object.prototype.toString.call(func);
return stringTag === '[object AsyncFunction]';
// 或者
return func[Symbol.toStringTag] === 'AsyncFunction';
}