Javascript学习笔记之 函数篇(二) : this 的工作机制
全局作用域下
this;
当在全局作用域中使用this,它指向全局对象。
这里详细介绍下全局对象:
全局对象(Globalobject)是在进入任何执行上下文之前就已经创建了的对象;
这个对象只存在一份,它的属性在程序中任何地方都可以访问,全局对象的生命周期终止于程序退出那一刻。
全局对象初始创建阶段将Math、String、Date、parseInt作为自身属性,等属性初始化,同样也可以有额外创建的其它对象作为属性(其可以指向到全局对象自身)。例如,在DOM中,全局对象的window属性就可以引用全局对象自身。
所以在console内输入window和this.window是一样的。
调用一个函数时
foo();
在这里,this同样指向全局对象。
调用一个方法时
test.foo();
在这个例子中,this将会指向test对象。
调用一个构造函数时
newfoo();
一个函数在被调用时和关键字new一起使用,我们称之为构造函数。此时在函数内,this指向新建的对象。
显式设置时
functionfoo(a,b,c){}//
varbar={};
foo.apply(bar,[1,2,3]);//arraywillexpandtothebelow
foo.call(bar,1,2,3);//resultsina=1,b=2,c=3
当使用Function.prototype的apply和call方法时,this的值为显式设置为该方法的第一个参数。
因此,不同于调用一个函数时的规则,上例中this指向了bar。
这里介绍下call和apply方法:
call方法:
语法:call([thisObj[,arg1[,arg2[, [,.argN]]]]])
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
apply方法:
语法:apply([thisObj[,argArray]])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
在这里我们要注意一点,在对象的字面声明时,this不能用来指向对象本身。如下:
varobj={me:this}
这里,this不会指向obj,this的应用只限于以上五种情形。
总结
尽管上述情形在大多时候是有意义的,但是第二种情形(即调用一个函数时)的this实际上是很少有用途的,这被认为是Javascript设计上的另一个错误。
Foo.method=function(){
functiontest(){
//thisissettotheglobalobject
}
test();
}
根据我们上面所述,这里的this将会指向全局对象,而不是Foo函数。
为了在test中获得指向Foo的途径,我们需要在method内部创建一个局部变量指向Foo。
Foo.method=function(){
varthat=this;
functiontest(){
//Usethatinsteadofthishere
}
test();
}
that只是普通的变量名,但是它经常被用来指向外部的this。
还有一个比较有意思的地方与函数别名相关,即将一个方法赋值给一个变量时。
vartest=someObject.methodTest; test();
上例中,test将会被当做一个普通函数看待,所以根据第二种情形(即调用一个函数时),其内部的this将会指向全局变量,而不是someObject。
尽管,this晚绑定初看上去是个不好的决定,但实际上这是原型式继承工作的基础。
functionFoo(){}
Foo.prototype.method=function(){};
functionBar(){}
Bar.prototype=Foo.prototype;
newBar().method();
此时,当method被调用时,它将指向Bar的实例对象。