原文地址:http://www.cnblogs.com/lynxcat/archive/2012/09/01/2666628.html
但凡跟javasript打交道。就万万不会不知道this。
初次接触this,总认为它很强大和神秘。不可预知,似乎有种不为人知的魔力。
因为在接触到它之前,大部分人认为this是那些oop语言的专利。至少我曾经是这么认为的。
随着时间的推移,对javascript的进一步提高。this那神秘的面纱才一步步被揭开。话休绕舌,下面就一起来看看这层神秘的面纱背后的this吧。
首先,我们要知道this是什么。它的含义。通俗的来说, this首先是一个对象,其次要知道的是this不是由它本身出现在何处来决定的。
而是由调用它的对象来决定的,可以简单的理解为。是谁调用了this,那么this便代表谁。比如在全局作用域中调用this。那么此时的this便代表着全局变量。
例:
console.log(this === window)
如上文说所的来分析,如是在全局作用域中。this则代表着全局变量。也就是window,那么事实是不是这样呢。运行上面的代码,输出true。证明this的却是window.
如果this是在一个对象中出现,那么正常情况下。this则代表该对象。
例:
var obj = { fn:function(){ console.log(this === obj); } } obj.fn();//true
弄明白了这两点,this的真相似乎已经浮出水面了。下面我们来看一个复杂点的例子。相信有很多人都会犯错,同时这也是一道经典的面试题。
var length = 20; function fn(){ console.log(this.length); } var o = { length:10, e:function (fn){ fn(); arguments[0](); } } o.e(fn);
相信有不少的同鞋会认为让面会输出 20,20; 也有少部分人认为是10,10; 或者20 10,10 20;
但是很遗憾,上面的答案全部错误。先不急着公布正确答案,我们来分析一下,看看在运行中this到底代表什么。
当运行o.e(fn);时,e中的this代表着o。因为是o调用了e。这点相信大家都没有疑问。
当进入e时。执行fn(); 此时的fn也就是参数传递进来的fn,由于函数名只是保存了一个指向函数的引用。所以此时e内部的fn与外面的fn是一模一样的。又因为函数内部的this是由函数的调用者决定的。所以此时fn内的this代表了window。这点相信当家也没有疑问。
当执行arguments[0]()时,由于arguments[0]是函数的第一个参数,等于fn。所以此时的函数也就等于外部的fn,理论上来说this也应该是等于window的。
似乎这么解释是合理的。 那么正确答案就应该是20,20.那么我又为何说上面的答案中没有一个是正确的呢。那是因为我们忽略了一点。那就是,arguments。
由于arguments[0]().相当与arguments.0(); 也就是说,正真调用fn的是arguments。所以函数内部的this应该是arguemnts,所以。this.length 等于参数的个数,也就是1.正确答案是20 1.
相信大家都明白了吧,那么下面我们就来看看是什么样的机制造就了this。
首先,当一个函数被运行时。他都会进入一个新的执行环境,就算是同一个函数两次调用,异或是函数自身递归调用,它们所进入的执行环境都是不同的。
当进入这个执行环境的时候,就会创建一个活动对象,并且关联到执行环境中。并且随之确定函数的作用域链,this等。所以this的值与它在那里出现没有关联。反而跟函数的调用者有关。
所以,只要记住。this就是调用函数的那个对象。那么this就不会在被this相关的问题给难住啦~