Mar*_*aio 1 javascript object this dom-events
'this' 关键字在全局对象中使用时指的是什么?
假设我们有:
var SomeGlobalObject =
{
rendered: true,
show: function()
{
/*
I should use 'SomeGlobalObject.rendered' below, otherwise it
won't work when called from event scope.
But it works when called from timer scope!!
How can this be?
*/
if(this.rendered)
alert("hello");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我们在 HTML 页面中调用内联脚本:
SomeGlobalObject.show();
window.setTimeout("SomeGlobalObject.show()", 1000);
Run Code Online (Sandbox Code Playgroud)
一切正常。
但是如果我们做这样的事情:
AppendEvent(window, 'load', SomeGlobalObject.show);
Run Code Online (Sandbox Code Playgroud)
我们收到错误,因为this.rendered从事件范围调用时未定义。
AppendEvent 只是一个简单的跨浏览器函数来追加一个事件,代码如下,但是为了回答上面的问题没有关系。
function AppendEvent(html_element, event_name, event_function)
{
if(html_element.attachEvent) //IE
return html_element.attachEvent("on" + event_name, event_function);
else
if(html_element.addEventListener) //FF
html_element.addEventListener(event_name, event_function, false);
}
Run Code Online (Sandbox Code Playgroud)
当您引用作为对象方法的函数时,您将它与该对象分离,并且this不再是对该对象的引用。
最简单的解决方案是将其包装在匿名函数中:
AppendEvent(window, 'load', function () { SomeGlobalObject.show() } );
Run Code Online (Sandbox Code Playgroud)
bind在 ECMAScript 第 5 版实现中还有可用于函数的方法,它允许您执行此操作:
AppendEvent(window, 'load', SomeGlobalObject.show.bind(SomeGlobalObject, arg1, arg2));
Run Code Online (Sandbox Code Playgroud)
JS 框架 Prototype 也为当前的 JS 实现提供了这种方法。代码(感谢@bobince):
// From Prototype.js
if (!Function.prototype.bind) { // check if native implementation available
Function.prototype.bind = function(){
var fn = this, args = Array.prototype.slice.call(arguments),
object = args.shift();
return function(){
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
};
};
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
271 次 |
| 最近记录: |