用 12 个实例总结一下 this 用法
下面列举一些简单的实例,总结一下 this 的一些用法:
1. 方法中的 this 会指向当前执行该方法的对象,如:
var name = "window"
var Tom = {
name:"Tom";
show:function(){alert(this.name)}
}
Tom.show(); // Tom
2. 方法中的 this 不会指向声明它的对象,如下:
var Bob={
name:"Bob",
show:function(){alert(this.name);}
};
var Tom={
name:"Tom",
show:Bob.show
};
Tom.show() ; // Tom
因为尽管 alert(this.name) 是在 Bob 对象环境中声明的,但该方法是由 Tom 对象调用执行所以 this 总是会指向当前执行的对象,而不是声明的对象
3. 将方法复制给变量时,执行时仍然会以 Tom 对象区调用该方法
var name="window";
var Tom={
name:"Tom".
show:function(){alert(this.name)}
};
var fun=Tom.show();
fun(); // Tom
可以看出赋值后再调用,并不影响调用其方法的对象
4. 将对象赋值给变量后,再调用方法,执行的对象仍然是 Tom
var name="window";
var Tom={
name:"Tom",
show:function(){alert(this.name)},
wait:function(){
var that=this;
that.show();
}
};
Tom.wait(); //Tom
这里 that 赋值了当前执行的对象,并让它继续调用 show,所以 show 方法中 alert(this.name) 自然而然的指向了 Tom,可以把上面的 that 赋值对象 然后调用方法 这个过程看做成执行对象的延迟,就是让 Tom 加班的意思
5. 另一种 指明调用方法的对象 的办法,如下:
var name = "window";
var Bob= {
name:"Bob",
show:function(){alert(this.name);}
};
var Tom= {name: "Tom"};
Bob.show(); //Bob
Bob.show.apply(); //window
Bob.show.apply(Tom); //Tom
当然 call() 也差不多类似
6. 下面来个特殊的例子
var name="window";
var Tom={
name:"Tom",
show:function(){alert(this.name)},
wait:function(){
var fun=this.show;
fun();
}
};
Tom.wait(); // window
上面也是赋值方法后,再调用,可是执行的对象却改成了 window 对象
解释:
在函数体内把方法赋值给变量再调用会导致对象更改为 Window 对象,执行 fun 时,可以看做是一种方法调用的延迟行为,延迟调用方法会使得执行的对象,变为全局对象也就是 window 对象。
下面我们来看看其他几种延迟方式,导致对象被更改为 window 的例子
7. 匿名函数的延迟
var name="window";
var Tom={
name:"Tom",
show:function(){alert(this.name)},
wait:function(){!function(call){call();}(this.show)}
}
Tom.wait(); // Window
8. setTimeout、setInterval 函数延迟,这里只以 setTimeout 为例子
var name="window";
var Tom={
name:"Tom",
show:function(){alert(this.name)},
wait:function(){setTimeout(this.show,1000)}
}
Tom.wait(); // window
9. 在延迟的环境下,尝试让 Tom 加班(对象也跟着延迟)
var name="window";
var Tom={ name:"Tom",
show:function(){
alert(this.name)
},
wait:function(){
setTimeout(Tom.show,1000)}
}
Tom.wait(); //window
上面中 this 对象改成了 Tom,尝试让 Tom 加班,但是结果仍然为 Window 对象,因为 Tom.show 放在第一个参数里,延迟的执行使得执行的对象变为 window 对象,而不再是 Tom 对象,如何让执行对象 Tom 在延迟当不被变更呢?下面给你答案
10. 虽然延迟会导致方法的执行对象被更改为 Window 但也有办法防止执行对象更改,如下
var name="window"
var Tom ={
name : "Tom",
show : function(){alert(this.name);},
wait: function(){
var that=this;
setTimeout(function(){that.show()},1000)}
}
Tom.wait(); //Tom
如果不能理解上面的代码,你就当做 Tom 对象也跟着函数一起延迟就好了,而第 9 个例子没有成功延迟,是因为没有变量保存对象使得执行对象没有跟着延迟。
11. eval 函数的延迟
对于 eval 比较特殊,在 eval 环境下,执行的对象就是当前作用域的对象,如下
var name="window";
var Bob={
name:"Bob",
showName: function(){ eval("alert(this.name)"); }
};
Bob.showName(); //Bob
12.eval 函数的环境下,不会受到延迟而影响函数执行的对象
之所以 eval 特殊是因为 eval 不受延迟的影响
var name="window";
var that;
var Tom={
name:"Tom",
show:function(){alert(this.name)},
wait:function(){that=this;setTimeout("that.show()",1000)}
}
Tom.wait(); //Tom
也许你会觉得上面的代码没有 eval 函数的身影,其实 setTimeout 函数的第一个参数就是 eval 环境,他会指向当前执行作用域的执行对象,忽略延迟方法延迟调用。
如果能把上面12个例子都理解了,那么 this 将成为你的一把有力的刀,挥舞在你代码中,当然如果不能理解,那么像闭包一样,尽量的少用!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论