发布于 2026-01-06 6 阅读
0

JavaScript 中的扩展运算符与其余运算符

JavaScript 中的扩展运算符与其余运算符

内容:

让我们来学习如何在代码中使用三个点。读完这篇文章,你就不会忘记它们之间的区别了!🐱🐱🐱

定义

  • 展开运算符可以将可迭代对象展开成单个元素。

  • 其余部分是我们用来表示数组不确定数量的参数的运算符。

两者都用三个点表示...,但你会发现很容易区分展开和休息!最后,还有一个小技巧要分享给你!

价差操作商

连接数组

展开运算符允许我们合并两个或多个数组,从而保持语言的简洁清晰。

一起喝杯咖啡吧?☕️ 请看下面的两个数组:

const coffee = ['coffee', 'water'];
const spices = ['cinnamon', 'nutmeg', 'cardamom'];
Enter fullscreen mode Exit fullscreen mode

我们可以使用展开式将各种成分混合成一个数组:

const coffeeReady = [...coffee, ...spices];

console.log(coffeeReady) 
// output:
// ['coffee', 'water', 'cinnamon', 'nutmeg', 'cardamom'];
Enter fullscreen mode Exit fullscreen mode

简单!比逐个从两个数组中写入元素来形成要好得多coffeeReady

重要的

1. 更改coffee不会影响coffeeReady

为了更好地理解:当我们进行复制时,我们可以创建一个指向原始值的新引用,或者直接复制该值。创建新引用实际上就是创建一个变量,该变量指向内存中原始值所在的同一位置

如果我们创建了一个新的引用,那么对现有数组的任何更改coffee都会影响到现有数组coffeeReady,反之亦然。但我们使用展开运算符(spread)所做的只是复制值,该值随后会存储在内存中的另一个位置。因此,对一个数组的更改不会影响另一个数组。

然而,一些细节可能会改变这种局面!这是因为……

2. 这种传播方式只能制造肤浅的复制品!

这意味着,根据数组 `a` 中包含的数据coffee,某些更改确实会影响`b` coffeeReady!如果coffee`a` 包含非原始值,计算机就会在内存中创建一个指向这些值的引用。因此,对其中一个数组的任何更改都会影响另一个数组,因为它们都存储了对内存中同一位置的引用。请参见下文:

let a = [1, [2, 3]];
// [2, 3] is an array nested in a, and therefore
// it is a non-primitive value
const b = [4, 5, 6];

let c = [...a, ...b];
console.log(c);
// output: [1, [2, 3], 4, 5, 6]

a[0] = 11;
a[1][0] = 22;

console.log(c);
// output: [1, [22, 3], 4, 5, 6]
Enter fullscreen mode Exit fullscreen mode

如上所示,更改 `a`a[0]并未影响 `b` c,因为我们更改的是一个原始值。换句话说,` a[0]a` 和`b`c指向相同的值,但它们位于内存中的不同位置。然而,更改`b` 会a[1][0]改变 `c` ,因为我们更改了 `a`和`b` 都指向c的那个值a[1][0]c

合并对象

我们还可以使用展开运算符将对象合并为一个对象:

const myParents = { 
  fathersName: 'Michael', 
  mothersName: 'Louise'
};
const mySiblings = { 
  brothersName: 'Philip', 
  sistersName: 'Lara' 
};

const myFamily = { ...myParents, ...mySiblings };
console.log(myFamily);
/* output:
{ 
  fathersName: 'Michael', 
  mothersName: 'Louise', 
  brothersName: 'Philip', 
  sistersName: 'Lara' 
} 
*/
Enter fullscreen mode Exit fullscreen mode

但是,需要注意的是,这种展开式并不会复制完全相同的属性!下面我们有两个对象,它们的属性分别为brothersName

const myParents = { 
  fathersName: 'Michael', 
  mothersName: 'Louise',
  brothersName: 'Gabriel'
};
const mySiblings = { 
  brothersName: 'Philip', 
  sistersName: 'Lara' 
};

const myFamily = { ...myParents, ...mySiblings };
console.log(myFamily);
/* output:
{ 
  fathersName: 'Michael', 
  mothersName: 'Louise', 
  brothersName: 'Philip', 
  sistersName: 'Lara' 
}
*/
Enter fullscreen mode Exit fullscreen mode

请注意,最终对象不会同时继承两个brothersName键。实际上,只会保留其中一个键,即来自第二个对象的键。

复制数组和对象

明白了吗?如果我们能合并数组和对象,那就意味着我们也能分别复制它们:

// creating a shallow copy of coffee:
const coffee = ['coffee', 'water'];
const coffeeCopy = [...coffee];
console.log(coffeeCopy)
// output: 
// ['coffee', 'water'];

// creating a shallow copy of mySiblings:
const mySiblings = { 
  brothersName: 'Philip', 
  sistersName: 'Lara' 
};

const myFamily = { 
  fathersName: 'Michael', 
  mothersName: 'Louise',
  ...mySiblings
};
// Now we can treat brothersName and sistersName as 
// a property of myFamily:
console.log(myFamily.brothersName) 
// output: Philip
Enter fullscreen mode Exit fullscreen mode

将字符串转换为数组

也可以使用扩展运算符将字符串转换为数组。这使得我们在操作字符串时更加灵活,因为我们可以将数组方法应用于字符串:

const str = 'coffee';
const letters = [...str, 's.', '☕️']; 
console.log(letters);// ["c", "o", "f", "f", "e", "e", "s.", "☕️"]
Enter fullscreen mode Exit fullscreen mode

剩余运算符

如上所述,剩余运算符用于将元素打包到数组中。你会发现,在处理大量值或值的数量不确定时,剩余运算符是一个非常有用的工具。

函数参数

剩余运算符允许我们将不定数量的参数表示为数组。

const order = function(beverage, ...otherIngredients) {
  console.log(beverage);
  console.log(otherIngredients);
};

order('green tea', 'milk', 'brown sugar'); 
// output:
// green tea 
// ['milk', 'brown sugar']
Enter fullscreen mode Exit fullscreen mode

请注意,这允许我们使用更多参数调用同一个函数,因为剩余运算符会将所有参数放入otherIngredients数组中:

const order = function(beverage, ...otherIngredients) {
  console.log(beverage);
  console.log(otherIngredients);
};

order('green tea', 'milk', 'brown sugar', 'mint', 'tonka'); 
// output:
// green tea 
// ['milk', 'brown sugar', 'mint', 'tonka']
Enter fullscreen mode Exit fullscreen mode

🍵 一个重要的细节是,剩余部分必须是函数中的最后一个参数function(...otherIngredients, beverage)!如果我们这样写,计算机就不知道何时停止,这段代码就会出错。

以休息和传播的方式进行解构

剩余元素和展开运算符也广泛用于解构赋值。如果您还不了解解构赋值,我建议您阅读我的另外两篇文章:数组解构对象解构

使用剩余部分:

const [a, b, ...others] = [1, 2, 3, 4, 5];
console.log(a, b, others); 
// output: 1 2 [3, 4, 5]
Enter fullscreen mode Exit fullscreen mode

现在,记住这个技巧,这样你就不会把“剩余部分”和“展开部分”混淆了:剩余部分在左边 “展开部分=右边=

休息时间 = ☕️

🍵 = ...传播

感谢你读到这里!希望这篇文章对你有所帮助!有什么想法吗?请在下方留言!

文章来源:https://dev.to/baroblesvi/spread-vs-rest-operators-in-javascript-45f3