带有类实例的 JavaScript 扩展运算符

spa*_*777 4 javascript ecmascript-6

如何使用扩展运算符修改类实例,同时保持其构造函数相同?

举个例子,这个问题可能会更清楚。

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

    getName() {
        return this.name
    }

    getAge() {
        return this.age
    }
}
Run Code Online (Sandbox Code Playgroud)

创建常规实例工作正常:

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

不起作用的是在实例中使用扩展运算符:

const u2 = { ...u1, age: 34 }
console.log(u2.getAge()) // 
Run Code Online (Sandbox Code Playgroud)

我读到传播运算符只复制自己的可枚举属性,所以我也试过这个:

const u3 = { ...u1, ...User.prototype, age: 34 }
console.log(u3.getAge())
Run Code Online (Sandbox Code Playgroud)

这效果更好(它允许我调用 中的方法User),但在使用instanceofor时仍然中断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
Run Code Online (Sandbox Code Playgroud)

我也尝试过这些,但它们也不起作用:

const u4 = Object.assign({ age: 34 }, u1)
const u5 = Object.assign({ age: 34 }, u1, User.prototype)
Run Code Online (Sandbox Code Playgroud)

那么,TL:DR,是否可以创建一个类实例的副本,该副本更改了父类的某些属性,但保留对其构造函数的引用?

希望我说清楚了。在此先感谢您的帮助!

tri*_*cot 8

使用{ }对象字面量符号,您始终创建一个普通对象,而不是自定义类的实例。您应该使用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
Run Code Online (Sandbox Code Playgroud)