先来看一个问题:
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
的丢失。