两个例子说明javascript中的‘this’ is not bounded - archering/basic GitHub Wiki

dot 前面de对象决定this的实际归属

javascript 中 函数内部的this, 只有在执行期间才能最终确定this最终代表的是谁。

let user = { name: "John" };
let admin = { name: "Admin" };

function sayHi() {
  alert( this.name );
}

// use the same functions in two objects
user.f = sayHi;
admin.f = sayHi;

// these calls have different this
// "this" inside the function is the object "before the dot"
user.f(); // John  这个时候确定了this   (this == user) 
admin.f(); // Admin 这个时候确定了this  (this == admin)

admin['f'](); // Admin (dot or square brackets access the method – doesn't matter)

上面例子说明,不到最后一刻 你知道this是谁

下面复杂情形

let user = {
  name: "John",
  hi() { alert(this.name); },
  bye() { alert("Bye"); }
};

user.hi(); // John (the simple call works)  这里输出正常  

// now let's call user.hi or user.bye depending on the name
(user.name == "John" ? user.hi : user.bye)(); // Error!   这里换了个马甲就不行了

分解说明下最后一行

(1) (user.name == "John" ? user.hi : user.bye) 这个部分相当于给一个匿名变量赋值,值为一个函数结构

(2) () ; 这部分相当于执行这个匿名变量代表的函数

表现形式如下:
var ano = (user.name == "John" ? user.hi : user.bye)
ano// function () { .... }
ano(); //执行,此时里面的this 就不知道是谁了

为什么直接使用 user.hi() 执行没有问题呢, To make user.hi() calls work, JavaScript uses a trick – the dot '.' returns not a function, but a value of the special Reference Type. 上面这句话,说的很明白,当你使用"." 或者 user["hi"]() 这种形式进行执行函数时,user.hi 这个部分返回一个特殊的引用类型,叫“specification type”.

这个类型的表现形式入下
(base, name, strict)

base is the object.
name is the property.
strict is true if use strict is in effect.

When parentheses () are called on the Reference Type, they ***receive the full information *** about the object and its method, and can set the right this (=user in this case).

Any other operation like assignment hi = user.hi* discards the reference type as a whole, takes the value of user.hi (a function) and passes it on. So any further operation “loses” this.