作家
登录

关于javascript中this关键字(翻译+自我理解)

作者: 来源:www.28hudong.com 2013-03-30 01:14:54 阅读 我要评论

下文有大概70%的内容出自http://www.quirksmode.org/js/this.html,另外30%是我自己对它的理解和感想。希望能对有需要的人一点帮助。。。 首先,先看一个很典型的关于this关键字题目:复制代码 代码如下: var name = 'hong' var obj = { name: 'ru', getName: function(){ return function(){ return this.name; }; } } alert(obj.getName()()); 这里也不卖关子了,执行结果为:hong 稍微改下代码: 复制代码 代码如下: var name = 'hong' var obj = { name: 'ru', getName: function(){ var that = this; return function(){ return that.name; }; } } alert(obj.getName()()); 执行结果为:ru 执行结果为:ru 关于出现这种结果的原因,下面会细细讨论。 【函数的拥有者】 要解释this,要先说这个概念。在JavaScript里,this始终指向我们当前正在执行的函数的“拥有者”。更为确切的说:是指向把这个函数作为方法的对象。 这句话怎么理解,我们可以看看下面的例子: 复制代码 代码如下: /* -- test1 -- */ function test1 () { this.title = 'me'; alert(window['title']); alert(this === window); //true } test1(); 执行结果为:me, true 在上例中,this是指向window对象的。并把window这个对象的title属性写为'me',因为test1是个顶级函数,所以它的拥有者是window对象,或者说它是window对象的一个方法。这个应该不难理解。比如上面调用test1()时,也可以写成 window.test1();这样的明了了。   接下来,我们建一个div,并把test1作为方法赋给div的onclick属性: 复制代码 代码如下: <div id="o" style="width:50px;height:50px;border:4px solid #333">me!</div> <script type="text/javascript"> /* -- test1 -- */ function test1 () { this.title = 'me'; alert(window['title']); alert(this === window); } var o = document.getElementById('o'); o.onclick = test1; </script> 点击div结果为:undefined, false; 同时我们用firebug可以看到‘me'这个属性值其实是被赋给了id为‘o'的这个HtmlObject显而易见,此时this指向了这个div,也就是说,test1()的拥有者变成了div这个HtmlObject,或者说它变成了div的onclick方法来调用。这种情况应该还是容易理解的。 下面我们接着改代码,就改一个地方: 复制代码 代码如下: o.onclick = test1(); // 注意:这里加了个括号 把上面代码的最后一句改成这样后,点击div运行的结果为:me, true 变成了和第一种情况一样了,this指向了window。有人会纳闷,觉得没什么区别,其实是有区别的。这里涉及到函数的copy和refer的问题。   【函数的Copy】   如果通过 复制代码 代码如下: o.onclick = test1; 这样的方式的话,其实是把test1() 这个函数Copy给了对象 o 的 onclick 属性。因此test1的拥有者变成了 o 这个对象。   如果通过 复制代码 代码如下: o.onclick = test1(); 这样的方式的话,本质上是指当获取到点击事件的handle时,指引它去执行test1()函数。注意是指引去执行而不是赋给它去执行。test1()的拥有者没变,还是window.   【函数的Refer】   同上,我们通过inline的方式把调用写到html里来调用的话,还是refer的方式 复制代码 代码如下: <div id="o" style="width:50px;height:50px;border:4px solid #333" onclick="test1()">me!</div> 点击div执行结果还是表示this指向window。   【函数copy的例子】 复制代码 代码如下: element.onclick = doSomething element.addEventListener('click',doSomething,false) element.onclick = function () {this.style.color = '#cc0000';} <element onclick="this.style.color = '#cc0000';"> 这几种方式都会使this的指向变为当前调用的object。   【函数refer的例子】 复制代码 代码如下: element.onclick = function () {doSomething()} element.attachEvent('onclick',doSomething) <element onclick="doSomething()"> 这几种方式都不会改变函数的拥有者,其中要注意的是addEventListener和attachEvent是不一致的,因为attachEvent其实是建立了一个reference到了doSomething,而不是copy了这个函数。   【用call的方式】 刚才我们说了,写成<element onclick="test()">的方式还是不能让test()的拥有者变成<element>,那我们可以这样做 复制代码 代码如下: <element onclick="test(this)"> function (o) { o.title = 'me'; } 这样显式的调用是可以的。或者,用call或apply这种对象冒充的继承方式也可以 复制代码 代码如下: <element onclick="test.call(this)"> function test () { this.title = 'me'; } 这也是对象冒充最典型的方式。   【自由变量问题】   写了这么长,我们还是回到最开始的那个问题: 复制代码 代码如下: var name = 'hong' var obj = { name: 'ru', getName: function(){ return function(){ return this.name; }; } } alert(obj.getName()()); 为什么这种方式得到的结果会是:hong 呢?重点在 复制代码 代码如下: return function(){ return this.name; }; 对比一下上面写的函数refer的例子,不难发现,返回的这个匿名函数的调用方式和onclick = function () {doSomething()} 如出一辙。所以这种方式并不会改变这个function的拥有者,它虽然是个嵌套函数,但是它的声明却是顶级的。其中的this指向的是window。   而第二种方式是强制在getName()中把this赋给了that,也就是说,that.name其实和getName()中的this.name是一样的。而在getName的上下文中,它的拥有者是obj这个对象,所以this会指向obj,故this.name === obj.name;   绕了这么一大圈不知道有没有把各位绕明白。   其实可以这样总结:在this所在的函数上下文中,如果这个函数不是以“方法”的形式被调用的话,那么这个this会指向window对象,否则会指向这个函数的拥有者。

  推荐阅读

  为jQuery.Treeview添加右键菜单的实现代码

先上图: jquery.treeview 数据通过JSON数据加载,有需要的朋友,可以通jquery的AJAX方法获取相关的JSON数据 json的数据格式:{"id":1,"parentid":0,"title":"标题","children":[{ ...}]} 需要两个jQuery 两件 (j>>>详细阅读


本文标题:关于javascript中this关键字(翻译+自我理解)

地址:http://www.17bianji.com/kaifa2/JS/25568.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)