首页 > 代码库 > javascript的this到底指向谁
javascript的this到底指向谁
新手对this最困惑。
因为javascript的面向对象比较诡异。
我们说, 通常的面向对象, 分为对象和消息。
由于一些课本的讲解问题, 大家通常认为消息就是方法, 就是函数
这个呢, 有的时候也不能说错啦。消息是抽象概念, 方法是具体实现。
而且对于像C#这类的语言来说, 基本上就是用方法来发消息。
可是对于javascript来说问题就大了。
因为对于javascript来说, 方法, 也是对象!
这下麻烦了。 那javascript还有消息么?
这个仁者见仁了。 你认为那个能发消息哪个就是消息好了。 这是题外话不再继续聊。
话说Function成了对象, 最大的问题就是, this是谁?
这个能搞晕一片人,即使不考虑with这种不推荐的情况
永远记住一点:this指向调用者。
*当没有调用者的时候, 指向全局变量(浏览器里是window)
没有调用者, 这个有点反直觉。 实际上这就是javascript不太面向对象的一点。
这里不谈大量空洞的理论, 只给出一个最简单的判断方式:
“当你把方法调用改成apply调用的时候, 你自然就知道如何填写this了”
这个技巧是我自己创造的。 所以不保证权威。 但是很有效。
请注意:该方法不会让你加深任何对this的理解, 只能让你理清整个代码的关系。
这里需要前置知识:apply方法。
MDN描述如下:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
The apply()
method calls a function with a given this
value and arguments
provided as an array (or an array-like object).
用法:
fun.apply(thisArg[, argsArray]
OK, 举个例子:
var a = function(){ alert(this);}var b = "test";a.apply(b);
运行结果, 弹出test
那么这里, 这个函数就很好理解了。 apply的第一个参数是this, 就这么简单。
现在再做一些迷惑人的题就容易多了。
比如这种:
(function(){var a = { name:‘Lina‘, test:function(){ alert(this.name); }}var b = {name:‘arthas‘};b.test = a.test;b.test();})();
最简单的this替换问题。
可能即使你不用我的技巧也能看得出。
我们调用b.test的时候, b就是this。
那么alert(this.name);相当于alert(b.name);, 所以会弹出arthas
换个理解则是:
a.test.apply(b);
因为我们传入了b, 所以b就是this。 弹出就是arthas
换个稍稍复杂点的:
(function(){var a = { name:‘Lina‘, test:function(){ alert(this.name); }}var b = {name:‘arthas‘};var test = a.test;test();})();
经验丰富的会说, 哦,
由于test是单独调用的, 所以this指向window对象。
那么我们要如何理解刚刚的代码呢?
改成这样:
test.apply();
没错, apply里面什么都不填。 在这个情况下, 似乎按照js的逻辑, 不传参数默认给undefined啊?
注意, apply的说明里有:
thisArg
The value of this
provided for the call to fun
. Note that this
may not be the actual value seen by the method: if the method is a function in non-strict mode code, null
and undefined
will be replaced with the global object, and primitive values will be boxed.
看到了吧, apply的第一个参数, 如果什么都不提供,也就是提供undefined, 那么会被替换为global object
在浏览器里, global object就是window了。
但是注意, 这仅仅是在non-strict模式下。
等以后用了use strict会如何呢?
话说这个我还真没研究过。 不过看文档, 估计应该是null吧。
紧接着是面试题最爱搞的:setTimeout
比如:
(function(){ var a = { name:‘arthas‘, test:function(){ setTimeout(function(){ alert(this.name); },100); }, test2:function(){ alert(this.name); } } a.test2(); a.test();})();
跑下来, test2给出的this.name是arthas, 这毫无疑问。
那么setTimeout呢?
setTimeout哪里, 开了一块新的区域来跑, 所以相当于这么个调用:
(function(){ alert(this.name);}).apply();
this是window, 所以show了个window.name
刚好是个空字串。
javascript的this到底指向谁