JavaScript оператор распространения с экземплярами класса - PullRequest
4 голосов
/ 20 июня 2020

Как я могу изменить экземпляр класса с помощью оператора распространения, сохранив при этом его конструктор?

Вопрос можно прояснить на примере.

class User {
    constructor({ name = "", age = 0 }) {
        this.name = name
        this.age = age
    }

    getName() {
        return this.name
    }

    getAge() {
        return this.age
    }
}

Создание обычного экземпляра работает нормально:

const u1 = new User({ name: 'John Doe', age: 33 })
console.log(u1.getAge()) // 33

Что не работает, так это использование оператора распространения с экземпляром:

const u2 = { ...u1, age: 34 }
console.log(u2.getAge()) // 

Я читал, что оператор распространения копирует только собственные перечисляемые свойства , поэтому я также пробовал это:

const u3 = { ...u1, ...User.prototype, age: 34 }
console.log(u3.getAge())

Это работает лучше (позволяет мне вызывать методы из User), но все равно не работает при использовании instanceof или Object.isPrototypeOf():

console.log(u1 instanceof User) // true
console.log(u2 instanceof User) // false
console.log(u3 instanceof User) // false

console.log(User.isPrototypeOf(u1)) // true
console.log(User.isPrototypeOf(u2)) // false
console.log(User.isPrototypeOf(u3)) // false

Я тоже пробовал их, но они тоже не работали:

const u4 = Object.assign({ age: 34 }, u1)
const u5 = Object.assign({ age: 34 }, u1, User.prototype)

Итак, TL: DR, можно ли создать копию экземпляра класса, который изменяет некоторые свойства родительский, но сохраняет ссылку на свой конструктор?

Надеюсь, я ясно выразился. Заранее спасибо за помощь!

1 Ответ

7 голосов
/ 20 июня 2020

Используя буквальную нотацию объекта { }, вы всегда создаете простой объект, а не экземпляр вашего настраиваемого класса. Для получения нового экземпляра следует использовать оператор new (или Object.create):

class User {
    constructor({ name = "", age = 0 }) {
        this.name = name
        this.age = age
    }

    getName() {
        return this.name
    }

    getAge() {
        return this.age
    }
}

const u1 = new User({ name: 'John Doe', age: 33 })
console.log(u1.getName(), u1.getAge()) // John Doe, 33

const u2 = new User({ ...u1, age: 34 });
console.log(u2.getName(), u2.getAge()) // John Doe, 34
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...