别名或以其他方式合并两个具有不同名称的相同对象原型

Aliasing or otherwise merging two identical object prototypes with different names

本文关键字:原型 对象 两个 方式 其他 合并 别名      更新时间:2023-09-26

我有两个这样的对象原型:

function Tag(name, description) {
    this.name = name;
    this.description = description || null;
}
function Category(name, description) {
    this.name = name;
    this.description = description || null;
}

他们两个完全一样,这看起来很尴尬。是否可以将它们合并到一个名为"Entity"的对象中,并用不同的名称(原始的"Tag"answers"Category")引用它们?

这可能会因为我需要在原型中引用当前的原型名称而变得更加复杂。

Tag.prototype.toJSON = function() {
    return {
        __type: 'Tag',
        name: this.name,
        description: this.description
    };
};

如何将相同的"toJSON"扩展应用于"Entity"对象,但确保它在"__type"字段中返回"Tag"或"Category",具体取决于使用的对象?

我会这样做:

Dummy = function () {};
Entity = function (name) {
  this.name = name;
};
Entity.prototype.toString = function () {
  return "My name is " + this.name + ".";
};
A = function () {
  Entity.call(this, 'A');
};
Dummy.prototype = Entity.prototype;
Dummy.prototype.constructor = A;
A.prototype = new Dummy();
B = function () {
  Entity.call(this, 'B');
};
Dummy.prototype = Entity.prototype;
Dummy.prototype.constructor = B;
B.prototype = new Dummy();
document.body.innerHTML = ""
+ (new A()) + "<br />"
+ (new B());

这里有一个小功能可以让事情变得更干净(希望如此):

function Nothing () {};
function extend (Sup, proto) {
  function Class () {
    if (this.init) {
      this.init.apply(this, arguments);
    }
  }
  Nothing.prototype = Sup.prototype;
  Nothing.prototype.constructor = Sup;
  Class.prototype = new Nothing();
  delete Nothing.prototype;
  for (var k in proto) {
    Class.prototype[k] = proto[k];
  }
  return Class;
}

以下是使用方法:

Entity = extend(Nothing, {
  init: function (name) {
    this.name = name;
  },
  toString: function () {
    return "My name is " + this.name + ".";
  }
});
A = extend(Entity, {
  init: function () {
    var sup = Entity.prototype;
    sup.init.call(this, 'A');
  }
});
B = extend(Entity, {
  init: function () {
    var sup = Entity.prototype;
    sup.init.call(this, 'B');
  }
});