在欧洲中世纪,城堡是西欧封建社会的基层核心,但在最高王权与最底层的农奴之间,不止是有一层领主,而是有好几个层次,每个领主的领地都来源于上一级大领主的封赏,同时他可将自己的领地划成数块封给自己的属下(即他的附庸),依次类推,直至最低一等的普通骑士。通常情况下附庸只对他的直接上一级领主负责,从而形成了所谓“我的附庸的附庸不是我的附庸”的原则。
在 ES 5 的世界里,this 隐式绑定时,他就是一个领主,只对他的直接上级领主负责,领主去哪里征战,他就奔赴哪里,赴汤蹈火,在所不辞,而他领主的领主,却不是他的领主......
1. 隐式绑定
在 js 中,我们知道变量都有自己的执行期上下文,一个变量在刚出生(声明)时,它的作用域就已经可知了;但是 this 却不一样,this 是谁直接调用它,它就指向谁!!!(es5)
我们下面就针对这句话进行详细的讲解:
首先还是老规矩,我们上代码:
【案例一】:
var name= "edward" function fn(){ var name = "zhangsan"; console.log(this) // Window console.log(this.name); // edward } var b = fn();
千万千万不可以认为!!!this.name就是this所在的作用域从而认为 this.name是zhangsan !!!
这里的 var b = fn() 实际上可以看成是 var b = window.fn()
其实,只要我们在全局里调用一个函数,其实都是 window 在调用,window 就是全局(Global)。类似的还有:window.alert('hello world') window.setInterval('i am edward'),等等。
【案例二】:链式调用(我的附庸的附庸,不是我的附庸)
1 var name= "edward" 2 function fn(){ 3 var name= "zhangsan"; 4 console.log(this.name); 5 } 6 var obj = { 7 name:"lisi" 8 }; 9 obj.fn = fn; 10 11 obj.fn(); // lisi
如果你刚刚看过案例一,你也许会想,第11行代码是不是要先看成是 window.obj.fn() 。当然这样是没有什么问题的,那么问题来了,到底是window调用了function fn 中的 this, 还是 obj 调用的,funciton fn 中的 this 又该何去何从呢?
需要注意的是,如果想知道某个函数中的 this 到底代表啥意思,当务之急是要找到是谁直接调用的 this,( 注意“直接”二字!!)
在window.obj.fn()这个链式调用中,window相当于国王,obj相当于是被国王册封的贵族,fn()中的 this 就是被贵族册封的下属,这俗话说的好啊,“我的附庸的附庸,不是我的附庸”。眼看着咱这话都说到了这个份儿上了,呵呵,fn 的 this 就发话了:“国王您就算再大,也甭想使唤我,就是这么硬气!”。国王想了想,反正是朕的江山,得嘞。就这样,this 忠心耿耿,一心向着 obj, obj说啥他就信啥,大智若愚。
回到正题,obj.fn() 虽然在全局的范围,但直接调用function fn 中的 this 的,是对象obj:
var obj = { name:"lisi", fn: function () { var name = "zhangsan" console.log(this.name) } }
obj.fn() // "lisi"
再如:
var person1 = { name:'Tom', getName(){ console.log(this); // person1 console.log(this.name); // Tom } }; var person2 = { name:'sam', friend:person1 }; var person3 = { name: 'jam', friend:person2 }; person3.friend.friend.getName() //本质上还是 person1 调用的