处理包含事件侦听器调用的“this"关键字的对象方法中的作用域 [英] Dealing with Scope in Object methods containing 'this' keyword called by Event Listeners

查看:12
本文介绍了处理包含事件侦听器调用的“this"关键字的对象方法中的作用域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将我对情况的缺乏了解概括为这个小问题.以下是我目前所知道的:

I've generalized my lack of understanding of the situation to this small problem. Here's what I think I know so far:

我有一个对象 myDog(一个全局变量).Dog 有一个成员变量 el 是一个 html 元素;因为它是一个元素,所以我可以向它添加事件侦听器.因此,当您单击 myDog.el 时,它会将 this.namemyDog.name 的值记录到控制台.由于范围的原因,正如预期的那样,this.name 是未定义的,myDog.name 是 'tye'.this 里面的 Dog.speak 当被点击事件监听器调用时,是指被点击的元素,成员变量el,而不是对象.由于 myDog 是一个全局变量,它能够在不考虑函数作用域的情况下进行备份,并且可以很好地到达 myDog.name.

I have an object myDog (a global variable). Dog has a member variable el that is an html element; because it's an element, I can add event listeners to it. So, when you click on myDog.el, it logs to the console the values of this.name and myDog.name. As expected because of scope, this.name is undefined and myDog.name is 'tye'. this inside of Dog.speak when invoked by the click event listener refers to the element that was clicked, the member variable el, not the object Dog. Since myDog is a global variable, it's able to pick back up regardless of the function's scope and get to myDog.name just fine.

见下面的代码:

function Dog(name,id) {
    this.name = name ? name : "spot";
    this.id = id ? id : "dog";
    this.el = document.getElementById(this.id); // given there is a div with a matching    
    this.el.addEventListener("click",this.speak); // ignore IE for simplicity (attachEvent has its own 'this' scope issues)
}

Dog.prototype = {
    speak: function() {
        console.log("this.name: "+this.name+"
myDog.name: "+myDog.name);
    }
};

var myDog = new Dog("tye","dog1");

所以...我的问题是

1) 有哪些将对象附加到 html 元素的策略,以便我可以从 this.el 回到 myDog (this.el 的所有者)而 myDog 不是全局变量?

1) What are some strategies for attaching objects to html elements, so that I can go from this.el back to myDog (this.el's owner) without myDog being a global variable?

2) 在这种情况下,全局变量是必要的邪恶吗?如果是这样,在这种情况下,有什么好的策略可以优雅地使用它们?例如,如果我想实例化 100 只狗怎么办?我将如何处理 Dog.speak 中的所有这些全局变量?

2) Are global variables in this case a necessary evil? And if so, what are so good strategies in this case to gracefully use them? For example, what if I wanted 100 dogs instantiated? How would I handle all those global variables in Dog.speak?

如果你想玩它,这里有一个 jsfiddle 版本:http://jsfiddle.net/chadhutchins/Ewgw5/

Here's a jsfiddle version if you want to play with it: http://jsfiddle.net/chadhutchins/Ewgw5/

推荐答案

"1) 将对象附加到 html 元素有哪些策略..."

由于您使用的是 .addEventListener(),我建议您利用它的一个似乎很少有人知道的功能...制作您的 Dog 对象实现 EventListener 接口.

Since you're using .addEventListener(), I'd suggest taking advantage of a feature of it that few people seem to know about... making your Dog object implement the EventListener interface.

这在您的 Dog 数据与其关联元素之间建立了非常清晰的关系.

This establishes a very clean relationship between your Dog data and its associated element.

只需要很小的改动.代码第一...解释如下.

Only minor changes are required. Code first... explanation below.

演示: http://jsfiddle.net/Ewgw5/1/

function Dog(name,id) {
    this.name = name ? name : "spot";
    this.id = id ? id : "dog";
    this.el = document.getElementById(this.id);

    // ---------------------------------v----no function!
    this.el.addEventListener("click", this);
}

Dog.prototype = {
    // Implement the `EventListener` interface   
    handleEvent: function(event) {
        switch (event.type) {
            case "click": return this.speak();
        }
    },
    speak: function() {
        console.log("this.name: "+this.name+"
myDog.name: "+myDog.name);
    }
};

var myDog = new Dog("tye","dog1");

<小时>

所以我所做的只是将构造函数中的 this 传递给 addEventListener() 而不是传递函数,然后我添加了一个 handleEvent()方法到Dog.prototype.


So all I did was pass this in the constructor to addEventListener() instead of passing a function, and then I added a handleEvent() method to Dog.prototype.

现在当 "click" 事件发生时,它会调用 handleEvent() 方法.该方法中 this 的值将是您的 Dog 实例.因此,您可以从那里调用您需要的任何方法.

Now when a "click" event occurs, it will invoke the handleEvent() method. The value of this in that method will be your Dog instance. So from there you can call whatever method(s) you need.

因为您将元素设为this 的属性,所以您可以通过this.el 访问该元素.但这在技术上甚至没有必要,因为该元素也可以通过 event 对象作为 event.currentTarget 使用.

Because you made the element a property of this, you can access the element via this.el. But that's technically not even necessary, since the element is also available via the event object as event.currentTarget.

2)在这种情况下,全局变量是否是必要的邪恶..."

幸好没有!

此行为应该是 .addEventListener() 的 shim 的一部分.

This behavior should be part of your shim for .addEventListener().

这篇关于处理包含事件侦听器调用的“this"关键字的对象方法中的作用域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆