【问题标题】:Javascript Class & EventListener [duplicate]Javascript类和EventListener [重复]
【发布时间】:2013-09-16 20:41:28
【问题描述】:

我有一个带有两个属性的基本 javascript 类。我想在点击事件中记录一个的值。这是我得到的:

function Clicker(/*string*/var1, /*id*/var2) {
    this.name = var1;
    this.clickerid = var2;
    this.clickevent = function() {
        console.log("1: " + this.name);
        console.log("2: " + this);
        console.log("3: " + window.testClicker.name);
    };

    var element = document.getElementById(this.clickerid);
    element.addEventListener("click", this.clickevent, false);
}

window.onload = function() {
    window.testClicker = new Clicker("lorem ipsum", "checkbox1");
};

<input id="checkbox1" type="checkbox" value="1" checked>

当我运行测试时,我在日志中看到以下内容:

1: undefined
2: <input id=​"checkbox1" type=​"checkbox" value=​"1" checked>​
3: lorem ipsum

我期待看到第一行和第三行匹配。有什么建议吗?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    this 的值取决于调用函数的上下文。

    当事件侦听器触发时,函数在与事件关联的元素的上下文中调用,而不是从复制函数的对象。

    使用bind 覆盖上下文(它会生成一个新函数,在您定义的任何上下文中调用原始函数)。

    element.addEventListener("click", this.clickevent.bind(this), false);
    

    这相当于:

    element.addEventListener(
        "click", 
        function (context) {
            return function () {
                context.clickevent();
            };
        }(this),
        false
    );
    

    【讨论】:

    • 感谢您的快速回复。现在按预期工作。
    【解决方案2】:

    我认为这可能是context 问题,以下是否可行:

    function Clicker(/*string*/var1, /*id*/var2) {
        this.name = var1;
        this.clickerid = var2;
        var self = this;
        this.clickevent = function() {
            console.log("1: " + self.name);
            console.log("2: " + this);
            console.log("3: " + window.testClicker.name);
        };
    
        var element = document.getElementById(this.clickerid);
        element.addEventListener("click", this.clickevent, false);
    }
    

    正如您在第二个 console.log 中看到的那样,this 指的是复选框,而不是 Cliker 对象

    【讨论】:

    • 不是作用域,而是上下文。
    • @Quentin 我也看到了关于将其称为“上下文”的争议(尽管有几个库这样做)。有人说它可能与“执行上下文”混淆。我个人一直在使用“this value”,它非常接近规范所称的。
    • 这种方法奏效了。谢谢。但我坚持使用 Quentin 上面展示的方法,因为要定义的变量更少。
    • 实际上,在玩了一会儿之后。我同样喜欢这种方法。当我不绑定时,我有一个有用的方法来操作复选框元素本身并通过self访问类对象。
    【解决方案3】:

    为了完整起见,有三种可能的解决方案:

    1. 使用 dm03514's answer 中建议的封闭变量。
    2. 按照Quentin's answer 中的建议使用bind
    3. 按照Dealing with Scope in Object methods containing 'this' keyword called by Event Listeners 的建议使用事件侦听器接口/handleEvent

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-30
      • 2021-03-17
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      • 2011-06-16
      • 1970-01-01
      相关资源
      最近更新 更多