首页 > 代码库 > Javascript---this
Javascript---this
为了解开JavaScript 中 this这个该死 的神秘面孔
连续三天上网查资料,终于有那么一丝丝头绪从脑海闪过
最终搞清楚了这个this黑盒子的第一个机关
为了不让之前的努力及其推断过程被没用的记忆冲刷掉。。。
只好写写日志 随便总结一下
就酱。。。可以启程了
这里研究this 是针对在对象函数内使用时指向:
一般情况下会指向 调用执行当前函数的对象如:
1
var name="window"
var Tom={
name:"Tom",
show:function(){alert(this.name)}
}
Tom.show(); //Tom
因为Tom对象调用show方法,
所以在show方法中this指向Tom
2
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.
var name="window";
var Tom={
name:"Tom".
show:function(){alert(this.name)}
};
var fun=Tom.show();
fun(); //window
因为show方法将函数体赋值给fun后
执行fun时的对象就不再是Tom,而是全局变量window
4.
var name="window";
var Tom={
name:"Tom",
show:function(){alert(this.name)},
wait:function(){
var fun=this.show;
fun();
}
};
Tom.wait(); //window
首先wait方法由Tom调用 所以this.show中的this指向Tom
然后Tom.show的函数体赋值给fun后,执行fun
此时不再是Tom去调用fun,而是没有对象去调用fun
因此调用的fun的对象就会被默认为window对象
那么是什么原因导致对象被更改呢?(不卖关子 答案就在下面)
在一个函数里调用其他函数时,其他函数可以看做这个函数的延迟
上面的例子可以这么看待:
wait方法里执行顺序如下
1.fun变量赋值 //但只是简单的复制Tom.show函数内容,并不会把当前执行的对象复制过来
2.调用函数fun //这里只是指导脚本下一步该怎么做, 在这Tom就算完成任务了
最后再执行fun之前赋值的函数内容,
因此fun函数可以看做Tom的延迟 ,所以fun得不到Tom的调用
下面是个反面例子
5.
var name="window";
var Tom={
name:"Tom",
show:function(){alert(this.name)},
wait:function(){
var that=this;
that.show();
}
};
Tom.wait(); //Tom
这里把wait当前执行的对象 (也就是Tom)给复制过来了
也就是告诉Tom 方法show也由他调用,因此show不算是Tom的延迟
所以wait完成任务后,Tom继续负责show的任务
总之可以看出真正导致当前执行对象被更改的原因----------就是延迟
而解决更改的对象的方法就是让Tom加班!
加班方法 除了像上面保存当前执行的对象外
还可以如下
6.
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()也差不多类似
那么我们现在来研究,除了上面保存函数值后调用该函数值导致的延迟外
还有那些情况是会导致调用延迟 而将当前执行的对象更改为window
7.匿名函数的延迟
貌似能延迟的就以上几种,日后回来补充
9
连续三天上网查资料,终于有那么一丝丝头绪从脑海闪过
最终搞清楚了这个this黑盒子的第一个机关
为了不让之前的努力及其推断过程被没用的记忆冲刷掉。。。
只好写写日志 随便总结一下
就酱。。。可以启程了
这里研究this 是针对在对象函数内使用时指向:
一般情况下会指向 调用执行当前函数的对象如:
1
var name="window"
var Tom={
name:"Tom",
show:function(){alert(this.name)}
}
Tom.show(); //Tom
因为Tom对象调用show方法,
所以在show方法中this指向Tom
2
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.
var name="window";
var Tom={
name:"Tom".
show:function(){alert(this.name)}
};
var fun=Tom.show();
fun(); //window
因为show方法将函数体赋值给fun后
执行fun时的对象就不再是Tom,而是全局变量window
4.
var name="window";
var Tom={
name:"Tom",
show:function(){alert(this.name)},
wait:function(){
var fun=this.show;
fun();
}
};
Tom.wait(); //window
首先wait方法由Tom调用 所以this.show中的this指向Tom
然后Tom.show的函数体赋值给fun后,执行fun
此时不再是Tom去调用fun,而是没有对象去调用fun
因此调用的fun的对象就会被默认为window对象
那么是什么原因导致对象被更改呢?(不卖关子 答案就在下面)
在一个函数里调用其他函数时,其他函数可以看做这个函数的延迟
上面的例子可以这么看待:
wait方法里执行顺序如下
1.fun变量赋值 //但只是简单的复制Tom.show函数内容,并不会把当前执行的对象复制过来
2.调用函数fun //这里只是指导脚本下一步该怎么做, 在这Tom就算完成任务了
最后再执行fun之前赋值的函数内容,
因此fun函数可以看做Tom的延迟 ,所以fun得不到Tom的调用
下面是个反面例子
5.
var name="window";
var Tom={
name:"Tom",
show:function(){alert(this.name)},
wait:function(){
var that=this;
that.show();
}
};
Tom.wait(); //Tom
这里把wait当前执行的对象 (也就是Tom)给复制过来了
也就是告诉Tom 方法show也由他调用,因此show不算是Tom的延迟
所以wait完成任务后,Tom继续负责show的任务
总之可以看出真正导致当前执行对象被更改的原因----------就是延迟
而解决更改的对象的方法就是让Tom加班!
加班方法 除了像上面保存当前执行的对象外
还可以如下
6.
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()也差不多类似
那么我们现在来研究,除了上面保存函数值后调用该函数值导致的延迟外
还有那些情况是会导致调用延迟 而将当前执行的对象更改为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为例子8.setTimeout、setInterval函数延迟
var name="window";
var Tom={
name:"Tom",
show:function(){alert(this.name)},
wait:function(){setTimeout(this.show,1000)}
}
Tom.wait(); //window
貌似能延迟的就以上几种,日后回来补充
9
对于eval函数,其执行时候似乎没有指定当前对象
但实际上其this并非指向window,
因为该函数执行时的作用域是当前作用域
即等同于在该行将里面的代码填进去。下面的例子说明了这个问题:
var name="window";
var Bob={
name:"Bob",
showName: function(){ eval("alert(this.name)"); }
};
Bob.showName(); //Bob
另外 虽然函数延迟会导致对象被更改 但是仍然可以在具有延迟的函数 让Tom加班
10.
上面把this对象改成Tom,然并卵。。。。依旧返回window
因为Tom.show放在setTimeout第一个参数里
只是将告诉setTimeout函数
执行的函数内容是Tom对象里的show方法,
而没有告诉他这个方法由Tom来执行
以下方法可以告诉他
11.
var name="window"
var Bob={
name:"Bob",
showName: function(){ eval("alert(this.name)"); }
};
Bob.showName(); //Bob
另外 虽然函数延迟会导致对象被更改 但是仍然可以在具有延迟的函数 让Tom加班
10.
var name="window";
var Tom={
name:"Tom",
show:function(){alert(this.name)},
wait:function(){setTimeout(Tom.show,1000)}
}
Tom.wait(); //window
上面把this对象改成Tom,然并卵。。。。依旧返回window
因为Tom.show放在setTimeout第一个参数里
只是将告诉setTimeout函数
执行的函数内容是Tom对象里的show方法,
而没有告诉他这个方法由Tom来执行
以下方法可以告诉他
11.
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
12.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环境,也就会指向当前调用执行的对象
Javascript---this
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。