【问题标题】:Assign all methods and properties of prototype B into prototype A?将原型 B 的所有方法和属性分配给原型 A?
【发布时间】:2019-09-02 09:43:30
【问题描述】:

我有一个 A 类,它是 B 类的子集。它共享 B 类的许多属性和方法。

A 类虽然缺乏实现。所以我希望 B 类中的所有功能都进入 A 类。

ClassA.prototype = ClassB.prototype;

ClassA.prototype += ClassB.prototype

但看来我必须:

ClassA.prototype.methodA = ClassB.prototype.methodA
ClassA.prototype.methodB = ClassB.prototype.methodB
ClassA.prototype.methodC = ClassB.prototype.methodC
ClassA.prototype.methodD = ClassB.prototype.methodD

对于每一个方法和属性。有没有办法一次将 B 中的实现放入 A 中?

【问题讨论】:

    标签: javascript typescript prototype mixins


    【解决方案1】:

    确实,您不能覆盖通过class 语法创建的函数的prototype 属性,因为它既是只读的又是不可配置的。如果您使用function 语法而不是Fullstack Guy points out,则可以做到这一点。

    但你可能想让ClassA 扩展 ClassB:

    class ClassA extends ClassB {
        // ...
    }
    

    现场示例:

    class ClassB {
        methodA() {
            console.log("methodA");
        }
        methodB() {
            console.log("methodB");
        }
        methodC() {
            console.log("methodC");
        }
        methodD() {
            console.log("methodD");
        }
    }
    class ClassA extends ClassB {
        // ...
    }
    new ClassA().methodA();

    如果没有,您可以使用循环复制所有方法:

    for (const name of Object.getOwnPropertyNames(ClassB.prototype)) {
        const method = ClassB.prototype[name];
        if (typeof method === "function") {
            ClassA.prototype[name] = ClassB.prototype[name];
        }
    }
    

    现场示例:

    class ClassB {
        methodA() {
            console.log("methodA");
        }
        methodB() {
            console.log("methodB");
        }
        methodC() {
            console.log("methodC");
        }
        methodD() {
            console.log("methodD");
        }
    }
    class ClassA {
        // ...
    }
    for (const name of Object.getOwnPropertyNames(ClassB.prototype)) {
        const method = ClassB.prototype[name];
        if (typeof method === "function") {
            ClassA.prototype[name] = ClassB.prototype[name];
        }
    }
    new ClassA().methodA();

    但请注意,如果ClassB是子类,则方法内的super会继续访问ClassB的超类方法,既不会无效也不会访问ClassA的超类方法。

    【讨论】:

      【解决方案2】:

      您可以使用Object.create 来制作ClassA 的原型,继承自ClassBprototyoe

      function ClassB(){
      }
      ClassB.prototype.methodA = function(){
         console.log("methodA");
      }
      
       
      function ClassA(){
        //no implementation
      }
      //Make the prototype of Class A inherit from the ptottype of Class B
      ClassA.prototype = Object.create(ClassB.prototype);
      const classA =  new ClassA();
      classA.methodA();
        

      以上是针对函数构造函数,如果你想使用ES6类,那么你只需要extendClassB

      class ClassB{
        methodA(){ console.log("methodA"); }
      }
      class ClassA extends ClassB{
      }
      
      const classA = new ClassA();
      classA.methodA();
      
      
      // When you extend another class, the instance methods of super class are inherited
      // in the prototype property of the child class
      ClassA.prototype.methodA();

      作为@T.J. Crowder 正确地说 class 对象的 prototype 属性是不可配置的,因此您不能为其分配另一个对象。此外,一旦将configurable 设置为false,就无法将其更改为true。唯一的选择是循环复制成员函数。

      您可以通过Object.getOwnPropertyDescriptor() 方法验证这一点:

      class ClassA{
      }
      
      //configurable and writable is false
      console.log(Object.getOwnPropertyDescriptor(ClassA, "prototype"));

      【讨论】:

      • OP 必须使用class 语法。否则,他们的第一个例子会很有效。这不适用于 class 语法。
      • @T.J.Crowder 让我也补充一下
      猜你喜欢
      • 2016-06-16
      • 1970-01-01
      • 2021-08-25
      • 2016-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      相关资源
      最近更新 更多