javascript使用符号三个点(…)作为剩余运算符和展开运算符,不过这两个运算符是有区别的。
最主要的区别就是,剩余运算符将用户提供的某些特定值的其余部分放入javascript数组中,而展开运算符则将可迭代的对象展开为单个元素。
例如下面这段代码,其中使用了剩余运算符将部分值存放到数组中:
// u rest to enclo the rest of specific ur-supplied values into an array:function mybio(firstname, lastname, ...otherinfo) { return otherinfo;}// invoke mybio function while passing five arguments to its parameters:mybio("oluwatobi", "sofela", "codesweetly", "web developer", "male");// the invocation above will return:["codesweetly", "web developer", "male"]
查看运行结中秋节征文果
上面的代码中,我们使用…otherinfo将传入函数mybio()参数中的剩余部分”codesweetly”,”we developer”和”male”存放到数组中。
然后我们再来看下面这个例子,其中使用了展开运算符:
// define a function with three parameters:function mybio(firstname, lastname, company) { return `${firstname} ${lastname} runs ${company}`;}// u spread to expand an array's items into individual arguments:mybio(...["oluwatobi", "sofela", "codesweetly"]);// the invocation above will return:“oluwatobi sofela runs codesweetly”
查看运行结果
上面的代码中,我们使用展开运算符(…)将数组[“oluwatobi”, “sofela”, “codesweetly”]的内容逐一展开并传递给函数mybio()的参数。
如果你对剩余运算符和展开运算符不是很熟悉,不用太担心,本文接下来会对它们进行介绍。
在接下来的章节中,我们将详细讨论剩余运算符和展开运算符在javascript中是如何工作的。
正如上面所提到的,剩余运算符将用户提供的某些特定值的其余部分放入javascript数组中。语法如下:
...yourvalues
上面代码中的三个点(…)用来表示剩余运算符。
剩余运算符之后的内容用来表示你希望填充到数组中的值。注意,只能在函数定义的最后一个参数中使用剩余运算符。
在javascript函数中,剩余运算符被用在函数最后一个参数的前面。如下面的代码:
// define a function with two regular parameters and one rest parameter:function mybio(firstname, lastname, ...otherinfo) { return otherinfo;}
这里,剩余运算符告诉javascript程序将用户提供给参数otherinfo的任何值都添加到一个数组中。然后,将该数组赋值给otherinfo参数。
因此,我们将…otherinfo称之为剩余参数。
需要注意的是,调用时传递给函数的实参中剩余参数是可选的。
另一个例子:
// define a function with two regular parameters and one rest parameter:function mybio(firstname, lastname, ...otherinfo) { return otherinfo;}// invoke mybio function while passing five arguments to its parameters:mybio("oluwatobi", "sofela", "codesweetly", "web developer", "male");// the invocation above will return:["codesweetly", "web developer", "male"]
查看运行结果
上面的代码中,调用函数mybio()时传入了5个参数,而函数mybio()的实参只有3个。也就是说,参数”oluwatobi”和”sofela”分别传递给了firstname和lastname,其它的参数(”codesweetly”,”web developer”和”male”)都传递给了剩余参数otherinfo。所以,函数mybio()返回的jazz是什么舞种结果是[“codesweetly”, “web developer”, “male”],它们都是剩余参数otherinfo的内容。
记住,不能在任何包含剩余参数,默认参数,或参数解构的函数体中使用”u s母亲节图trict”指令。否则,javascript将报语法错误。
考虑下面的代码:
// define a function with one rest parameter:function printmyname(...value) { "u strict"; return value;}// the definition above will return:"uncaught syntaxerror: illegal 'u strict' directive in function with non-simple parameter list"
注意:只有当整个脚本或封闭作用域处于strict模式时,才可以将”u strict”放到函数体外。
现在我们知道了剩余运算符在函数中的作用,接下来我们来看看它在参数解构中是如何工作的。
剩余运算符在参数解构赋值时通常被用在最后一个变量的前面。下面是一个例子:
// define a destructuring array with two regular variables and one rest variable:const [firstname, lastname, ...otherinfo] = [ "oluwatobi", "sofela", "codesweetly", "web developer", "male"];// invoke the otherinfo variable:console.log(otherinfo);// the invocation above will return:["codesweetly", "web developer", "male"]
查看运行结果
这里的剩余运算符(…)告诉javascript程序将用户提供的其它值都添加到一个数组中。然后,将该数组赋值给otherinfo变量。
因此,我们将这里的…otherinfo称之为剩余变量。
另一个例子:
// define a destructuring object with two regular variables and one rest variable:const { firstname, lastname, ...otherinfo } = { firstname: "oluwatobi", lastname: "sofela", companyname: "codesweetly", profession: "web developer", gender: "male"}// invoke the otherinfo variable:console.log(otherinfo);// the invocation above will return:{companyname: "codesweetly", profession: "web developer", gender: "male"}
查看运行结果
注意上面的代码中,剩余运算符将一个属性对象(而不是数组)赋值给otherinfo变量。也就是说,当你在解构一个对象时使用剩余运算符,它将生成一个属性对象而非数组。
但是,如果你在解构数组或函数时使用剩余运算符,它将生成数组字面量。
你应该已经注意到了,在javascript arguments和剩余参数之间存在一些区别,下面我们来看看这些区别都有哪些。
下面我列出了javascript arguments和剩余参数之间的一些区别:
区别1:arguments对象是一个类似于数组的对象,但它并非真正的数组!
请记住这一点,javascript arguments对象不是真正的数组。它是一个类似于数组的对象,不具备数组所拥有的任何特性。
而剩余参数是一个真正的数组,你可以在它上面使用数组所拥有的任何方法。例如,你可以对一个剩余参数使用sort()、map()、foreach()或pop()方法。但你不能对arguments对象使用这些方法。
区别2:不能在箭头函数中使用arguments对象
arguments对象在箭头函数中不可用,而剩余参数在所有的函数中都是可用的,也包括箭头函数。
区别3:优先使用剩余参数
优先使用剩余参数而不是arguments对象,特别是在编写es6兼容代码时。
我们已经了解了剩余运算符是如何工作的,下面我们来讨论下展开运算符,并看看它和剩余运算符之间的区别。
展开运算符(…)将一个可迭代的对象展开为单个元素。
展开运算符可以应用在数组字面量,函数调用,以及被初始化的属性对象中,它将可迭代对象的值逐一展开到单独的元素中。实际上,它和剩余操作符正好相反。
注意,只有在数组字面量,函数调用,或被初始化的属性对象中使用展开运算符时才有效。
下面我们来看一些实际的例子。
示例1:展开运算符在数组字面量中如何工作
const myname = ["sofela", "is", "my"];const aboutme = ["oluwatobi", ...myname, "name."];console.log(aboutme);// the invocation above will return:[ "oluwatobi", "sofela", "is", "my", "name." ]
查看运行结果
上面的代码中,展开运算符(…)将数组myname拷贝到aboutme中。
注意:
对myname的任何修改不会反映到aboutme中。因为myname数组中的所有值都是原语。扩展操作符只是简单地将myname数组的内容复制并粘贴到aboutme中,而不创建任何对原始数组元素的引用。展开运算符只做浅拷贝。所以,当myname数组中包含任何非原语值时,javascript将在myname和aboutme之间创建一个引用。有关展开运算符如何处理原语值和非原语值的更多信息,可以查看这里。假设我们没有使用展开运算符来复制数组myname的内容,例如我们编写这行代码const aboutme = [ “oluwatobi”, myname, “name.” ] 这种情况下javascript将给myname分配一个引用,这样,所有对myname数组所做的修改就都会反映到aboutme数组中。示例2:如何使用展开运算符将字符串转换为数组
const myname = "oluwatobi sofela";console.log([...myname]);// the invocation above will return:[ "o", "l", "u", "w", "a", "t", "o", "b", "i", " ", "s", "o", "f", "e", "l", "a" ]
查看运行结果
上面的代码中,我们在数组字面量中使用展开运算符([…])将myname字符串的值展开为一个数组。这样,字符串”oluwatobi sofela”的内容被展开到数组[ “o”, “l”, “u”, “w”, “a”, “t”, “o”, “b”, “i”, ” “, “s”, “o”, “f”, “e”, “l”, “a” ]中。
示例3:展开运算符如何在函数调用中工作
const numbers = [1, 3, 5, 7];function addnumbers(a, b, c, d) { return a + b + c + d;}console.log(addnumbers(...numbers));// the invocation above will return:16
查看运行结果
上面的代码中,我们使用展开运算符将数组numbers的内容展开并传递给函数addnumbers()的参数。如果数组numbers的元素多于4个,javascript只会将前4个元素作为参数传递给函数addnumbers()而忽略其余的元素。
下面是一些其它的例子:
const numbers = [1, 3, 5, 7, 10, 200, 90, 59];function addnumbers(a, b, c, d) { return a + b + c + d;}console.log(addnumbers(...numbers));// the invocation above will return:16
查看运行结果
const myname = "oluwatobi sofela";function spellname(a, b, c) { return a + b + c;}console.log(spellname(...myname)); // returns: "olu"console.log(spellname(...myname[3])); // returns: "wundefinedundefined"console.log(spellname([...myname])); // returns: "o,l,u,w,a,t,o,b,i, ,s,o,f,e,l,aundefinedundefined"console.log(spellname({...myname})); // returns: "[object object]undefinedundefined"
查看运行结果
示例4:展开运算符在对象字面量中如何工作
const mynames = ["oluwatobi", "sofela"];const bio = { ...mynames, runs: "codesweetly.com" };console.log(bio);// the invocation above will return:{ 0: "oluwatobi", 1: "sofela", runs: "codesweetly.com" }
查看运行结果
上面的代码中,我们在bio对象内部使用展开运算符将数组mynames的值展开为各个属性。
当使用展开运算符时,请记住以下三个基本信息。
由于属性对象是非可迭代对象,所以不能使用展开运算符将它的值进行展开。但是,你可以使用展开运算符将一个对象的属性克隆到另一个对象中。
看下面这个例子:
const myname = { firstname: "oluwatobi"内蒙古大草原旅游, lastname: "sofela" };const bio = { ...myname, website: "codesweetly.com" };console.log(bio);// the invocation above will return:{ firstname: "oluwatobi", lastname: "sofela", website: "codesweetly.com" };
查看运行结果
上面的代码中,我们使用展开运算符将myname对象的内容克隆到了bio对象中。
注意:
展开运算符只能展开可迭代对象的值。只有当一个对象包含一个带有@@iterator key的属性时,才是一个可迭代的对象。array,typedarray,string,map,t都是内置的可迭代类型,因为它们默认都带有@@iterator属性。属性对象是非可迭代数组类型,因为默认情况下它没有@@iterator属性。可以在属性对象上添加@@iterator使其成为可迭代对象。假设我们使用展开运算符将对象a的属性克隆到对象b中,如果对象b包含与对象a中相同的属性,那么对象b的属性将覆盖对象a的属性。换句话说,在这个过程中,对象a中那些与对象b相同的属性不会被克隆。
看下面这个例子:
const myname = { firstname: "tobi", lastname: "sofela" };const bio = { ...myname, firstname: "oluwatobi", website: "codesweetly.com" };console.log(bio);// the invocation above will return:{ firstname: "oluwatobi", lastname: "sofela", website: "codesweetly.com" };
查看运行结果
注意,展开运算符没有将myname对象的firstname属性的值复制到bio对象中,因为对象bio中已经包含firstname属性了。
如果在只包含原语值的对象(或数组)上使用展开运算符,javascript不会在原对象和复制对象之间创建任何引用。
看下面这段代码:
const myname = ["sofela", "is", "my"];const aboutme = ["oluwatobi", ...myname, "name."];console.log(aboutme);// the invocation above will return:["oluwatobi", "sofela", "is", "my", "name."]
查看运行结果
注意,myname中的每一个元素都是一个原语值,因此,当我们使用展开运算符将myname克隆到aboutme时,javascript不会在两个数组之间创建任何引用。所以,对myname数组所做的任何修改都不会反映到aboutme数组中,反之亦然。
让我们给myname数组添加一个元素:
myname.push("real");
现在我们来检查一下myname和aboutme的值:
console.log(myname); // ["sofela", "is", "my", "real"]console.log(aboutme); // ["oluwatobi", "sofela", "is", "my", "name."]
请注意,我们对myname数组的修改并没有反映到aboutme数组中,因为展开运算符并没有在原始数组和复制数组之间创建任何引用。
假设myname包含非原语项,这种情况下,展开运算符将在原数组的非原语项和克隆项之间创建一个引用。
看下面的例子:
const myname = [["sofela", "is", "my"]];const aboutme = ["oluwatobi", ...myname, "name."];console.log(aboutme);// the invocation above will return:[ "oluwatobi", ["sofela", "is", "my"], "name." ]
查看运行结果
注意,这里的myname数组包含一个非原语项。
因此,当使用展开运算符将myname的内容克隆到aboutme时,javascript将在两个数组之间创建一个引用。这样,任何对myname数组的修改都会反映到aboutme数组中,反之亦然。
作为例子,我们同样给myname数组添加一个元素:
myname[0].push("real");
现在我们来查看myname和aboutme的值:
console.log(myname); // [["sofela", "is", "my", "real"]]console.log(aboutme); // ["oluwatobi", ["sofela", "is", "my", "real"], "name."]
查看运行结果
注意,对myname数组的修改内容反映到了aboutme数组中,因为展开运算符在原始数组和复制数组之间创建了一个引用。
另外一个例子:
const myname = { firstname: "oluwatobi", lastname: "sofela" };const bio = { ...myname };myname.firstname = "tobi";console.log(myname); // { firstname: "tobi", lastname: "sofela" }console.log(bio); // { firstname: "oluwatobi", lastname: "sofela" }
查看运行结果
上面的代码中,myname的更新内容没有反映到bio对象中,因为我们在只包含原语值的对象上使用展开运算符。
注意,开发人员通常将这里的myname称之为浅对象,因为它只包含原语项。
另外一个例子:
const myname = { fullname: { firstname: "oluwatobi", lastname: "sofela" }};const bio = { ...myname };myname.fullname.firstname = "tobi";console.log(myname); // { fullname: { firstname: "tobi", lastname: "sofela" } }console.log(bio); // { fullname: { firstname: "tobi", lastname: "sofela" } }
查看运行结果
上面的代码中,myname的更新内容被反映到bio对象中,因为我们在包含非原语值的对象上使用了展开运算符。
注意:
我们称这里的myname为深对象,因为它包含非原语项。将一个对象克隆到另一个对象时,如果创建了引用,则进行的是浅拷贝。例如,…myname产生了myname对象的一个浅拷贝,因为你对其中一个对象所做的任何修改都会反映到另一个对象中。将一个对象克隆到另一个对象时,如果没有创建引用,则进行的时深拷贝。例如,我可以通过const bio = json.par(json.stringify(myname))将myname对象深拷贝到bio对象中。如此一来,javascript将把myname克隆到bio中而不创建任何引用。我们可以通过用一个新对象来替换myname或bio中的fullname子对象,从而切断myname和bio之间的引用。例如,使用myname.fullname = { firstname: “tobi”, lastname: “sofela” }来断开myname和bio之间的指针。本文讨论了剩余操作符和展开操作符之间的区别,并通过示例说明了它们在javascript中是如何工作的。
到此这篇关于javasc没考上大学怎么办ript展开运算符和剩余运算符的区别详解的文章就介绍到这了,更多相关javascript展开运算符和剩余运算符 内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!
本文发布于:2023-04-04 11:24:54,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/370721d182582fc6c3ea4837ffd41825.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:JavaScript展开运算符和剩余运算符的区别详解.doc
本文 PDF 下载地址:JavaScript展开运算符和剩余运算符的区别详解.pdf
留言与评论(共有 0 条评论) |