es6之扩展运算符三个点(...)

原创
小哥 3年前 (2022-10-21) 阅读数 7 #Web前端
文章标签 jsES6JavaScript

es6扩张运算符 三个点(...)

es6扩张运算符 三分(…)

对象的扩张运算符

理解对象的扩张运算符实际上非常简单,只需记住一句话:

对象中的扩张运算符(...)用于取出参数对象中的所有可遍历属性,并将它们复制到当前对象中。

let bar = { a: 1, b: 2 };
let baz = { ...bar }; // { a: 1, b: 2 }

上述方法实际上是等价的:

let bar = { a: 1, b: 2 };
let baz = Object.assign({}, bar); // { a: 1, b: 2 }

Object.assign 该方法用于合并对象,将源对象 (source) 的所有可枚举属性都将复制到目标对象。 (target)

Object.assign 该方法的第一个参数是目标对象,以下参数是源对象。( 如果目标对象具有与源对象同名的属性,或者多个源对象具有同名属性,则以下属性将覆盖上一个属性 )。

同样,如果用户定义的属性放在扩展操作符之后,扩展操作符中同名的属性将被覆盖。

let bar = {a: 1, b: 2};
let baz = {...bar, ...{a:2, b: 4}};  // {a: 2, b: 4}

使用上述功能,可以非常方便地修改对象的某些属性。在……里面 redux 中的 reducer 该函数必须为 纯函数 (如果不清楚什么是纯函数,可以参考。 这里 ), reducer 中的 state 不能直接修改对象要求。您可以通过扩展操作符复制所有修改路径的对象,然后生成一个要返回的新对象。

这里需要注意的是,扩展操作符的对象实例副本是浅层副本。一定有人会问,什么是肤浅的抄袭?我们知道 javascript 有两种数据类型,即 基本数据类型引用数据类型基本数据类型 是按值访问的,公共 基本数据类型NumberStringBooleanNullUndefined ,这些变量的副本将被完全复制; 引用数据类型 比如 Array 复制时,复制的是对象的引用。当原始对象更改时,复制的对象也会更改,例如:

let obj1 = { a: 1, b: 2};
let obj2 = { ...obj1, b: 2-edited};
console.log(obj1); // {a: 1, b: 2}
console.log(obj2); //  {a: 1, b: "2-edited"}

上例中扩张运算符复制的对象为 基本数据类型 ,因此对 obj2 对的修改不会影响 obj1 ,如果更改为:

let obj1 = { a: 1, b: 2, c: {nickName: d}};
let obj2 = { ...obj1};
obj2.c.nickName = d-edited;
console.log(obj1); // {a: 1, b: 2, c: {nickName: d-edited}}
console.log(obj2); // {a: 1, b: 2, c: {nickName: d-edited}}

正如你在这里看到的,对吗? obj2 的修改会影响复制的对象。 obj1 ,原因已经在上面说过了,因为 obj1 中的对象 c 是引用数据类型。复制时,将复制对象的引用。

数组的扩张运算符

在数组运算中也可以使用扩张运算符。

  • 您可以将数组转换为参数序列。

    function add(x, y) { return x + y; }

    const numbers = [4, 38]; add(...numbers) // 42

  • 您可以复制数组

不建议通过以下方法直接复制数组:

const arr1 = [1, 2];
const arr2 = arr1;
arr2[0] = 2;
arr1 // [2, 2]

上面已经介绍了原因,使用分机运算符非常方便:

const arr1 = [1, 2];
const arr2 = [...arr1];

还记得那句话吗: 扩张运算符(…)用于取出参数对象中的所有可遍历属性,并将它们复制到当前对象中。 ,这里参数对象是个数组,数组里面的所有对象都是基本数据类型,将所有基本数据类型重新拷贝到新的数组中。

  • 扩张运算符可以与解构赋值结合起来,用于生成数组

    const [first, ...rest] = [1, 2, 3, 4, 5]; first // 1 rest // [2, 3, 4, 5]

需要注意的一点是:

如果将扩张运算符用于数组赋值,只能放在参数的最后一位,否则会报错。

const [...rest, last] = [1, 2, 3, 4, 5];
// 报错
const [first, ...rest, last] = [1, 2, 3, 4, 5];
// 报错
  • 扩张运算符还可以将字符串转为真正的数组

    [...hello] // [ "h", "e", "l", "l", "o" ]

  • 任何 Iterator 接口的对象(请参见 Iterator 一章),都可以用扩张运算符转为真正的数组

这一点比较官方,你可以参考阮易峰老师的 ECMAScript 6入门教程

一个常见的应用是将一些数据结构转换为数组。,比如:

// arguments对象
function foo() {
  const args = [...arguments];
}

用于替换 es5 中的 Array.prototype.slice.call(arguments) 写法。

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除