关于javascript里面的this,下面函数的执行结果是怎么得来的
var num=1;
var obj={
num:2,
fn:(function(){
this.num+=10;
num=num+10;
var num=3;
return function(){
this.num+=10;
num++;
console.log(num);
}
})()
}
var fn=obj.fn;
fn();//4
obj.fn();//5
console.log(num);//21
console.log(obj.num);//12
</script> 展开
这是一个文字表述起来很麻烦的问题,解释之前先记住一下几点:
Point 1 : 使用 var 声明一个变量,变量声明会被提前到作用域最的最前面,也就是说无论你在什么地方 var 一个变量,这个变量都在代码一开始就被声明了,在函数内声明的变量也是如此
Point 2:所有的函数在被当做函数执行的时候,this 都指向 window(global),ES6除外
然后说你的那段代码:
定义了一个全局的 num = 1;
定一个 obj,并且有一个属性 num = 2
obj 有一属性 fn,fn 的值是通过自动执行函数返回的 function
自动执行函数构成了一个闭包
以上是几个关键的点,下面解释一下 fn :
根据 上文 Point 1 和 Point 2 来看,实际上 fn 的代码等价于下面的代码:
fn : ( function() {
var num; // 根据 Point 1,num 在函数中的声明被提到最前
window.num += 10; // 根据上文 Point 2,函数在自动执行过程中,this 指向的是 global
num = num + 10; // num 被声明,但是没有赋值,所以 num == undefined,所以 num + 10 会是 NaN
num = 3; // num 被赋值为 3
return function() {
this.num += 10;
num++; // 这个作用域内没有 num,但是因为形成了闭包,所以这个 num 是外层函数的 num,就是被赋值成了 3 的那个。
console.log( num );
}
} )()
下面看你执行的代码:
var fn=obj.fn; fn();
num 初始值是3, 所以 num++ 是 4,同时 fn 被以普通函数来执行,所以里面的 this 指向 window,this.num 改变的是最外层 num 的值,最外层的 num 这时候等于 21 了(在函数自动执行的时候还 + 过10)。
obj.fn();
再执行一次 num++ 值是 5,fn 是被作为 obj 的属性执行的,所以 fn 里面的 this 指向的是 obj.num,所以 obj.num 等于 12
console.log( num );
这个 num 是最外层的 num。
console.log( obj.num );
这个没什么需要说的了。
num:2,
fn:(function(){
this.num+=10;//这个this指向window,就是先前在全局定义var num = 1;现在已经是=11了
num=num+10;//没有指向,但只执行一次
var num=3;
return function(){
this.num+=10;
num++;
console.log(num);
}
})()
}
//定义的时候 里面的匿名函数自执行了一次就得到
obj={
num:2,
fn: //num = 3,这个已经不存在,但是下面的方法用到所以类似于闭包的作用将num保存下来 num=3
function(){
this.num+=10;//现在这里依然是指向全局定义的num
num++;//现在这个已经是4了
console.log(num);
}
}
fn()--》console.log(num);得出的是4 而全局的num 已经是21了
obj.fn();--> 现在执行 function(){
this.num+=10;
num++;//现在这个已经是5了
console.log(num);
}
//方法里面的this现在指向的是obj.num也就是说 2 += 10 --> 12
如果有哪里不对的地方请大神指出,谢谢