Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
保存';这';javascript原型事件处理程序中的引用_Javascript_Oop_Event Handling_This - Fatal编程技术网

保存';这';javascript原型事件处理程序中的引用

保存';这';javascript原型事件处理程序中的引用,javascript,oop,event-handling,this,Javascript,Oop,Event Handling,This,在对象原型中存储的事件处理程序中保存此javascript引用的正确方法是什么?我不想创建像“this”或“that”这样的临时变量,也不能使用像jQuery这样的框架。我看到很多人谈论使用“bind”函数,但不确定如何在我给定的场景中实现它 var Example = function(foo,bar){ this.foo = foo; this.bar = bar; }; Example.prototype.SetEvent = function(){ this.ba

在对象原型中存储的事件处理程序中保存
javascript引用的正确方法是什么?我不想创建像“this”或“that”这样的临时变量,也不能使用像jQuery这样的框架。我看到很多人谈论使用“bind”函数,但不确定如何在我给定的场景中实现它

var Example = function(foo,bar){
    this.foo = foo;
    this.bar = bar;
};
Example.prototype.SetEvent = function(){
    this.bar.onclick = this.ClickEvent;
};
Example.prototype.ClickEvent = function(){
    console.log(this.foo); // logs undefined because 'this' is really 'this.bar'
};
我发现
bind()
是迄今为止最干净的解决方案:

this.bar.onclick = this.ClickEvent.bind(this);

顺便说一句,另一个
通常被称为

查看
bind
上的MDN文档:

使用此功能,您可以更改范围(此
是什么):

但是,请注意,这是EMCA的新添加,因此可能并非所有用户代理都支持。在上面链接的MDN文档中有一个pollyfill可用。

问题在于

该函数可以多填充,但与本机实现不完全相同:

  • 警告:绑定函数具有原型属性
  • 警告:绑定函数不会试图阻止您操作它们的
    参数
    调用者
    属性
  • 警告:绑定函数在
    call
    apply
    中没有检查,以避免作为构造函数执行

另一种选择是:

如果您希望稍后删除事件处理程序,这将更有帮助,因为当函数通过该方法时,jQuery会生成一个新的guid值,然后将该guid应用于核心函数以及生成的代理函数,因此,您可以使用原始函数引用解除已代理的事件处理程序回调的绑定:

$(elem).off('click', eventHandler);
其他解决方案:使用ES6引入的“箭头函数”。它们具有不改变上下文的特殊性,即
指向的内容。以下是一个例子:

function Foo(){
    myeventemitter.addEventListener("mousedown", (()=>{
        return (event)=>{this.myinstancefunction(event)}; /* Return the arrow
function (with the same this) that pass the event to the Foo prototype handler */
    })());
}
Foo.prototype.myinstancefunction = function(event){
    // Handle event in the context of your Object
}

编辑


小心点。如果您在客户端使用它,并且无法确定JS解释器的功能,请注意,旧浏览器无法识别箭头函数()。只有当您知道将运行什么时才使用此方法(仅限最新浏览器和NodeJS应用程序)

我讨厌创建一个称为“that”(la Crockford)的引用。我更喜欢“instance”(一个la Stefanov)或“me”(一个la ExtJS)实际上,我讨厌创建
this
引用,不管它们是如何命名的。但我同意,
这并不是最好的命名。我使用“self”,但最近发现它与WebWorkers中的顶级属性名称冲突。并不是说你不能有相同的名字,但它确实混淆了事情。此外,我发现名称“that”与“this”完全相反@GeorgeJempty这只是个人偏好这当然在旧IE(8及以上版本)中不起作用
。bind()
$.proxy
一样完全跨浏览器。它基本上是
.bind()
的非标准版本。如果您列出的注意事项实际上是一个问题,那么
$.proxy
将不会更好。更不用说这个问题很清楚,他不能使用jQuery。@我建议使用
$.proxy
(或类似的实现),因为它是一个松散的连接,这对OO事件处理非常有帮助。但谢谢你,我会更新我的答案,因为正如你所说,polyfilled
.bind()
$.proxy
一样完全跨浏览器。
$(elem).off('click', eventHandler);
function Foo(){
    myeventemitter.addEventListener("mousedown", (()=>{
        return (event)=>{this.myinstancefunction(event)}; /* Return the arrow
function (with the same this) that pass the event to the Foo prototype handler */
    })());
}
Foo.prototype.myinstancefunction = function(event){
    // Handle event in the context of your Object
}