将原型B的所有方法和属性赋值给原型A?

Assign all methods and properties of prototype B into prototype A?

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

Class A 缺少实现。所以我希望 class B 中的所有功能都进入 class 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 中?

您可以使用 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类,那么你只需要extend ClassB:

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"));

您确实无法覆盖通过 class 语法创建的函数的 prototype 属性,因为它是只读的且不可配置的。如果您使用 function 语法而不是 .

就可以做到这一点

但你可能想要 ClassA extend 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的超类方法。