码迷,mamicode.com
首页 > 编程语言 > 详细

javascript的this到底指向谁

时间:2014-10-14 14:12:58      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:blog   http   io   ar   java   for   strong   sp   div   

新手对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的说明里有:

thisArgThe 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到底指向谁

标签:blog   http   io   ar   java   for   strong   sp   div   

原文地址:http://www.cnblogs.com/ArthasCui/p/4022739.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!