考虑这个简单的例子:
const someFunction = () => [1, 2, 3];
现在
const myArr = [...someFunction];
给出了运行时错误,这是可以理解的,因为函数不可迭代。所以
const myArr = [...someFunction()];
是正确的实现。
但是,
const myObj = {...someFunction};
结果为{}
,不会引起相同的错误。
[请帮助我理解此行为以及为什么最后一种情况不会导致相同的错误。
Javascript函数是对象,并且您扩展了函数(对象)属性。
您可以使用该函数并添加一个值,如下所示:
someFunction.hello = 'world';
console.log(someFunction.hello);
您的{...someFunction}
之所以起作用是因为函数是对象,而对象文字中的...
被设计为可用于对象,而不是可迭代对象:它具有自己的可枚举属性并将其放入正在创建的对象中。默认情况下,函数没有任何自己的可枚举属性,因此您将获得一个空对象,但是如果向该函数添加了一个属性,然后在对象文字中使用了...
,则该属性将被复制到新的对象:
const someFunction = () => [1, 2, 3];
someFunction.myProperty = "foo";
const obj = {...someFunction};
console.log(obj.myProperty); // "foo"
console.log(Object.keys(obj)); // ["myProperty"]
...
在不同的上下文中表示不同的事物。数组文字中的...
与对象文字中的...
不同。正如您所说,在数组文字中,它使用迭代来为数组建立条目,但是在对象文字中并非如此。对象文字中的...
是property spread,已在ES2018中添加。它根本不依赖迭代。相反,它使用称为[[OwnPropertyKeys]]的内部操作来查找要从源对象复制的属性的键,然后复制它们(这在CopyDataProperties内部操作中)。