【问题标题】:Object oriented Javascript: event handling面向对象的Javascript:事件处理
【发布时间】:2013-03-12 08:59:01
【问题描述】:

我正在尝试为一个对象创建一个事件以让它监听它。考虑以下示例:

var moon;

moon = document.createEvent("Event");
moon.initEvent("Event",true,true);

var Dog = function (name) {
  this.name = name;
  
  document.addEventListener("Event",this.bark,false);
};
dog.prototype.bark = function() {
  console.log(this.name + ': Awooooooof Woof!');
};


var spot = new Dog("Spot");
var dot = new Dog("Dot");


//invoke
document.dispatchEvent(moon);

我希望收到如下输出:

现场:呜呜呜呜!

点:呜呜呜呜呜!

但我得到的是:

未定义:呜呜呜呜!

我的例子有什么问题?如何注册每个 Dog 实例都有的侦听器?

【问题讨论】:

    标签: javascript oop dom-events


    【解决方案1】:

    在这一行

    document.addEventListener("Event",this.bark,false);
    

    您没有将this.bark 的范围绑定到this。在 JavaScript 中,this 的值不取决于函数的定义位置,而是调用位置。这意味着当您将this.bark 传递给addEventListener 时,您会将其与当前对象分离。

    在prototype.js 和JQuery 等框架中,有绑定this 的快捷方式,使用原生JavaScript 你可以这样做:

    function bind(scope, fn) {
       return function() {
          return fn.apply(scope, arguments);
       }
    }
    

    然后:

    document.addEventListener("Event",bind(this, this.bark),false);
    

    【讨论】:

    • 非常感谢!我想出了如何用 jQuery 来实现它,但我认为你的解决方案更优雅。
    【解决方案2】:

    您遇到的问题是函数内部的this 没有引用您要操作的对象。

    在函数定义中添加函数bark怎么样?

    var Dog = function (name) {
        this.name = name;    
        this.bark = function() {
            console.log(name + ': Awooooooof Woof!');
        };
        document.addEventListener("Event", this.bark, false);
    };
    

    【讨论】:

      【解决方案3】:

      问题

      this 内的关键字 Dog.prototype.bark() 指向调用该方法的对象。例如,当调用 spot.bark() 时,this.name 的计算结果为 spot.name,如下所示:

      Dog.prototype.bark = function () {
          console.log(spot.name + ': Awooooooof Woof!');
      };
      

      当事件侦听器被添加到 Dog 的构造函数中时,document 对象被告知要侦听该事件,并被告知在听到该事件时调用 Dog.prototype.bark()。此设置已正确完成,document 对象将在听到该事件时调用正确的函数,

      document 对象实际调用 bark 函数时,问题就会发生。现在,this 指向 document 对象,this.name 计算结果为 document.name,如下所示:

      Dog.prototype.bark = function () {
          console.log(document.name + ': Awooooooof Woof!');
      };
      

      document.name 不存在,因此输出为:undefined: Awooooooof Woof!

      修复

      使用Function.prototype.bind() 将提供的值绑定到函数的this 关键字,如下所示:

      document.addEventListener("Moon", this.bark.bind(this), false);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-31
        • 1970-01-01
        • 2013-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-14
        相关资源
        最近更新 更多