从阮老师博客的一道测试题说起:
代码段一:
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()());
代码段二:
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name; }; } }; alert(object.getNameFunc()());
这两段代码是为了巩固javascript中闭包的用法,但是如果不了解javascript中this的用法的话,很难理解这两段代码的真正意思。
从这个例子入手,首先了解javascript中this的指向。
This
1、this的指向是由它所在函数调用的上下文决定的,而不是由它所在函数定义的上下文决定的;
2、当一个函数作为函数而不是方法来调用的时候,this指向的是全局对象,反之this指向方法前的对象(也就是说当出现 [对象].[函数名] 时,this指向是[对象])。
demo1:指向方法前的对象
var obj = { x:20, f:function(){console.log(this.x);} }; obj.f(); //输出20,f()前有obj对象所以this指向obj obj.innerobj = { x:30, f:function(){console.log(this.x);} } obj.innerobj.f(); //输出30 注:此时当出现多个 . 时,要看最后函数前的 . 本例中为obj.innerobj.
demo2:指向全局对象
/*example 2*/ var x = 10; var obj = { x:20, f:function(){ console.log(this.x); var foo = function(){ console.log(this.x); } foo(); } }; obj.f(); //输出20和10 在执行f函数中的foo()函数时,由于foo()前没有对象名,故默认为全局对象,输出10 /*example 3*/ var x = 10; var obj = { x:20, f:function(){ console.log(this.x); } }; obj.f(); //输出20 var fOut = obj.f; fOut(); //输出10 fOut()前没有对象名,所以默认为全局变量 var obj2 = { x:30, f:obj.f } obj2.f(); //输出30 f()前对象时obj2,故this指向obj2
3、this指向利用call或apply所指派给this的对象
有时候我们需要人为的修改this指向,那么我们就需要用到call或者apply具体用法如下:
(A对象).函数名.call(B对象,参数1,参数2,参数3,......);//使用此方法函数this指向B对象(若B对象为空则指向全局对象)
(A对象).函数名.apply(B对象,[参数1,参数2,参数3,......]);//使用此方法函数this指向B对象,且参数通过数组传递(若B对象为空则指向全局对象)
不多说看例子:
/*example 4*/ var obj = { x:20, f:function(){ console.log(this.x); } }; var obj2 = { x:30 }; obj.f.call(obj2); //输出30而不是obj中的20 因为使用了call();
4、this指向new所产生的新对象
即:当函数当做构造函数来使用时,函数内部的this则指向于new出的新对象。
function Student(){ this.name="Leon"; this.sex = "male"; this.age=20; }; var stu = new Student(); console.log(stu.sex); //输出male Student()中this指向了stu 故赋值给new出的stu对象
5、callback函数内的this会指向于,调用放入该callback的函数的this所指向的对象
作用域链