文章翻译自此文章
javascript中最有威力的关键字之一就是this。不幸的是,如果你不彻底了解它是如何工作的话,它会很难使用。下面我介绍了如何在event handling。稍后,我会加入一些this的其他用法。
所有者
接下来我们将要讨论的问题是:在doSomething函数中,this指的是什么?
function doSomething() { this.style.color = ‘#cc0000‘; }
在javascript中,this始终指向我们正在执行的函数的“所有者”,更精确地说,指向把这个函数作为方法的对象。当我们在一个页面定义我们忠实的doSomething函数,他的所有者是这个页面,更精确的说,是javascript的window对象(或者全局对象)。一个onclick属性,被它属于的HTML元素所拥有。这种“所有权”是javascript面向对象方式的结果。通过 对象作为关联数组 这个页面了解更多。
如果我们直接执行doSomething函数,this指向window,这个函数将尝试改变window的style.color,因为window没有style对象(似乎属性更好,但原文如此),这函数将失败并导致一个javascript错误。
复制
所以,如果我们想要充分利用this,我们就要小心的让使用了这个this的函数被正确的HTML元素“拥有”。换句话说,我们不得不将函数拷贝给onclick属性传统的事件注册照顾好了这个:
element.onclick = doSomething;
这个函数被整体拷贝给了onclick属性(它这样就变成了一个方法)因此,如果event handler 被执行,this指向这个HTML元素同时他的color将会改变。
我们当然可以用这种方式拷贝这个函数给几个event handler。每次this将指向正确的HTML元素。
这样你可以最大限度的利用this。每次函数被调用,this指向的HTML元素正在正确的处理事件,HTML元素“拥有”doSomething函数的拷贝。
引用
然而,如果你使用了内联事件注册(inline event registration)
<element onclick="doSomething()">
你这样是没有拷贝这个函数的!相反,你引用了它,引用和拷贝这两者之间的区别是至关重要的。onclick属性没有包含真正的函数,仅仅是一个函数调用:
doSomething();所以,这个表达式的意思是“转到doSomething()并执行它。”当我们到达doSomething(),this关键字有一次指向全局window对象同时函数返回错误消息。
区别
如果你想为了访问那些正在处理事件的HTML元素(accessing the HTML element that is handling the event)而使用this,你必须确保this关键字已经整整的写入了onclick属性中。只有在这种情况,this才指向那些注册了event handler 的HTML元素。因此,如果你这样做:
element.onclick = doSomething;
alert(element.onclick)
你得到的是:
function doSomething() { this.style.color = ‘#cc0000‘; }
正如你所见,this关键字出现在了onclick方法中,因此它指向HTML元素。
但如果你这样做:
<element onclick="doSomething()">
alert(element.onclick)
你得到:
function onclick() { doSomething() }
这仅仅是doSomething()函数的引用。this关键字没有出现在onclick方法中,因此它不指向HTML元素。
拷贝的例子
下面的例子中this被写入到onclick方法:
element.onclick = doSomething element.addEventListener(‘click‘,doSomething,false) //addEventListener是W3C标准的注册方式 element.onclick = function () {this.style.color = ‘#cc0000‘;} <element onclick="this.style.color = ‘#cc0000‘;">
引用的例子
下面的例子this指向window:
element.onclick = function () {doSomething()} element.attachEvent(‘onclick‘,doSomething) //这是IE的事件注册方式注意和上面拷贝的不同 <element onclick="doSomething()">
注意attachEvent()的存在,微软事件注册模型的主要缺点就是attachEvent()生成的是函数的引用而不是宝贝这个函数。因此有时候了解那个HTML当前正在处理时间是不可能的。
混合
当使用内联事件注册你一可以传递this给这个函数,这样你就仍然可以使用它:
<element onclick="doSomething(this)"> function doSomething(obj) { // this is present in the event handler and is sent to the function // obj now refers to the HTML element, so we can do obj.style.color = ‘#cc0000‘; }
后记:
这个作者关于几个事件注册方式的阐述也很值得一看:早期事件注册 ,传统事件注册和高级事件注册。同时这篇介绍函数调用以及this也是相当值得一看的,这篇是单独介绍this。
原文:http://www.cnblogs.com/muzinian/p/3801288.html