【问题标题】:JavaScript Prototypal Inheritance - Is this the right way to do things? [duplicate]JavaScript Prototypal Inheritance - 这是正确的做事方式吗? [复制]
【发布时间】:2025-12-31 06:05:12
【问题描述】:

如果我在一个对象的构造函数之外声明基本原型对象,所有创建的对象都基于那个不适合我需要的单个基本对象,因为我需要多个基本对象实例。

简而言之:这段代码正确吗?它有效,但我对正确的代码很挑剔。

例子:

function BaseObject()
{
    BaseObject.prototype.insertObject = function()…
    …
    … // Some other functions.
}

function Object1()
{
    Object1.prototype = new BaseObject();

    Object1.prototype.coolFunction = function()…
    …
    … // Same kind of pattern.
}

function Object2()
{
    Object2.prototype = new Object1();

    Object2.prototype.incredibleFunction = function()…
    …
    … // You get the idea.
}

【问题讨论】:

    标签: javascript class inheritance prototype instantiation


    【解决方案1】:

    一般模式:

    function Base ( baseMember ) {
        this.baseMember = baseMember;
    }
    
    Base.prototype.baseFunc = function () {};
    
    function Derived ( baseMember, derivedMember ) {
        Base.apply( this, arguments );   
        this.derivedMember = derivedMember;
    }
    
    Derived.prototype = Object.create( Base.prototype );
    Derived.prototype.constructor = Derived;
    
    Derived.prototype.derivedFunc = function () {};
    

    这很丑,我知道...

    【讨论】:

      【解决方案2】:

      不,当前在构造函数中的所有代码都应该在它们之外。现在,每次有人创建新对象时,您都会重新分配原型的这些属性。

      最后,好的做法要点:

      • 您应该始终“修复”任何派生原型的constructor 属性。这是 JS 继承的一个怪癖;它被覆盖。人们很少依赖 constructor 属性是正确的,但有时他们会这样做,如果不这样做就会感觉不对。
      • Object.create(Base.prototype)new Base() 更好,如果您在支持它的浏览器中工作,或者使用 es5-shim。它只实例化对象,而不是创建它,这很好,因为您不需要对象的实际副本来执行原型继承。

      这一切看起来像:

      function BaseObject() { }
      
      BaseObject.prototype.insertObject = function () { };
      
      function Object1() { }
      
      Object1.prototype = Object.create(BaseObject.prototype);
      Object1.prototype.constructor = Object1;
      Object1.prototype.coolFunction = function () { };
      
      function Object2() { }
      
      Object2.prototype = Object.create(Object1.prototype);
      Object2.prototype.constructor = Object2;
      Object2.prototype.incredibleFunction = function () { };
      

      【讨论】:

      • 如果我在构造函数之外执行Object1.prototype = new BaseObject();,则从 Object1 创建的每个对象都依赖于 BaseObject 的单个实例。我需要一种方法来创建 BaseObject 的新实例。
      • 即使您在构造函数中执行它,情况仍然如此。 Object1.prototypeObject1 的每个实例共享,因此每次重新分配它时您所做的就是使Object1 的每个实例都依赖于相同的新建原型BaseObject
      • 但是当我在实际代码中执行此操作时,它就像我需要的那样工作,因为每次调用构造函数时,它都会将对象上的原型设置为 BaseObject 的新创建实例,然后我重复那个模式,它工作正常。必须有一个干净和正确的方法来做到这一点。
      • 它会像你一样工作;它只是效率低下且非常规(“错误”)。 “在 the 对象上设置原型”也不正确;它在每个对象上设置原型。