扩展运算符( spread )是三个点( ...)如同 rest 参数的逆运算 将一个数组转为用逗号分隔参数序列
console.log(...[1,2,3,4]) // 1 2 3 4
console.log(l , ...[2 , 3 , 4 ], 5 ) // 1 2 3 4 5
// 该运算符主要用于函数调用
function push(array, ... items) {
array.push ( ...items);
}
// 扩展运算符后面还可以放置表达式
const arr = [
...(x > 0 ? ['a'] : [] ),
'b'
]
// 扩展运算符后面是个空数组,则不产生任何效果
[...[], 1] // [1]
// 例子1: 函数传参时传的是数组的形式
// ES5 的写法
function f (x, y, z) {
//
var args = [0, 1 , 2] ;
f.apply(null, args) ;
// ES6 的写法
function f(x, y, z) {
// ...
}
var args = [Q, 1, 2];
f (...args) ;
//例子2: 应用 Math .max 方法简化求出数组中的最大元素。
// ES5 的写法
Math .max.apply(null , (14 , 3 , 77])
// ES6 的写法
Math.max ( ...[14, 3, 77])
// 例子3: 通过 push 函数将一个数组添加到另一个数组的尾部
var arr1 = [0, 1 , 2] ;
var arr2 = [3 , 4, 5];
// ES5写法
Array.prototype.push.apply(arr1,arr2);
// ES6写法
arr1.push(...arr2)
// 合并数组
扩展运算符提供了数组合并的新写法。
// ESS
[1 , 2].concat(more)
// ES6
[1 , 2 , ...more]
var arr1 = [ ' a ','b'];
var arr2 = [ 'c' ];
var arr3 = [ 'd','e' ] ;
// ES5 的合并数纽
arr1.concat(arr2 , arr3) ; //[ 'a','b ','c','d','e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3] // [ 'a','b ','c','d','e' ]
// 与解构赋值结合
例子1
const [first, .. . rest] = [1 , 2 , 3 , 4 , 5];
first // 1
rest // [2 , 3 , 4 , 5]
例子2
const [first, ...reset] = ['123'];
first // "123"
rest // []
如果将扩展运算符用于数组赋值,则只能将其放在参数的最后一位,否则会报错。
const [ ... butLast, last]= [1 , 2 , 3 , 4 , 5] ; // 报错
const [first, .. . middle , last] = [1 , 2 , 3 , 4 , 5] ; // 报错
const [ butLast, ...last]= [1 , 2 , 3 , 4 , 5] ; // [1] , [2,3,4,5]
用于将两类对象转为真正数组:类似数组的对象和可遍历的的对象(包括ES6新增的数据结构Set和Map)
// ESS 的写法
var arrl = [].slice.call(arrayLike); // [ 'a','b','c' ]
// ES6 的写法
let arr2 = Array.from(arrayLike) ; // [ 'a','b','c' ]
// querySelectorAll 方法返回的是一个类似数组的对象,只有将这个对象转为真正的数组,才能使用forEach 方法。
// 只要是部署了 Iterator 接口的数据结构 Array.from 都能将其转为数组。
例子1:
Array.from ('hello') // ['h', 'e', 'l', 'l', 'o']
例子2:
let namesSet =new Set ([ 'a ','b'] )
Array.from(nameSet) // ['a', 'b']
Array from 还可以接受第 个参数,作用类似于数组的 map 方法,用来对每个元素进行 处理,将处理后的值放入返回的数组。
如果 map 函数里面用到了 this 关键字,还可以传入 Array.from 第三个参数,用来绑定this
Array.from(arrayLike, x => x * x)
//等同于
Array.from(arrayLike).map(x => x * x );
Array.from([1 , 2 , 3), (x) => x * x)
// [1 , 4 , 9]
Array from 的第 个参数指定了第二个参数运行的次数。这种特性可以 让该方法的用法变得非常灵活。
Array. from ( { length: 2 } , () => ’ j ack ’) //[’ jack ’,’jack ’]
Array.from()的另一个应用是,将宇符串转为数组,然后返回字符串的长度。因为它能正确处理各种 Unicode 字符,可以避免 JavaScript 将大于\uFFFF 的 Unicode 字符算作 2个字符 的bug
function countSymbols(string) { return Array.from(string) .length;}
用于将一组值转换为数组。
主要目的是弥补数组构造函数 Array ()的不足, 因为参数个数的不同会导致 Array()的行为有差异。
Array() 与 Array.of() 设置新数组的区别,
Array.of() 和 ES5方法 Array() 比较
Array.of(3 , 11 , 8) // [3 , 11 , 8]
Array.of(3) // [3]
Array.of(3).length // 1
Array() // []
Array(3) // [ , , , ] 这里输出的并不是预想中的结果
Array (3, 11 , 8) // [3 , 11 , 8]
// 参数个数只有1个时,实际上是指定数组的长度。
// 当参数个数不少于2个时,Array()才会返回由参数组成的新数组。
Array.of 方法可以用下面的代码模拟实现:
function ArrayOf() {
return [].slice.call(arguments);
}
数组实例的 copyWithin 方法会在当前数组内部将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法会修改当前数组。
Array.prototype.copyWithin(target, start= 0 , end= this.length)
它接受 个参数。
• target (必选〉 :从该位置开始替换数据。
start (可选):从该位置开始读取数据,默认为 。如果为负值,表示倒数。
• end (可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。
这3个参数都应该是数值,如果不是,会自动转为数值。
[1, 2 , 3 , 4, 5].copyWithin(0, 3) // [4, 5 , 3 , 4, 5 ]
数组实例的 find 方法用于找出第一个符合条件的数组成员。
它的参数是 个回调函数, 所有数组成员依次执行该回调函数 直到找出第1个返回值为 true 的成员,然后返回该成员
如果没有符合条件的成员,则返回 undefined
[1 , 4 , - 5 , 10] .find( (n) => n < 0) // -5
[1 , 5 , 10, 15].find(function (value , index , arr) {
return value > 9;
}) // 10
这两个方法都可以发现 NaN 弥补了数组的 indexOf 方法的不足。
findindex方法可以借Object.is方法做到。
[NaN].indexOf(NaN) // -1
[NaN].findlndex(y => Object.is(NaN, y)) // 0
fill 方法使用给定值填充 数组。
例子1:
['a','b','c'].fill(7) // [7,7,7]
例子2:
new Array(3).fill (7)
// [7 , 7 , 7]
fill 方法还可以接受第二个和第三个参数 用于指定填充 起始位置和结束位置
上面的代码表示, fill 方法从1号位开始向原数组填充7,到2号位之前结束。
['a','b','c'].fill(7 , 1 , 2)
//[ 'a', 7 , 'c']
['a','b','c'].fill(7 , 1 , 3)
// ["a", 7, 7]
['a','b','c'].fill(7 , 2 , 3)
// ["a", "b", 7]
可用 for ... of 循环遍历 唯一的区别在于keys()是对键名的遍历; values ()是对键值的遍历; entries()是对键值对的遍历。
for(let index of [1,2].keys()) {console.log(index)}
// 0 1
for(let index of [1,2].values()) {console.log(index)}
// 1 2
for(let index of [1,2].entries()) {console.log(index)}
// [0, 1] [1, 2]
Array prototype ncludes 方法返回一个布尔值,表示某个数组是否包含给定的值, 与字符串的 includes 方法类似。
ES2016引入该方法
[1,2,3].includes(2) // true
[1,2,3].include(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 方法有两个缺点 :
一是不够语义化,其含义是找到参数值的第一个出现位置,所以要比较是否不等于-1 ,表达起来不够直观;
二是,其内部使用严格相等运算符(===)进行 判断,会导致对 NaN 的误判。
[NaN].indexOf(NaN) // -1 即表示不存在
includes 使用的是不一样的判断算法:
[NaN].includes(NaN) // true
数组的空位指数组的某个位置没有任何值。比如,Array 构造函数返回的数组都是空位。
空位不是 undefined ,一个位直的值等于 undefined 依然是有值的 空位是没有任何 值的, in 运算符可以说明这一点
0 in [undefined, undefined, undefined] // true
0 in [, , , ] // false
第一个数组的0号位置是有值的 第二个数组的0号位置没有值。
由于空位的处理规则非常不统 ,所以建议避免出现空位。
ES5 对空位的处理很不一致 ,大多数情况下会忽略空位
ES6 则是明确将空位转为 undefined !!!
ES5 对空位的处理很不一致 ,大多数情况下会忽略空位
• forEach ()、 filter ()、 every ()和 some ()都会跳过空位。
• map ()会跳过空位,但会保留这个值。
• join ()和 toString ()会将空位视为 undefined ,而 undefined null 会被处
理成空字符串。
ES6的例子:空位处理
1.Array.from 方法会将数组的空位转为 undefined.
Array.from(['a', , 'b']) // ['a', undefined, 'b']
2.扩展运算符( ...)也会将空位转为 undefined.
[...['a', ,'b']] // ['a', undefined, 'b']
3. copyWithin() 会连空位一起复制。
[,'a','b', ,].copyWithin(2,0) // [ ,'a', ,'a']
4. fill() 会将空位视为正常的数组位置。
new Array(3).fill(3) // [3,3,3]
5. for ... of 循环也会遍历空位,转换为undefined
let arr = [ , 'a', ,] // [empty, "a", empty]
for(let i of arr) {
console.log(i) // undefined 'a' undefined
}
6. entries()、 keys()、 values() 、find()和 findindex() 会将空位处理成 undefined