使用eventListener进行Javascript继承

时间:2016-12-11 08:16:02

标签: javascript inheritance

我有一个designMain课程,其范围为design

我发现如果我在design中设置了eventListener,那么当事件被触发时,对this的所有引用都只会引用非扩展的design对象。有没有办法克服我的扩展班级的这个缺点?

更新 - 我已经包含了一个按预期工作的ES6版本并显示了我要完成的任务 - 即带有扩展类的this将始终引用扩展甚至在基类中使用代码(例如addEventListener)。在这种情况下,this.name应始终来自扩展类。

这是a jsFiddle

HTML

<div id="test">
    Design (click will fail)
</div>

<div id="test2">
    DesignMain (click will succeed)
</div>

的javascript

design = (function() {
  function design() {
    this.name = "design";

    var _this = this;
    var e = document.getElementById("test");
    e.addEventListener("click", function() {
      _this.callHello();
    });
  }

  design.prototype.callHello = function() {
    // I expect that this.name will be "designMain"
    console.log(this.name)
    // will fail if called from the design class eventListener
    this.hello();
  }

  return design;
})();


designMain = (function() {
  function designMain() {
    this.name = "designMain";
    this.init();
  }

  designMain.prototype.init = function() {
    this.extend();
    var _this = this;
    var e = document.getElementById("test2");
    e.addEventListener("click", function() {
      _this.callHello();
    });
  }

  designMain.prototype.extend = function() {
    var old = new design();
    // save reference to original methods
    this._designMain = Object.create(old);
    for (var name in this._designMain) {
      if (!this[name]) {
        this[name] = this._designMain[name]
      }
    }
  }

  designMain.prototype.hello = function() {
    alert("Hello " + this.name);
  }

  return designMain;
})();


var t = new designMain();

使用ES6 - 它按预期工作(see fiddle

class design {
  constructor() {
    this.name = "design";

    var _this = this;
    var e = document.getElementById("test");
    e.addEventListener("click", function() {
      _this.callHello();
    });
  };

  callHello() {
    // should be "designMain"
    console.log(this.name)
    this.hello();
  }

  get name() {
    return this._name;
  };
  set name(name) {
    this._name = name;
  };
}


class designMain extends design {
  constructor() {
    super();
    this.name = "designMain";
    var _this = this;
    var e = document.getElementById("test2");
    e.addEventListener("click", function() {
      _this.callHello();
    });
  };

  hello() {
    alert("Hello " + this.name);
  }

}

t = new designMain();

1 个答案:

答案 0 :(得分:0)

感谢Bergi和他发布的链接 - 我有一个解决方案。使用Object.create扩展/继承更简单,我只需要添加design.call(this)来运行基类的构造函数。

designMain = (function() {
  designMain.prototype = Object.create(design.prototype);

  function designMain() {
    design.call(this)

工作解决方案:

design = (function() {
  function design() {
    this.name = "design";

    var _this = this;
    var e = document.getElementById("test");
    e.addEventListener("click", function() {
      _this.callHello();
    });
  }

  design.prototype.callHello = function() {
    // will fail if called from the design class eventListener
    console.log(this.name)
    this.hello();
  }

  return design;
})();


designMain = (function() {
  designMain.prototype = Object.create(design.prototype);

  function designMain() {
    design.call(this)
    this.name = "designMain";
    this.init();
  }

  designMain.prototype.init = function() {
    var _this = this;
    var e = document.getElementById("test2");
    e.addEventListener("click", function() {
      _this.callHello();
    });
  }

  designMain.prototype.hello = function() {
    alert("Hello " + this.name);
  }

  return designMain;
})();


var t = new designMain();