Spread语法是ES6提供的一个非常方便的新语法,给我们操作数组和对象带来了极大的便利。我在很多文章中也提到过这个语法。但是,扩展运算符的使用仍然相当复杂。我会用一篇文章做一个总结,梳理扩展操作的语法和用法细节。
扩展运算符扩展语法也称为扩展语法,其写法为.顾名思义,它实际上是一种用于扩展字符串、数组和对象的语法。在函数调用/数组构造期间,可以在语法级别扩展数组表达式或字符串;在构造文字对象时,还可以以键值的方式扩展对象表达式。的常见语法如下:
//函数调用:
我的功能(.iterable obj);
//文字数组构造或字符串:
[.iterableObj, 4 ,你好,6];
//构造文字对象时,克隆或复制属性(ECMAScript 2018规范中的新特性):
let objClone={.obj };
在函数调用中使用扩展运算符等效于使用Function.prototype.apply:
函数myFunction(x,y,z) { }
var args=[0,1,2];
我的功能(.args);
//相当于
函数myFunction(x,y,z) {}
var args=[0,1,2];
myFunction.apply(null,args);
与apply不同,我们不仅可以将所有参数放在一个数组中,还可以用扩展操作符只扩展其中的几个参数,而且我们可以在一次调用中多次使用扩展操作符。
函数myFunction(a,b,c,d,e) {
console.log(a,b,c,d,e);//-1 0 1 2 3
console.log(参数);//[参数] { 0: -1, 1: 0, 2: 1, 3: 2, 4: 3 }
}
var args=[0,1];
myFunction(-1,参数,2,[3]);
使用new关键字调用构造函数时,不能直接使用数组加apply的方式(apply是调用[[Call]],而不是构造[[Construct]])。使用扩展语法,很容易将数组扩展到构造函数的参数中:
var日期字段=[1970,0,1];//1970年1月1日
var d=新日期(.日期字段);
如果想在不使用扩展运算符的情况下达到同样的效果,就必须用函数包装构造函数,将这个新构造函数的原型设置为原构造函数的实例,并使用Object。Create (constructor.prototype)(这里主要是新构造函数的原型的修改不会影响原构造函数的原型,也可以直接使用constructor来实现。原型作为新构造函数的原型)。
函数applyAndNew(构造函数,参数){
函数partial() {
返回constructor.apply(this,args);
}
if(type of constructor . prototype=== object ){
partial . prototype=object . create(constructor . prototype);
}
返回部分;
}
函数myConstructor() {
console . log( arguments . length: arguments . length )。
console.log(参数);
this . prop 1= val 1 ;
this . prop 2= val 2 ;
}
var myArguments=[hi , how , are , you , mr ,null];
var myconstructorwithrarguments=applyAndNew(my constructor,my arguments);
console . log(new myconstructorwithrarguments());
//(在我的构造函数中):arguments.length: 6
//(在我的构造函数中):[hi , how , are , you , Mr ,null]
//(在 new myconstructorwith arguments ):{ prop 1: val 1 ,prop2: val2}
当然,最常用的方法是文字数组。在没有扩展语法的情况下,只能结合使用push、splice、concat等方法,将已有的数组元素变成新数组的一部分。有了扩展语法,通过文字方式构造新数组将更简单、更优雅:
var parts=[肩膀,膝盖];
var lyrics=[head ,部分,和,脚趾];
//[头,肩,膝,和,脚趾]
可用于实现数组的浅层复制:
var arr=[1,2,3];
var arr2=[.arr];//like arr.slice()
arr 2 . push(4);
//此时arr2变成[1,2,3,4]
//arr不受影响
连接多个阵列:
var arr1=[0,1,2];
var arr2=[3,4,5];
var arr3=[.arr1,arr 2];
扩展操作符还可以将现有对象的所有可枚举属性复制到新构造的对象中。这个方法是浅拷贝,可以拷贝符号属性,但是不包含原型上的属性和方法。如果同时复制多个对象,后面的对象将覆盖同名的前面对象的属性。
var obj1={ foo: bar ,x: 42,[Symbol( a )]:123 };
var obj2={ foo: baz ,x: 100,y:13 };
var clonedObj={.obj 1 };
console . log(clonedObj);//{ foo: bar ,x: 42,[Symbol(a)]: 123 }
var mergedObj={.obj1,obj 2 };
console . log(merge dobj);//{ foo: baz ,x: 100,y: 13,[Symbol(a)]: 123 }
该方法在本质上类似于Object.assign,但是Object.assign()函数会触发setters,而扩展语法不会。
需要注意的事项
在数组或函数参数中使用扩展语法时,扩展运算符只能用于iterable对象。
只有在调用函数时,扩展运算符才能放在括号中,否则会报错。
它只能用于函数调用、文字数组(字符串可以在数组中展开)和文字对象。
当用于解构和分配数组时,扩展运算符只能位于最后一个位置。
展开的对象可以是任何迭代对象。
剩余参数
剩余参数语法允许我们将不定数量的参数表示为一个数组。如果函数的最后一个命名参数带有前缀.它将成为剩余参数的真实数组,其中从0(包括)到Args.length(不包括)的元素由传递给函数的实际参数提供。
rest语法看起来与扩展语法完全相同,只是Rest参数用于解构数组和对象。在某种意义上,余数语法与扩展语法相反:扩展语法将一个数组扩展成它的元素,而余数语法将多个元素收集并“浓缩”成一个元素。扩展运算符用于函数调用,而其余的参数用于函数声明。
其余的parameters和arguments对象之间有三个主要区别:
其余的参数只包含没有对应参数的参数,而arguments对象包含传递给函数的所有参数。
arguments对象不是真正的数组,而其余的参数是真正的数组实例,这意味着您可以直接对它使用所有的数组方法,如sort、map、forEach或pop。
arguments对象还有一些附加属性(如callee属性)。
如果剩余参数(包含在解构赋值中)的右边有一个逗号,就会抛出一个SyntaxError,因为剩余元素必须是函数的最后一个参数或者数组的最后一个元素。
以上是ES6扩展运算符的详细说明。更多关于ES6扩展运营商的信息,请关注我们的其他相关文章!