前端面试之代码输出结果(一)

463 阅读2分钟

这是我参与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();

答案:会一直执行

说明

  1. 调用func函数时候,会将函数放入"调用堆栈"
  2. 处理调用堆栈时候,执行 setTimeout 方法,调用堆栈会清空
  3. setTimeout 时间为 0,func将被放入"任务队列"
  4. 因为"调用堆栈"是空的,事件循环将"任务队列"里的func放入"调用堆栈"执行
  5. 再次重复 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()**  返回一个由目标对象自身的属性键组成的数组。