求解答作用域问题

不明白这段代码的执行结果,是undefined,1s后是0,求大神帮忙解释下?
图片描述

var a = 0;
var obj = {
 a:'obj',
 b:function(a){
 setTimeout(function(){
 console.log(this.a);
 },1000)
 }
}
obj.b(1);

作为对象方法调用,this不是应该指向这个对象么,也就是obj对象,这样获得的this.a应该是'obj'了,请大神帮忙解答。

阅读 2.8k
5 个回答

首先,undefined是因为你的obj.b这个函数没有返回值,所以会显示返回的是undefined;

然后this对象的指向是因为,你利用了setTimeout异步操作,1s后this指针不再指向obj这个对象了,而是指向了全局的windows这个对象,所以this.a也就是window.a,也就会输出0

如果你把setTimeout去掉 输出的就会是你obj里面的a

——————————————————————————
补充个传送门
https://segmentfault.com/q/10...


clipboard.png

setTimeout中你定义的是一个匿名函数,如果不适用es6的箭头函数,默认这个匿名函数的上下文对象,也就是this指向的是window.

两个方案:

var a = 0;
var obj = {
 a:'obj',
 b:function(a){
 setTimeout(function(){
 console.log(this.a);
 }.bind(this),1000)
 }
}
obj.b(1);
var a = 0;
var obj = {
 a:'obj',
 b:function(a){
 setTimeout(()=>{
 console.log(this.a);
 },1000)
 }
}
obj.b(1);

setTimeout里你写了个闭包 闭包中this指向window;

var a = 0;
var obj = {
 a:'obj',
 b:function(a){
 //或者 
 //var _self = this;
 //setTimeout(()=>{
 //console.log(_self .a);
 // },1000)
 setTimeout(()=>{
 console.log(this.a);
 },1000)
 }
}
obj.b(1);

这样就可以输出'obj'了

出undefined的时候,应该很好理解,后面出来0,是因为闭包函数是里面this是全局的

clipboard.png

clipboard.png
把你的代码跑了一下,b:function(a) 你这里的a并不是你定义obj下的a;所以会 undefined;

clipboard.png

clipboard.png
如果你这里定义了传入的参数以后,就可以得到这个参数的值了。

推荐问题