关于js中this指向的问题
关于js中this指向的问题
案例:
var num = 1;{1} var obj={ num : 8, nm : (function(){//{2} this.num *=2;//{3} return function(){ return this.num *=2;{4} } })() }; var dbl = obj.nm; obj.nm(); obj.nm(); obj.nm(); console.log(obj.num);//64 console.log(this.num);//2
解释
【上述问题中其实就是this的指向问题,this指向明白了自然就清楚了!】
1、首先看{1}所指代码:
这句是声明了一个全局变量num=1,即window.num = 1;
2、{2}所指函数是一个自执行函数,也就是该函数会在加载完成后自动调用
nm : (function(){//{2} this.num *=2;//{3} return function(){ return this.num *=2;{4} } })()
{3}所指代码自始至终就只会执行一次,也就是加载完成后由window对象自动调用的一次,因此{3}行中this指的是window对象;
执行obj.nm()实际上是执行的下面这个函数,因此如果是直接调用obj.nm(),{4}中代码指向的是obj;
function(){ return this.num *=2;{4} }
如下,dbl并没有执行,所以并没有起到作用,obj.nm();执行的时候会执行‘function(){return this.num *=2;}’这句代码,也就是this指向的是obj,没执行一次,obj.num就会乘2;
var dbl = obj.nm;//obj.num =8; this.num = 2;
obj.nm();//obj.num =16; this.num = 2;
obj.nm();//obj.num =32; this.num = 2;
obj.nm();//obj.num =64; this.num = 2;
如果修改代码如下,让‘var dbl = obj.nm;’起作用:
var num = 1;{1} var obj={ num : 8, nm : (function(){//{2} this.num *=2;//{3} return function(){ return this.num *=2;{4} } })() }; var dbl = obj.nm; dbl.nm(); dbl.nm(); dbl.nm(); console.log(obj.num);//64 console.log(this.num);//2
此时,自执行函数还是执行一次,但是由于dbl === window.dbl,所以dbl.nm();调用的时候都是有window调用执行的,所以此时{4}中this指向则变为window;
var dbl = obj.nm;//obj.num =8; this.num = 2; dbl.nm();//obj.num =8; this.num = 4; dbl.nm();//obj.num =8; this.num = 8; dbl.nm();//obj.num =8; this.num = 16;
此时想改变this的指向,可以用bind,call,apply达到目的:
bind:
var dbl = obj.nm; dbl.bind(obj)();// obj.num = 16 this.num = 2; dbl.bind(obj)();//obj.num = 32 this.num = 2; dbl.bind(obj)();//obj.num = 64 this.num = 2;
call:
var dbl = obj.nm; dbl.call(obj);// obj.num = 16 this.num = 2; dbl.call(obj);//obj.num = 32 this.num = 2; dbl.call(obj);//obj.num = 64 this.num = 2;
apply:
var dbl = obj.nm; dbl.apply(obj);// obj.num = 16 this.num = 2; dbl.apply(obj);//obj.num = 32 this.num = 2; dbl.apply(obj);//obj.num = 64 this.num = 2;
只要理清了this表示的是谁,问题就变得很容易了。