Javascript的属性有三个点(...)

14
我在处理一个代码时遇到了问题。我发现了一个我不熟悉的语法,并且在搜索文档方面遇到了困难。
export const Something = class Something {
    constructor(someObject = {}) {
        this.someObject = {...Something.someObjectDefaultAsStaticMethod,...someThing};
    };
// The rest of the class
};

我不太理解参数前面的三个点(...)是什么意思。而且,“参数中的省略号javascript”是一个糟糕的搜索词。有人可以帮我吗?也许告诉我这种语法实际上被称为什么,或者直接给我提供相关文档的链接?

2
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator - Keith
1
可能是Spread Syntax ES6的重复问题。 - BlackBeard
这个回答解决了你的问题吗?ES2015/ES6中的Spread语法和Rest参数的区别 - Henke
@BlackBeard 和 Henke:不,这个问题是“*在对象字面量中...是什么意思?”的规范目标。在你们提供的那些链接中,“扩展语法”这个术语已经被知道了,并且它们要求与其他事物进行比较。 - Bergi
5个回答

15

这并不是ES6的内容,而是在ECMAScript 2018中添加的。

它被称为“对象Rest/Spread属性”,是“展开语法”的一部分。 (Spread Syntax)


4
这个答案是正确的。但是为了澄清一下,数组剩余/扩展运算符在ES6中已经存在了,而这个"对象"是处于第三阶段。 - dayuloli

7

2
正确,但请注意它不是一个“运算符”;它不是表达式语法的一部分。 - Pointy

7

...在JavaScript中被称为Spread SyntaxSpread Operator。这允许扩展可迭代的对象,如数组表达式或字符串,并在任何位置扩展对象表达式。

我想列出最常用的实际应用场景Spread Syntax(Spread Operator)。下面将在这个stackoverflow答案中通过示例进行解释。

  1. 合并数组(连接数组)
  2. 复制数组
  3. 调用函数而不需要使用Apply
  4. 解构数组
  5. 函数参数作为Rest参数
  6. 使用Math函数
  7. 结合两个对象
  8. 将字符串分成单独字符

请查看此stackoverflow答案,其中详细列出了每个用例的清晰示例。 - stomy
@Keet 如果您能为每个使用案例编写清晰的代码示例,那将非常好。 - stomy
@stomy 我在答案中附上了链接,其中提供了清晰的代码示例。https://dev59.com/w10Z5IYBdhLWcg3wzC5W#61683996 - Keet Sugathadasa

5
您可以在对象中使用"..."。在下面的示例中,"...data"获取'name: "John",age:24'

const data= { name: "John", age: 24 };

const newData = {
  ...data, // Here
  sex: "Male"
}

console.log(newData);

以下是结果:

{ name: "John", age: 24, sex: "Male" }

以下是另一个示例,使用"...data[key]"向数组中的每个对象添加"id"

const data = [
  { name: "John", age: 24 },
  { name: "Marry", age: 18 },
  { name: "Tom", age: 15 },
]

const newData = [];

for(const key in data) {

  const obj = {
    id: Number(key),
    ...data[key] // Here
  }

  newData.push(obj);
}

console.log(newData);

这是结果:

[
  { id: 0, name: "John", age: 24 },
  { id: 1, name: 'Marry', age: 18 },
  { id: 2, name: 'Tom', age: 15 }
]

0

背景:其中一个用例是进行“复制”,但在处理子属性时,您应该注意这种特定的“按引用”行为。

发现:请注意,子属性不是按值传递,而是按引用传递。换句话说,只有第一级属性作为副本“按值”传递。请参见以下示例:

sourcePerson = { name: 'John', colors: ["red", "blue"] }
targetPerson = { ...sourcePerson }
console.log("Target person result:\n", JSON.stringify(targetPerson), "\n\n") //it seems a copy, but...

console.log("Let's update the name source value:\n")
sourcePerson.name = 'Kevin'
console.log("Updated source person:\n", JSON.stringify(sourcePerson), "\n")
console.log("Target person is NOT updated, It keeps a copy by value\n")
console.log(JSON.stringify(targetPerson), "\n\n")

//But if you update a sub-property, it has NOT been copied by value
console.log("Let's update a color sub-property:\n")
sourcePerson.colors[0] = "YELLOW"
console.log("Updated source person:\n", JSON.stringify(sourcePerson), "\n")
console.log("Target person is updated BY REFERENCE!\n")
console.log(JSON.stringify(targetPerson)) // it is not a copy, it is a reference!

console.log("\nCONCLUSION: ... spread syntax make a copy 'by value' for first level properties, but 'by reference' for sub-properties, so take care!\n")


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接