javascript - 防止构造函数的多个实例共享相同的原型(prototype)属性

标签 javascript inheritance prototype

就在我认为我掌握了原型(prototype)继承在 JavaScript 中的工作原理时,我遇到了一个我以前没有考虑过的问题。

看看下面的简单 JavaScript 代码:

var Observable = function () {
  this.events = [];
};

Observable.prototype.addEvent = function (e) {
  this.events.push(e);
};

var Model = function () {};
Model.prototype = new Observable();

var appModel = new Model();
var taskModel = new Model();

appModel.addEvent('Hello');
taskModel.addEvent('World');

查看 appModel.eventstaskModel.events 会产生相同的数组:['Hello', 'World']。我想要做的是让每个新的 Model 都有自己的 events 数组,并且尽可能简洁。 Model 的以下实现有效:

var Model = function () {
  this.events = [];
};
Model.prototype = new Observable();

但是,随着更多的属性被添加到 Observable 中,这变得更加笨拙。我想我可以按如下方式解决这个问题:

var Model = function () {
  this.prototype.constructor.apply(this, arguments);
};
Model.prototype = new Observable();

虽然我敢肯定,那些对 JavaScript 更有经验的人会意识到这会引发错误:TypeError: Cannot read property 'constructor' of undefined

总而言之,我正在为每个新的 Model 寻找一种方法来从 Observable 继承属性,并且让每个 Model 都有自己的 事件。我意识到这很像类,但我想知道如何仅使用基于 JavaScript 原型(prototype)的继承来做到这一点。

值得注意的是,我看过 Dean Edward 的 Base.js。以下作品:

var Observable = Base.extend({
  constructor: function () {
    this.events = [];
  },
  addEvent: function (e) {
    this.events.push(e);
  }
});

var Model = Observable.extend({
  constructor: function () {
    this.base();
  }
});

var appModel = new Model();
var taskModel = new Model();

appModel.addEvent('Hello');
taskModel.addEvent('World');

但以下不会:

var Observable = Base.extend({
  events: [],
  addEvent: function (e) {
    this.events.push(e);
  }
});

var Model = Observable.extend({
  constructor: function () {
    this.base();
  }
});

var appModel = new Model();
var taskModel = new Model();

appModel.addEvent('Hello');
taskModel.addEvent('World');

除此之外,我还想学习如何在不使用类库的情况下使用 JavaScript 原型(prototype)来做到这一点。

最佳答案

我在这里的理解是,您希望每个实例都有其单独的事件数组,如果是这样,请遵循答案:

function Model(){
  this.events = [];
  this.addEvent = function(eventName){
    this.events.push(eventName);
  };
  this.getEvents = function(){
    return this.events;
  }
}

var m1 = new Model;
var m2 = new Model;
m1.addEvent("eve-1");
m2.addEvent("eve-2");
m1.getEvents(); //["eve-1"]
m2.getEvents(); //["eve-2"]

在您的情况下,您是将事件直接添加到 prototype 而不是实例,因此它们被添加到所有实例中......我希望这会有所帮助

关于javascript - 防止构造函数的多个实例共享相同的原型(prototype)属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14086358/

相关文章:

javascript - div 标签不使用 jquery 折叠/展开

javascript - 如何避免文本字段中连续重复的字符?

c# - XAML 用户控件继承

javascript - getBindingContext() 获取未定义的属性

javascript - JS lambda默认返回值

C#:WCF:接口(interface)继承和转换问题

c++ - 与派生类的虚指针混淆

javascript - 为什么 Function.x 在声明 Function.prototype.x 后工作?

Javascript 继承 : How prototype chain works between native prototypes

javascript - 如何将控制事件绑定(bind)到使用 javascript 原型(prototype)声明的函数