一、深入理解一下obj.method()的工作原理
1.1 仔细观察,我们可以发现obj.method()这个表达式由两部分组成:
- obj.method:首先是.点操作符,用来检索对象的属性
- 然后是小括号():执行该方法
1.2 这两部分是如何协作的?理解了这个问题,自然就明白为何this会丢失了。
let user = {
nickname: 'duola',
sayHello() {
console.log(this.nickname)
}
}
let sayHey = user.sayHello //第一部分
sayHey(); // 第二部分
- 在第一部分,我们将方法
sayHello赋值给了变量sayHey,紧接着我们执行了该方法。
- 为了确保
user.sayHello()可以正常调用,JavaScript使用了一些小技巧——事实上,点操作符返回的并不是函数,而是一个特别的Reference Type。
- 这个特别的
Reference Type的值由3个值构成——(base, name, strict)
- base :是点操作符前面的对象
- name :是属性名
- strict : 是否使用严格模式
- 当执行第二部分(也就是小括号去调用这个特别的
Reference Type)时,Reference Type的值((base, name, strict))会完整的被传递接收,这时候就可以接收到正确的this,在本例中也就是user
Reference Type是一个特殊的中间量,它的目的就是在点操作符和小括号操作符之间传递信息。
- 点操作符和小括号操作符不可以分开,一旦分开,比如
let sayHey = user.sayHello,那么中间量Reference Type将被整体丢弃,它所拥有的信息也将丢失!这就是在隐式绑定时,this会丢失的真正原因!
- 因此,直接使用
obj.method()形式或者obj['method']()是避免this丢失的唯一方式!