这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战。
解构赋值
// 考察JS对象解构赋值
// 执行以下代码, 会输出什么结果
var { ...obj } = Object.create({ a: 1 });
console.log(obj.a);
答案:undefined
说明
先来说一下Object.create:
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。(摘自MDN)
也就是说Object.create({ a: 1 })返回一个新对象,带着指定的原型对象和属性{ a: 1 }。 所以输出的Object.create({ a: 1 })是一个空对象,而它的原型链上有a这个属性
而解构赋值不能解构原型链上的属性
所以obj是{},且它的原型链上没有a这个属性。
堆栈和任务执行
// 考察JS的堆栈执行
// 执行以下代码,会堆栈溢出?还是会不停执行?
function func() {
console.log(Date.now())
setTimeout(func, 0);
}
func();
答案:会一直执行
说明
- 调用func函数时候,会将函数放入"调用堆栈"
- 处理调用堆栈时候,执行 setTimeout 方法,调用堆栈会清空
- setTimeout 时间为 0,func将被放入"任务队列"
- 因为"调用堆栈"是空的,事件循环将"任务队列"里的func放入"调用堆栈"执行
- 再次重复 setTimeout,不会导致堆栈溢出
再说一个会溢出的例子
function runStack (n) {
if (n === 0) return 100;
return runStack( n- 2);
}
runStack(50000)
答案:堆栈溢出
说明
这个例子就是调用栈得不到清空,一直压栈导致溢出
Reflect.ownKeys
Object.prototype.a = '111';
var obj = {
[Symbol('a')]: '222'
};
Object.defineProperty(obj, 'b', {
value: '333'
});
const keys = Reflect.ownKeys(obj);
console.log(keys.length)
答案:2
说明
Reflect.ownKeys()得出的是对象自己的所有属性,包括不可枚举的和 Symbol 的属性,但是拿不到原型上的属性。 这个考题有几个点需要掌握
- Object.defineProperty
- Reflect.ownKeys 先说一下Object.defineProperty
Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
静态方法
Reflect.ownKeys()** 返回一个由目标对象自身的属性键组成的数组。