1. 扩展运算符
其实就是三个点(...). 主要用于函数调用与数组字面量.
- fn(...arr)
- [...arr,1,2,3]
函数传参
目前为止, 我们都是使用 Function.prototype.apply 方法来将一个数组展开成多个参数:
function fn(x, y, z) { }
- var args = [0, 1, 2];
- fn.apply(null, args);
- // 使用...
- function fn(x, y, z) { }
- var args = [0, 1, 2];
- fn(...args);
数据解构
- let cold = ['autumn', 'winter'];
- let warm = ['spring', 'summer'];
- // 析构数组
- let otherSeasons, autumn;
- [autumn, ...otherSeasons] = cold;
- otherSeasons // => ['winter']
数据构造
- // 字符串转为真正的数组.
- [...'hello']
- // [ "h", "e", "l", "l", "o" ]
- // 两个对象连接返回新的对象
- let a = {aa:'aa'}
- let b = {bb:'bb'}
- let c = {...a,...b}
- console.log(c)
- // {"aa":"aa","bb":"bb"}
- // 两个数组连接返回新的数组
- let d = ['dd']
- let e = ['ee']
- let f = [...d,...e]
- console.log(f)
- // ["dd","ee"]
- // 数组加上对象返回新的数组
- let g = [{gg:'gg'}]
- let h = {hh:'hh'}
- let i = [...g,h]
- console.log(i)
- // [{"gg":"gg"},{"hh":"hh"}]
- // 数组 + 字符串
- let j = ['jj']
- let k = 'kk'
- let l = [...j,k]
- console.log(l)
- // ["jj","kk"]
- // 带有数组和对象的结合
- let state = {
- resultList: [],
- currentPage: 0,
- totalRows: {}
- }
- let data = {
- resultList: [{new:'new'}],
- currentPage: 2,
- totalRows: {row:'row'}
- }
- let combile = {
- ...state,
- resultList: [
- ...state.resultList,
- ...data.resultList
- ],
- currentPage: data.currentPage,
- totalRows: data.totalRows
- }
- console.log(combile)
- // {"resultList":[{"new":"new"}],"currentPage":2,"totalRows":{"row":"row"}}
- Array.from()
请查看: es6 日常经常用到的知识点(var,let,const, set, Array.from())-- 总结 1
Array.of()
Array.of 方法用于将一组值, 转换为数组. Array.of 总是返回参数值组成的数组. 如果没有参数, 就返回一个空数组.
这个方法的主要目的, 是弥补数组构造函数 Array()的不足. 因为参数个数的不同, 会导致 Array()的行为有差异.
Array.of 基本上可以用来替代 Array()或 new Array(), 并且不存在由于参数不同而导致的重载. 它的行为非常统一.
- Array() // []
- Array(3) // [, , ,]
- Array(3, 11, 8) // [3, 11, 8]
- Array.of(3, 11, 8) // [3,11,8]
- Array.of(3) // [3]
- Array.of(3).length // 1
- Array.of() // []
- Array.of(undefined) // [undefined]
- Array.of(1) // [1]
- Array.of(1, 2) // [1, 2]
Array.of 方法可以用下面的代码模拟实现.
- function ArrayOf(){
- return [].slice.call(arguments);
- }
数组实例的 copyWithin()
数组实例的 copyWithin 方法, 在当前数组内部, 将指定位置的成员复制到其他位置(会覆盖原有成员), 然后返回当前数组. 也就是说, 使用这个方法, 会修改当前数组.
Array.prototype.copyWithin(target, start = 0, end = this.length)
它接受三个参数.
target (必需): 从该位置开始替换数据.
start (可选): 从该位置开始读取数据, 默认为 0 . 如果为负值, 表示倒数.
end (可选): 到该位置前停止读取数据, 默认等于数组长度. 如果为负值, 表示倒数.
这三个参数都应该是数值, 如果不是, 会自动转为数值.
- // 将 3 号位复制到 0 号位
- [1, 2, 3, 4, 5].copyWithin(0, 3, 4)
- // [4, 2, 3, 4, 5]
- // -2 相当于 3 号位,-1 相当于 4 号位
- [1, 2, 3, 4, 5].copyWithin(0, -2, -1)
- // [4, 2, 3, 4, 5]
- // 将 3 号位复制到 0 号位
- [].copyWithin.call({length: 5, 3: 1}, 0, 3)
- // {0: 1, 3: 1, length: 5}
- // 将 2 号位到数组结束, 复制到 0 号位
- let i32a = new Int32Array([1, 2, 3, 4, 5]);
- i32a.copyWithin(0, 2);
- // Int32Array [3, 4, 5, 4, 5]
- // 对于没有部署 TypedArray 的 copyWithin 方法的平台
- // 需要采用下面的写法
- [].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
- // Int32Array [4, 2, 3, 4, 5]
数组实例的 find() 和 findIndex()
数组实例的 find 方法, 用于找出第一个符合条件的数组成员. 它的参数是一个回调函数, 所有数组成员依次执行该回调函数, 直到找出第一个返回值为 true 的成员, 然后返回该成员. 如果没有符合条件的成员, 则返回 undefined.
- [1, 5, 10, 15].find(function(value, index, arr) {
- return value> 9;
- }) // 10
- //find 方法的回调函数可以接受三个参数, 依次为当前的值, 当前的位置和原数组.
数组实例的 findIndex 方法的用法与 find 方法非常类似, 返回第一个符合条件的数组成员的位置, 如果所有成员都不符合条件, 则返回 - 1.
- [1, 5, 10, 15].findIndex(function(value, index, arr) {
- return value> 9;
- }) // 2
这两个方法都可以接受第二个参数, 用来绑定回调函数的 this 对象.
- function f(v){
- return v> this.age;
- }
- let person = {name: 'John', age: 20};
- [10, 12, 26, 15].find(f, person); // 26
另外, 这两个方法都可以发现 NaN, 弥补了数组的 indexOf 方法的不足.
- [NaN].indexOf(NaN)
- // -1
- [NaN].findIndex(y => Object.is(NaN, y))
- // 0
- // 上面代码中, indexOf 方法无法识别数组的 NaN 成员, 但是 findIndex 方法可以借助 Object.is 方法做到.
数组实例的 fill()
fill 方法使用给定值, 填充一个数组.
- ['a', 'b', 'c'].fill(7)
- // [7, 7, 7]
- new Array(3).fill(7)
- // [7, 7, 7]
- ['a', 'b', 'c'].fill(7, 1, 2)
- // ['a', 7, 'c']
上面代码表明, fill 方法用于空数组的初始化非常方便. 数组中已有的元素, 会被全部抹去.
fill 方法还可以接受第二个和第三个参数, 用于指定填充的起始位置和结束位置
注意, 如果填充的类型为对象, 那么被赋值的是同一个内存地址的对象, 而不是深拷贝对象.
- let arr = new Array(3).fill({name: "Mike"});
- arr[0].name = "Ben";
- arr
- // [{name: "Ben"}, {name: "Ben"}, {name: "Ben"}]
- let arr = new Array(3).fill([]);
- arr[0].push(5);
- arr
- // [[5], [5], [5]]
数组实例的 entries(),keys() 和 values()
ES6 提供三个新的方法 -- entries(),keys()和 values() -- 用于遍历数组. 它们都返回一个遍历器对象, 可以用 for...of 循环进行遍历, 唯一的区别是 keys()是对键名的遍历, values()是对键值的遍历, entries()是对键值对的遍历
- for (let index of ['a', 'b'].keys()) {
- console.log(index);
- }
- // 0
- // 1
- for (let elem of ['a', 'b'].values()) {
- console.log(elem);
- }
- // 'a'
- // 'b'
- for (let [index, elem] of ['a', 'b'].entries()) {
- console.log(index, elem);
- }
- // 0 "a"
- // 1 "b"
如果不使用 for...of 循环, 可以手动调用遍历器对象的 next 方法, 进行遍历.
- let letter = ['a', 'b', 'c'];
- let entries = letter.entries();
- console.log(entries.next().value); // [0, 'a']
- console.log(entries.next().value); // [1, 'b']
- console.log(entries.next().value); // [2, 'c']
数组实例的 includes()
Array.prototype.includes 方法返回一个布尔值, 表示某个数组是否包含给定的值, 与字符串的 includes 方法类似.
- [1, 2, 3].includes(2) // true
- [1, 2, 3].includes(4) // false
- [1, 2, NaN].includes(NaN) // true
该方法的第二个参数表示搜索的起始位置, 默认为 0. 如果第二个参数为负数, 则表示倒数的位置, 如果这时它大于数组长度(比如第二个参数为 - 4, 但数组长度为 3), 则会重置为从 0 开始.
- [1, 2, 3].includes(3, 3); // false
- [1, 2, 3].includes(3, -1); // true
indexOf 的两个缺点:
一, 不够语义化, 其含义是找到参数值的第一个出现位置, 表达起来不够直观;
二, 其内部使用 === 判断, 会导致对 NaN 的误判
- [NaN].indexOf(NaN)
- // -1
- [NaN].includes(NaN)
- // true
数组的空位
数组的空位指, 数组的某一个位置没有任何值. 比如, Array 构造函数返回的数组都是空位.
Array(3) // [, , ,]
上面代码中, Array(3)返回一个具有 3 个空位的数组.
注意, 空位不是 undefined, 一个位置的值等于 undefined, 依然是有值的. 空位是没有任何值, in 运算符可以说明这一点.
- 0 in [undefined, undefined, undefined] // true
- 0 in [, , ,] // false
上面代码说明, 第一个数组的 0 号位置是有值的, 第二个数组的 0 号位置没有值.
ES5 对空位的处理, 已经很不一致了, 大多数情况下会忽略空位.
forEach(), filter(), reduce(), every() 和 some()都会跳过空位.
map()会跳过空位, 但会保留这个值
join()和 toString()会将空位视为 undefined, 而 undefined 和 null 会被处理成空字符串.
- // forEach 方法
- [,'a'].forEach((x,i) => console.log(i)); // 1
- // filter 方法
- ['a',,'b'].filter(x => true) // ['a','b']
- // every 方法
- [,'a'].every(x => x==='a') // true
- // reduce 方法
- [1,,2].reduce((x,y) => return x+y) // 3
- // some 方法
- [,'a'].some(x => x !== 'a') // false
- // map 方法
- [,'a'].map(x => 1) // [,1]
- // join 方法
- [,'a',undefined,null].join('#') // "#a##"
- // toString 方法
- [,'a',undefined,null].toString() // ",a,,"
ES6 则是明确将空位转为 undefined.
- //Array.from 方法会将数组的空位, 转为 undefined, 也就是说, 这个方法不会忽略空位.
- Array.from(['a',,'b'])
- // [ "a", undefined, "b" ]
- // 扩展运算符 (...) 也会将空位转为 undefined.
- [...['a',,'b']]
- // [ "a", undefined, "b" ]
- //copyWithin()会连空位一起拷贝.
- [,'a','b',,].copyWithin(2,0) // [,"a",,"a"]
- //fill()会将空位视为正常的数组位置.
- new Array(3).fill('a') // ["a","a","a"]
- //for...of 循环也会遍历空位.
- let arr = [, ,];
- for (let i of arr) {
- console.log(1);
- }
- // 1
- // 1
- // 上面代码中, 数组 arr 有两个空位, for...of 并没有忽略它们. 如果改成 map 方法遍历, 空位是会跳过的.
entries(),keys(),values(),find()和 findIndex()会将空位处理成 undefined.
- // entries()
- [...[,'a'].entries()] // [[0,undefined], [1,"a"]]
- // keys()
- [...[,'a'].keys()] // [0,1]
- // values()
- [...[,'a'].values()] // [undefined,"a"]
- // find()
- [,'a'].find(x => true) // undefined
- // findIndex()
- [,'a'].findIndex(x => true) // 0
由于空位的处理规则非常不统一, 所以建议避免出现空位.
来源: http://www.qdfuns.com/article/18271/f8ba5496a88bdd5cea1df43fab475abb.html