SOURCE

// 等号表达式是典型的赋值形式,函数传参和for循环的变量都是特殊形式的赋值。解构的原理是赋值的两边具有相同的结构,就可以正确取出数组或对象里面的元素或属性值,省略了使用下标逐个赋值的麻烦。

// 对于三个点号,三点放在形参或者等号左边为rest运算符; 放在实参或者等号右边为spread运算符,或者说,放在被赋值一方为rest运算符,放在赋值一方为扩展运算符。
//... 拓展运算符 
console.log(...[1, 2, 3])//  会返回带逗号的参数序列 1 2 3
console.log([1,2,...[3,4,5]]) // 返回[1,2,3,4,5]

//用于函数时  用于函数参数时...
function push(array, ...items) {
  var arr1 array.push(...items);
return arr1;
}
push([],1,2,3,4)//  rest参数 items这个形参时变成数组[1,2,3,4] 在 push()items中为实参

function add(x, y) {
  return x + y;
}
const numbers = [4, 38];
add(...numbers) // 42 同上

//扩展运算符与正常的函数参数可以结合使用,非常灵活。

function f(v, w, x, y, z) { }
const args = [0, 1];
f(-1, ...args, 2, ...[3]);

//扩展运算符后面还可以放置表达式。
var number= 1;
var arr1 = [1,...(numver==1?['a']:['b']),3] //[1,'a',3];
//如果扩展运算符后面是一个空数组,则不产生任何效果。
[...[], 1] //[1]


//代替函数apply方法 
//例一 将数组转换为函数参数
function f(x,y,z){
  return arguments
}
//es5
f.apply(null,[1,2,3])// [1,2,3];
//es6
f(...[1,2,3])// [1,2,3];

// 例子2,获取数组中的最大值
//es5
Math.max.apply(null,[1,2,3,4,8,6,4])// 8;
//es6
Math.max(...[1,2,3,4,8,6,4])// 8;

// 例子3 是通过push函数,将一个数组的元素添加到另一个数组的尾部。
// es5
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1,arr2);
//es6
arr1.push(...arr2);

// 扩展运算符的应用
// 1.复制数组
//e5
let a1 =[1,2];
let a2 = a1.concat();
let a2 = a1.slice(0);
a1[0]='aa'
console.log(a2)

//es6
let a2 = [...a1];
[...a2] = a1;

// 2.合并数组
//es5
var a1 = [1,2,3];
var a2 = [4,5,6];

a1.concat(a2);
// es6
[...a1,...a2]

// 3.与解构赋值结合
// es5
var list=[1,2,3,4];
a = list[0]; b=list.slice(1);
// es6 解构用于数组时是根据数组的index值来对应
[a,...b]= list; //解构配合rest 返回a=1;b=[2,3,4];

const [...b,a]= [12,12,12,312,,]//会报错 因为扩展运算符用于数组赋值时,只能放在参数的最后一位否则会报错;

//实现了 Iterator 接口的对象
//任何Iterrator接口的对象,都可以用扩展运算符转为真正的数组
//如querySelectorAll 获取到的事nodeLIst数组便可以用扩展运算符转为真正耳朵数组
//例子1
var nodeList = document.querySelectorAll('div');
var arr1 = [...nodeList]; //返回一个真正的数组因为nodeList有iterator接口;

//对于那些没有部署 Iterator 接口的类似数组的对象,扩展运算符就无法将其转为真正的数组。
let arrayLike = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  length: 3
};

// TypeError: Cannot spread non-iterable object. 不可遍历 会报错
let arr = [...arrayLike];
// 可以使用Array.from 去转成数组 用于可迭代对象和 部署了iterator接口 es6
Array.from(arrayLike)// ['a','b','c'];
// es5
var obj = [].slice.call(arrayLike)// ['a','b','c'];

// 但是可以自己去部署iterator接口

var obj={
  data:['chen','shi','gold']
}

obj.prototype[Symbol.iterator]=function(){
  var index = this.index=0;
   this.next(){
     if(index<this.data.length){
       index++
       return {
         value:this.data[index - 1],
         done:false
       }
     }else{
           return {
         value:undefined,
         done:true
       }
     }
   }  
}

//如果是类数组的话 可以直接引用数组的iterator接口
var obj={ 
0:'chen', 
1:'shi', 
2:'zhen', 
length:3 
} 
Object.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; //这样做会使得对象直接有接口不是很好 
console.log([…obj])

// 为单个类数组对象添加 iterator接口
var obj={ 
0:'chen', 
1:'shi', 
2:'zhen', 
length:3 ,
  [Symbol.iterator]:[][Symbol.iterator]
} 
console.log(...obj)// chen shi zhen

// Array.from 应用
//Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
// NodeList对象

let ps = document.querySelectorAll('p');
//直接把类数组转为数组 传的第一个参数为需要转的类数组,第二个是类似map
Array.from(ps).filter(p => {
  return p.textContent.length > 100;
});

// arguments对象  
function foo() {
  //同上
  var args = Array.from(arguments);
  // ...
}

//只要是部署了 Iterator 接口的数据结构,Array.from都能将其转为数组。

Array.from('hello')
// ['h', 'e', 'l', 'l', 'o']

let namesSet = new Set(['a', 'b'])
Array.from(namesSet) // ['a', 'b']

//扩展运算符背后调用的是遍历器接口(Symbol.iterator),如果一个对象没有部署这个接口,就无法转换。Array.from方法还支持类似数组的对象。所谓类似数组的对象,本质特征只有一点,即必须有length属性。因此,任何有length属性的对象,都可以通过Array.from方法转为数组,而此时扩展运算符就无法转换。

Array.from({ length: 3 });
// [ undefined, undefined, undefined ]
//上面代码中,Array.from返回了一个具有三个成员的数组,每个位置的值都是undefined。扩展运算符转换不了这个对象。
Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);

Array.from([1, 2, 3], (x) => x * x)
// [1, 4, 9]

let spans = document.querySelectorAll('span.name');
let name1 =Array.prototype.map.call(spans,(value) => value.textContent);

let name2 =Array.from(name1,(value) => value.textContent)

//数组中 布尔值为false的 返回0
let name3 = Array.from([1,'',2,3],(x) => x || 0);

function typeoof(){
  return Array.from(arguments,(x) => typeof x)
}
typeoof(1,'1')

//例子2 可以用来创造规定个数的数组

function createArr(){
  return Array.from({length:3},(x) => 'chenshi')
}























console 命令行工具 X clear

                    
>
console