先来看一个问题:
let user = {
name: "John",
hi() { console.log(this.name); }
};
(user.hi)(); //(1)
let hi = user.hi;
hi(); //(2)
(user.name == "John" ? user.hi : user.bye)(); //(3)
(1)(2)(3) 分别输出什么?为什么?
运行一下代码,从结果可以看到,(2)和(3)丢失了this,(1)没有。
(1) 先执行了'.' 取了属性 user.hi 的值,然后()执行了它。事实上,这里'.' 运算返回的不是一个函数,而是一个特殊的 Reference Type 的值。
Reference Type 是 ECMA 中的一个“规范类型”,它被用在 JavaScript 语言内部,不能直接使用。它是一个三个值的组合 (base, name, strict),其中:
base是对象。name是属性名。strict在use strict模式下为true。
对Reference Type调用(),能够传递对象方法和源对象,得到正确的this。
进行任何其它操作,Referenct Type都会自动变成属性name的值,丢失其它信息。所以任何使用表达式从对象动态地获取一个方法的操作,都会导致this的丢失。
本文解析JavaScript中,通过user对象动态获取方法hi时,(1)为何能保持this,(2)和(3)为何丢失this。详细解释了ReferenceType的工作原理和动态方法调用中this丢失的机制。
5371





