2021-07-04-js扩展运算符-展开语法与剩余语法

一,js展开语法 …

应用:函数调用/数组构造
作用:将数组表达式或者string在语法层面展开;还可以在构造字面量对象时, 将对象表达式按key-value的方式展开。
(译者注: 字面量一般指 [1, 2, 3] 或者 {name: “mdn”} 这种简洁的构造方式)

// A code block
add(...numbers)
function add(x, y, z) {
  return x + y + z;
}
 
const num = [1, 2, 3];
 
console.log(add(...numbers));
//  6
 
console.log(sum.apply(null, numbers));
// 6

1,等同于apply方式

var person = {
    fullName: function() {
        return this.firstName + " " + this.lastName + city + mount;
    }
}
var person1 = {
    firstName: "Bill",
    lastName: "Gates",
}
person.fullName.apply(person1); 
//BillGates

person.fullName.apply(person1,["GUA","U"]); 还可以添加参数
//Bill Gates GUA U (没有空格)

person.fullName.call(person1, "Oslo", "Norway");
//同上


  不同在于:
	call() 方法分别接受参数。
	apply() 方法接受数组形式的参数。

2,还可用于new方式(注意不能用new使用apply,apply是调用而不是构造)

var dateFields = [1970, 0, 1]; // 1970年1月1日
var d = new Date(...dateFields);

3,构造字面量数组或字符串时,取代只能组合使用 push, splice, concat 等方法

var parts = ['shoulders', 'knees']; 
var lyrics = ['head', ...parts, 'and', 'toes']; 
// ["head", "shoulders", "knees", "and", "toes"]
... 在构造字面量数组时, 可以在任意位置多次使用

4,数组拷贝(copy)


var arr = [1, 2, 3];
var arr2 = [...arr]; // like arr.slice()
arr2.push(4); 
 
// arr2 此时变成 [1, 2, 3, 4]
// arr 不受影响

实际上, 展开语法和 Object.assign() 行为一致, 执行的都是浅拷贝(只遍历一层)。如果想对多维数组进行深拷贝, 下面的示例就有些问题了。

var a = [[1], [2], [3]];
var b = [...a];
b.shift().shift(); // 1
// Now array a is affected as well: [[], [2], [3]]

Object.assign相同属性会覆盖

const o1 = { a: 1, b: 1, c: 1 };
const o2 = { b: 2, c: 2 };
const o3 = { c: 3 };

const obj = Object.assign({}, o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }

Array.concat 函数常用于将一个数组连接到另一个数组的后面

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// 将 arr2 中所有元素附加到 arr1 后面并返回
var arr3 = arr1.concat(arr2);
var arr3 = [...arr1, ...arr2];

Array.unshift 方法常用于在数组的开头插入新元素/数组. 不使用展开语法

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 = [...arr2, ...arr1]; // arr1 现在为 [3, 4, 5, 0, 1, 2]

5,只能用于可迭代对象

在数组或函数参数中使用展开语法时, 该语法只能用于 可迭代对象:

var obj = {'key1': 'value1'};
var array = [...obj]; // TypeError: obj is not iterable

6.使用限制

在函数调用时使用展开语法,请注意不能超过 JavaScript 引擎限制的最大参数个数。
JavaScriptCore引擎中有被硬编码的 参数个数上限:65536

展开语法为解析,而剩余语法为结构数组和对象。从某种意义上说,剩余语法与展开语法是相反的:展开语法将数组展开为其中的各个元素,而剩余语法则是将多个元素收集起来并“凝聚”为单个元素。

二,剩余语法

作用:允许我们将一个不定数量的参数表示为一个数组。

1,举例

function(a, b, ...theArgs) {
  // ...
}
```,1,函数的最后一个命名参数以...为前缀,则它将成为一个由剩余参数组成的真数组,其中从0(包括)到theArgs.length(排除)的元素由传递给函数的实际参数提供。

```javascript
function f(...[a, b, c]) {
  return a + b + c;
}

f(1)          // NaN (b and c are undefined)
f(1, 2, 3)    // 6
f(1, 2, 3, 4) // 6 (the fourth parameter is not destructured)

2,剩余参数和 arguments对象之间的区别主要有三个:

  1. 剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参。
  2. arguments对象不是一个真正的数组,而剩余参数是真正的 Array实例,也就是说你能够在它上面直接使用所有的数组方法,比如 sort,map,forEach或pop。
  3. arguments对象还有一些附加的属性 (如callee属性)。

arguments 是一个对应于传递给函数的参数的类数组对象。

function func1(a, b, c) {
  console.log(arguments[0]);
  // expected output: 1

  console.log(arguments[1]);
  // expected output: 2

  console.log(arguments[2]);
  // expected output: 3


}

func1(1, 2, 3);

1),arguments对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引0处。例如,如果一个函数传递了三个参数,你可以以如下方式引用他们:

2)参数也可以被设置:

arguments[1] = 'new value';

3)arguments对象不是一个 Array 。它类似于Array,但除了length属性和索引元素之外没有任何Array属性
例如,它没有 pop 方法。但是它可以被转换为一个真正的Array:

var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);

// ES2015
const args = Array.from(arguments);
const args = [...arguments];

4)typeof

typeof arguments);    // 'object'
typeof arguments[0]) //this will return the typeof individual arguments.

5)还可以使用Array.from()方法或扩展运算符将参数转换为真实数组:

var args = Array.from(arguments);
var args = [...arguments];

6)属性

  1. arguments.callee
    指向参数所属的当前执行的函数。
    指向调用当前函数的函数。
  2. arguments.length
    传递给函数的参数数量。
  3. arguments[@@iterator]
    返回一个新的Array 迭代器 对象,该对象包含参数中每个索引的值。
    注意: 在严格模式下,arguments对象已与过往不同。arguments[@@iterator]不再与函数的实际形参之间共享,同时caller属性也被移除。

7)这个例子定义了一个函数来连接字符串。这个函数唯一正式声明了的参数是一个字符串,该参数指定一个字符作为衔接点来连接字符串

function myConcat(separator) {
  var args = Array.prototype.slice.call(arguments, 1);
  return args.join(separator);
  Array.prototype--实例化对象:每个函数就是一个对象(Function),函数对象都有一个子对象 prototype对象,类是以函数的形式来定义的。prototype表示该函数的原型,也表示一个类的成员的集合。
}


你可以传递任意数量的参数到该函数,并使用每个参数作为列表中的项创建列表。

// returns "red, orange, blue"
myConcat(", ", "red", "orange", "blue");

// returns "elephant; giraffe; lion; cheetah"
myConcat("; ", "elephant", "giraffe", "lion", "cheetah");

// returns "sage. basil. oregano. pepper. parsley"
myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");

8)arguments对象可以与剩余参数、默认参数和解构赋值参数结合使用。

function foo(...args) {
  return args;
}
foo(1, 2, 3);  // [1,2,3]

3,theArgs是个数组,所以你可以使用length属性得到剩余参数的个数:

function fun1(...theArgs) {
  alert(theArgs.length);
}

fun1();  // 弹出 "0", 因为theArgs没有元素
fun1(5); // 弹出 "1", 因为theArgs只有一个元素
fun1(5, 6, 7); // 弹出 "3", 因为theArgs有三个元素

本博客内容参考于此博客,详情请了解链接: js 中 … 的用法.
链接: 剩余语法.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值