为什么Function.prototype.call()的执行时机早于console.log()?
问题现象解释
这个现象和Function.prototype.call()的执行顺序无关,是浏览器开发者控制台的引用类型打印延迟求值特性导致的视觉错觉,代码的实际执行顺序完全符合书写逻辑。
实际执行顺序说明
你给出的代码执行时,严格按照以下顺序运行:
- 执行
new Food()时,首先创建一个空对象,将构造函数内的this绑定到该空对象 - 先执行
console.log(this):此时this指向的对象确实没有name、price属性 - 再执行
Product.call(this, 'cheese', 5):通过call方法将Product内的this绑定到当前实例,给实例挂载name: 'cheese'、price: 5两个属性 - 最后执行
this.category = 'food',给实例挂载category属性
控制台打印错觉的原因
浏览器控制台打印引用类型(比如对象、数组)时,不会立刻保存该对象当前所有属性的快照,只会在你手动点击展开打印结果的箭头时,才去读取该对象当前的最新属性值。
你看到展开后的对象有name、price,是因为你点击展开的时候,后续的Product.call已经执行完成,对象属性已经被更新了。
验证方法
你可以把console.log(this)替换为以下任意一种写法,就能看到打印时刻的真实状态:
- 打印序列化后的对象快照:
console.log(JSON.parse(JSON.stringify(this)))
- 直接打印具体的基础类型属性值:
console.log(this.name, this.price) // 会输出undefined undefined,符合执行顺序的预期
内容的提问来源于stack exchange,提问作者sina
相关产品推荐
相关产品推荐

