js中...的⽤法
展开语法(Spread syntax), 可以在函数调⽤/数组构造时, 将数组表达式或者string在语法层⾯展开;还可以在构造字⾯量对象时, 将对象表达式按key-value的⽅式展开。(译者注: 字⾯量⼀般指 [1, 2, 3] 或者 {name: "mdn"} 这种简洁的构造⽅式)
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers));
// expected output: 6
console.log(sum.apply(null, numbers));
// expected output: 6
语法
函数调⽤:
myFunction(...iterableObj);
字⾯量数组构造或字符串:
[...iterableObj, '4', ...'hello', 6];
构造字⾯量对象时,进⾏克隆或者属性拷贝(ECMAScript 2018规范新增特性):
let objClone = { ...obj };
⽰例
在函数调⽤时使⽤展开语法
等价于apply的⽅式
如果想将数组元素迭代为函数参数,⼀般使⽤ 的⽅式进⾏调⽤。
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction.apply(null, args);
有了展开语法,可以这样写:
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);
所有参数都可以通过展开语法来传值,也不限制多次使⽤展开语法。
function myFunction(v, w, x, y, z) { }
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);
在 new 表达式中应⽤
使⽤ new 关键字来调⽤构造函数时,不能直接使⽤数组+ apply 的⽅式(apply 执⾏的是调⽤ [[Call]] , ⽽不是构造 [[Construct]])。当然, 有了展开语法, 将数组展开为构造函数的参数就很简单了:
var dateFields = [1970, 0, 1]; // 1970年1⽉1⽇
var d = new Date(...dateFields);
如果不使⽤展开语法, 想将数组元素传给构造函数, 实现⽅式可能是这样的:
function applyAndNew(constructor, args) {
function partial () {
return constructor.apply(this, args);
};
if (typeof constructor.prototype === "object") {
js argumentspartial.prototype = ate(constructor.prototype);
}
return partial;
}
function myConstructor () {
console.log("arguments.length: " + arguments.length);
console.log(arguments);
this.prop1="val1";
this.prop2="val2";
};
var myArguments = ["hi", "how", "are", "you", "mr", null];
var myConstructorWithArguments = applyAndNew(myConstructor, myArguments);
console.log(new myConstructorWithArguments);
// (myConstructor构造函数中): arguments.length: 6
// (myConstructor构造函数中): ["hi", "how", "are", "you", "mr", null]
// ("new myConstructorWithArguments"中): {prop1: "val1", prop2: "val2"}
构造字⾯量数组时使⽤展开语法使⽤展开语法
构造字⾯量数组时更给⼒!
没有展开语法的时候,只能组合使⽤ push, splice, concat 等⽅法,来将已有数组元素变成新数组的⼀部分。有了展开语法, 通过字⾯量⽅式, 构造新数组会变得更简单、更优雅:
var parts = ['shoulders', 'knees'];
var lyrics = ['head', ...parts, 'and', 'toes'];
// ["head", "shoulders", "knees", "and", "toes"]
和参数列表的展开类似, ... 在构造字⾯量数组时, 可以在任意位置多次使⽤.
数组拷贝(copy)
var arr = [1, 2, 3];
var arr2 = [...arr]; // like arr.slice()
arr2.push(4);
// arr2 此时变成 [1, 2, 3, 4]
// arr 不受影响
提⽰: 实际上, 展开语法和 ⾏为⼀致, 执⾏的都是浅拷贝(只遍历⼀层)。如果想对多维数组进⾏深拷贝, 下⾯的⽰例就有些问题了。
var a = [[1], [2], [3]];
var b = [...a];
b.shift().shift(); // 1
// Now array a is affected as well: [[], [2], [3]]
连接多个数组
函数常⽤于将⼀个数组连接到另⼀个数组的后⾯。如果不使⽤展开语法, 代码可能是下⾯这样的:
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// 将 arr2 中所有元素附加到 arr1 后⾯并返回
var arr3 = at(arr2);
使⽤展开语法:
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
var arr3 = [...arr1, ...arr2];
⽅法常⽤于在数组的开头插⼊新元素/数组. 不使⽤展开语法, ⽰例如下:
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// 将 arr2 中的元素插⼊到 arr1 的开头
Array.prototype.unshift.apply(arr1, arr2) // arr1 现在是 [3, 4, 5, 0, 1, 2]
如果使⽤展开语法, 代码如下: [请注意, 这⾥使⽤展开语法创建了⼀个新的 arr1 数组, ⽅法则是修改了原本存在的 arr1 数组]:
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr2, ...arr1]; // arr1 现在为 [3, 4, 5, 0, 1, 2]
构造字⾯量对象时使⽤展开语法
提议(stage 4) 对 增加了展开特性。其⾏为是, 将已有对象的所有可枚举(enumerable)属性拷贝到新构造的对象中.
浅拷贝(Shallow-cloning, 不包含 prototype) 和对象合并, 可以使⽤更简短的展开语法。⽽不必再使⽤ ⽅式.
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
// 克隆后的对象: { foo: "bar", x: 42 }
var mergedObj = { ...obj1, ...obj2 };
// 合并后的对象: { foo: "baz", x: 42, y: 13 }
提⽰: 函数会触发 ,⽽展开语法则不会。
提⽰: 不能替换或者模拟 函数:
var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
const merge = ( ...objects ) => ( { ...objects } );
var mergedObj = merge ( obj1, obj2);
// Object { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } }
var mergedObj = merge ( {}, obj1, obj2);
// Object { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }
在这段代码中, 展开操作符(spread operator)并没有按预期的⽅式执⾏: ⽽是先将多个解构变为剩余参数(rest parameter), 然后再将剩余参数展开为字⾯量对象.
只能⽤于可迭代对象
在数组或函数参数中使⽤展开语法时, 该语法只能⽤于 :
var obj = {'key1': 'value1'};
var array = [...obj]; // TypeError: obj is not iterable
展开多个值
在函数调⽤时使⽤展开语法,请注意不能超过 JavaScript 引擎限制的最⼤参数个数。更多详细信息,请参考: 。
剩余语法(剩余参数)
剩余语法(Rest syntax) 看起来和展开语法完全相同,不同点在于, 剩余参数⽤于解构数组和对象。从某种意义上说,剩余语法与展开语法是相反的:展开语法将数组展开为其中的各个元素,⽽剩余语法则是将多个元素收集起来并“凝聚”为单个元素。 请参考: 。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论