在《JavaScript高级程序设计》中提到,“this对象是在运行时基于函数的执行环境绑定的。” ,首先我们需要明白执行环境这个概念,在《你不知道的JavaScript》中指出:“call-site:the location in code where a function is called(not where it’s declared).” ,也就是说执行环境是函数被调用时的位置 。
按照我的理解,当函数被调用时,js引擎需要知道这个函数是在哪里被调用的,这时候函数如果声明在某个对象里,js引擎就只需要监听这个对象就可以了。如果不在某个对象里,则关联到全局对象上。所以函数执行环境就是函数所处的对象。
解决完call-site,还有this binding 。这给我感觉就有点像OS的PCB(进程控制块),this就像这个控制块里面的信息,记录了函数的执行环境地址。每个函数在被调用的时候会有一个this指针,指向执行环境。
理论知识差不多,是时候来点实践。
- 例子1
- function foo( ){
- //”use strict”
- console.log( this.a );
- }
- var a = 2;
- foo( ) ; //2
- foo函数的执行环境是全局对象。
- 不过这在严格模式下会报错,因为在严格模式下禁止this指向全局对象。
- ——————————————————————-
- 例子2
- function foo( ){
- console.log( this.a);
- }
- var obj2 = {
- a : 42,
- foo : foo
- }
- var obj1 = {
- a : 2 ,
- obj2 : obj2
- };
- obj1.obj2.foo( ) ; // 42
- 这个例子被调用的foo的执行环境是obj2对象
- —————————————————————
- 例子3
- function foo ( ){
- console.log( this.a );
- }
- var obj = {
- a : 2
- };
- foo.call( obj ); //2
- call , apply和bind函数都可以硬性改变this的指向,而且对改变之后的this指针再次绑定另一个执行环境是没效果的(称之为hard binding)
- —————————————————————–
- 例子4
- function foo( a ){
- this.a = a ;
- }
- var bar = new foo( 2 );
- console.log( bar.a ); //2
- 这个例子是通过new关键字来生成一个对象,而且这种也类似上面的硬性绑定。
- 这3个例子取自《你不知道的JavaScript》,例1被作者称为Default Binding , 例2 被称为 Implict Binding , 例3 被称为Explicit Binding , 例4 被称为 new Binding。
这里还有两个要注意的点
js里调用事件回调函数中this的上下文是全局的,所以通常我们都会
self = this
btn.addEventListener ( ‘click’ ,function (e) {
alert( self.Name)
})
在ES6中,箭头函数的this是绑定在函数声明的时候而非调用的时候。
第一次写博文,排版和组织词汇难免有些不足,这博文主要是我自己的平时学习的总结,如有错误望留言指正,觉得写得还可以的,请读者多多留言,一起交流学习。