Как некоторые методы могут быть в прототипе, но не передаваться через Object.assign, в то время как некоторые другие - PullRequest
0 голосов
/ 23 марта 2020

Возьмем следующие классы A, B и C и их экземпляры a, b и c

class A {
    constructor() {
        this.method1 = function() {}
    }

    method2() {}
}

A.prototype.method3 = function() {};


class B extends A {
    constructor() {
        super();
    }
}


class C {
    constructor() {}
}

Object.assign(C.prototype, A.prototype);

const a = new A();
const b = new B();
const c = new C();

Почему класс B наследует метод 2, а класс C нет?

Как могут следующие утверждения быть правдой?

A.prototype.method2 !== undefined
c.method2 === undefined

Если вам интересно, c.method3 !== undefined, поэтому между этими двумя понятиями есть принципиальная разница, которую я не могу gr asp.

Вы можете поиграть с этим здесь https://jsfiddle.net/pdn64bv2/


Обновление

Я подумал, что это будет полезно рассказать, как добиться эффекта, который я ожидал получить Object.assign(C.prototype, A.prototype).

Object.getOwnPropertyNames(A.prototype).forEach(name => {
  if (name !== "constructor") C.prototype[name] = A.prototype[name];
});

Это копирует прототип A в C, включая не перечисляемые свойства.

Обратите внимание, что он не копирует цепочку прототипов отверстий, как Reflect.setPrototypeOf(C.prototype, A.prototype), что может быть интересно для композиции объекта.

1 Ответ

2 голосов
/ 23 марта 2020

Существуют две вещи, предполагающие этот эффект:

1) Object.assign будет копировать только перечислимых собственных свойств объекта. Любые неперечислимые свойства не будут скопированы

2) Когда вы используете ключевое слово class, вы определяете любые методы , а не . Это отличается от того, когда вы назначаете объект объекту с A.prototype.method3 = function() {}, где свойство будет перечисляемым.

Таким образом, поскольку A.prototype.method2 не перечислим, он не получает положить на C .prototype, когда вы делаете Object.assign(C.prototype, A.prototype);

Еще один способ увидеть, что методы класса не перечислимы, это использовать Object.keys. Те, которые определены с помощью ключевого слова class, отсутствуют:

class A {
    constructor() {
        this.method1 = function() {}
    }

    method2() {}
}

A.prototype.method3 = function() {};

console.log(Object.keys(A.prototype));

console.log(A.prototype.method2); // it's there
console.log(Object.prototype.propertyIsEnumerable('method2')); // but it's not enumerable
...