JavaScript 对象展开

概要: 在本教程中,您将学习如何在 ES2018 中使用 JavaScript 对象展开 (...) 来克隆对象或将多个对象合并为一个。

JavaScript 对象展开运算符简介

在 ES6 中,您使用 展开运算符 (...) 来解包 数组 的元素。展开运算符对于克隆数组非常有用。例如

let colors = ['red', 'green', 'blue'];
let rgb = [...colors];
console.log(rgb);
Code language: JavaScript (javascript)

输出

[ 'red', 'green', 'blue' ]    
Code language: JSON / JSON with Comments (json)

在此示例中,展开运算符 (...) 解包了 colors 数组的元素并将它们放置在一个新的数组 rgb 中。展开运算符 (...) 可用于将两个或多个数组合并为一个,如下例所示

let rgb = [ 'red', 'green', 'blue' ];
let cmyk = ['cyan', 'magenta', 'yellow', 'black'];
let merge = [...rgb, ...cmyk];
console.log(merge);
Code language: JavaScript (javascript)

输出

[ 'red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'black' ]
Code language: JSON / JSON with Comments (json)

ES2018 扩展了展开运算符 (...) 使其能够与对象的 自身 可枚举属性 协同工作。假设您有一个名为 circle 的对象,它有一个名为 radius 的属性

const circle = {
    radius: 10
};
Code language: JavaScript (javascript)

以下示例使用展开运算符 (...) 创建一个 coloredCircle 对象,该对象具有 circle 对象的所有属性以及一个额外的属性 color

const coloredCircle = {
    ...circle,
    color: 'black'
};

console.log(coloredCircle);
Code language: JavaScript (javascript)

输出

{
    radius: 10,
    color: 'black'
}
Code language: CSS (css)

JavaScript 对象展开运算符用例

1) 克隆对象

您可以使用展开运算符来克隆对象的自身可枚举属性

const circle = {
    radius: 10
};

const clonedCircle = {...circle};

console.log(clonedCircle);
Code language: JavaScript (javascript)

输出

{ radius: 10 }
Code language: CSS (css)

请注意,克隆始终是浅层克隆。例如

const circle = {
    radius: 10,
    style: {
        color: 'blue'
    }
};

const clonedCircle = {
    ...circle
};


clonedCircle.style = 'red';

console.log(clonedCircle);
Code language: JavaScript (javascript)

输出

{ radius: 10, style: 'red' }
Code language: CSS (css)

2) 合并对象

与数组类似,您可以使用展开运算符 (...) 合并两个对象

const circle = {
    radius: 10
};

const style = {
    backgroundColor: 'red'
};

const solidCircle = {
    ...circle,
    ...style
};

console.log(solidCircle);
Code language: JavaScript (javascript)

输出

{ radius: 10, backgroundColor: 'red' }
Code language: CSS (css)

展开运算符与 Object.assign()

展开运算符 (...) 在目标对象中定义新的 属性,而 Object.assign() 方法则为它们赋值。它有两个副作用。

1) 带有设置器的目标对象

Object.assign() 在目标对象上调用设置器,而展开运算符则不会。以下示例说明了如何使用 Object.assign() 和展开运算符 (...) 来克隆对象。但是,只有 Object.assign() 方法会触发设置器

class Circle {
    constructor(radius) {
        this.radius = radius;
    }
    set diameter(value) {
        this.radius = value / 2;
        console.log('SET ', value);
    }
    get diameter() {
        return this.radius * 2;
    }
}

let circle = new Circle(100);

let cloneCircle1 = Object.assign(circle, {
    diameter: 200
});

let cloneCircle2 = {
    ...circle
};
Code language: JavaScript (javascript)

输出

SET  200

2) 带有只读属性的目标对象

如果目标对象具有只读属性,则不能使用 Object.assign() 方法为该属性分配新值。但是,展开运算符 ( ...) 可以定义一个新属性。假设您有一个名为 blueSquare 的对象,其 color 属性是只读的

const blueSquare = {
    length: 100,
    color: 'blue'
};

Object.defineProperty(blueSquare, 'color', {
    value: 'blue',
    enumerable: true,
    writable: false

});

console.log(blueSquare);
Code language: JavaScript (javascript)

输出

{ length: 100, color: 'blue' }Code language: CSS (css)

以下代码使用展开运算符 (...) 合并 styleblueSquare 对象

// merge style and blueSquare objects:
const style = {
    color: 'green'
};

const greenSquare = {
    ...blueSquare,
    ...style
};

console.log(greenSquare);
Code language: JavaScript (javascript)

输出

{ length: 100, color: 'green' }Code language: CSS (css)

但是,如果您使用 Object.assign() 方法,您将收到错误

// merge style and redSquare objects: ERROR
const redSquare = Object.assign(blueSquare, {
    color: 'red'
});Code language: JavaScript (javascript)

错误

TypeError: Cannot assign to read only property 'color' of object '#<Object>'Code language: JavaScript (javascript)

摘要

  • 对象展开运算符 (...) 解包对象的自身可枚举属性。
  • 使用对象展开运算符来克隆对象或将多个对象合并为一个。克隆始终是浅层克隆。
  • 合并对象时,展开运算符定义新的属性,而 Object.assign() 方法则为它们赋值。
本教程对您有帮助吗?