es6 - 数组的扩展

224 阅读5分钟
  1. arguments
  2. 数组的扩展 - rest参数(形式为...变量名)
  3. 数组的扩展 - 箭头函数
  4. 数组的扩展 - 扩展运算符(三个点(...))
  5. 数组的扩展 - Array.from()
  6. 数组的扩展 - Array.of()
  7. 数组的扩展 - copyWithin()
  8. 数组的扩展 - find(), findIndex()
  9. 数组的扩展 - fill()
  10. 数组的扩展 - includes()
  11. 数组的扩展 - flat()
  12. 数组的扩展 - at()

1. arguments

function pay() {
  if (arguments.length === 0) {
    console.log('手机支付...')
  } else if (arguments.length === 1) {
    console.log(`现金结账:收您${arguments[0]}元`)
  } else {
    console.log(`刷卡支付:从您的卡号${arguments[0]}扣款成功`)
  }
}
pay() //手机支付...
pay(100)  //现金结账:收您100元
pay("6008 1234", "123456")  //刷卡支付:从您的卡号6008 1234扣款成功

2. 数组的扩展 - rest参数

  • ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
function add(...values) {
  let sum = 0;
  for (var val of values) {
    sum += val;
  }
  return sum;
}
console.log(add(2, 5, 3)) //10
  • 利用rest参数,改写数组push方法的示例:
function push(array, ...items) {
  items.forEach(item => {
    array.push(item)
  })
  console.log(items)	//[1, 2, 3]
}
var a = []
push(a, 1, 2, 3)

3. 箭头函数

var f = v => v
// 等同于
var f = function(v) {
	return v
}

var f = () => 5
// 等同于
var f = function() {
	return 5
}

let getTempItem = function(id) {
  ({
    id: id,
    name: "Temp"
  })
}
// 等同于
let getTempItem = id => ({
  id: id,
  name: "Temp"
})

4. 数组的扩展 - 扩展运算符(三个点(...))

  • 4.1 替代函数的apply()方法
function f(x, y, z) {
  console.log(x, y, z)
}
var args1 = [0, 1, 2]
// es5的写法
console.log(f.apply(null, args))
// es6的写法
console.log(f(...args))

// ES5 的写法
console.log(Math.max.apply(null, [14, 3, 77])) //77
// ES6 的写法
console.log(Math.max(...[14, 3, 77]))
// 等同于
console.log(Math.max(14, 3, 77))
  • 4.2 push()函数
// ES5 的写法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1, arr2)
console.log(arr1) // [0, 1, 2, 3, 4, 5]

// ES6 的写法
arr1.push(...arr2)
console.log(arr1)

// ES5
console.log(new(Date.bind.apply(Date, [null, 2015, 1, 1])))
// ES6
console.log(new Date(...[2015, 1, 1]))
  • 4.3 扩展运算符的应用
// 4.3.1 复制数组
const a1 = [1, 2]
// 写法一
const a2 = [...a1]
//写法二
const [...a2] = a1

// 4.3.2 合并数组
const arr1 = ['a', 'b']
const arr2 = ['c']
const arr3 = ['d', 'e']
console.log(arr1.concat(arr2, arr3))	//['a', 'b', 'c', 'd', 'e']
console.log([...arr1, ...arr2, ...arr3])

5. 数组的扩展 - Array.from()

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

console.log(Array.from([1, 2, 3], x => x * x)) //[1, 4, 9]
// 将数组中布尔值为false的成员转为0
console.log(Array.from([1, , 2, , 3], n => n || 0)) //[1, 0, 2, 0, 3]

6. 数组的扩展 - Array.of()

Array.of()方法用于将一组值,转换为数组。

console.log(Array.of(3,11,8)) //[3, 11, 8]
console.log(Array.of(3))  //[3]
console.log(Array.of(3).length) //1

7. 数组的扩展 - copyWithin()

数组实例的copyWithin()方法,在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。 它接受三个参数。

  • target(必需):从该位置开始替换数据。如果为负值,表示倒数。
  • start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。
  • end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。

这三个参数都应该是数值,如果不是,会自动转为数值。

console.log([1,2,3,4,5].copyWithin(0,3))	//4, 5, 3, 4, 5

8. 数组的扩展 - find(), findIndex()

数组实例的find()方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined

数组实例的findIndex()方法的用法与find()方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1

console.log([1, 4, -5, 10].find(n => n < 0)) //-5
console.log([1, 5, 10, 15].find((value, index, arr) => value > 0)) //1
console.log([1, 5, 10, 15].findIndex((value, index, arr) => value > 9)) //2

function f(v) {
  return v > this.age
}
let person = { name: 'John', age: 20 }
console.log([10, 12, 26, 15].find(f, person)) //26

// 这两个方法都可以发现NaN,弥补了数组的indexOf()方法的不足。
console.log([NaN].indexOf(NaN)) //-1
console.log([NaN].findIndex(y=>Object.is(NaN,y))) //NaN
// 上面代码中,indexOf()方法无法识别数组的NaN成员,但是findIndex()方法可以借助Object.is()方法做到。

9. 数组的扩展 - fill()

fill方法使用给定值,填充一个数组。

console.log(['a','b','c'].fill(7))  //[7, 7, 7]
console.log(new Array(3).fill(7)) //[7, 7, 7]
// fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。
console.log(['a', 'b', 'c'].fill(7, 1, 2))  //[a,7,c]

10. 数组的扩展 - includes()

方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似

console.log([1, 2, 3].includes(2))  //true
[NaN].indexOf(NaN)  // -1
[NaN].includes(NaN)  // true

indexOf方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判。

11. 数组的扩展 - flat(),flatMap()

数组的成员有时还是数组,Array.prototype.flat()用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响。

flat()默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1。

console.log([1,2,[3,4]].flat()) // [1, 2, 3, 4]

// `flat()`的参数为2,表示要“拉平”两层的嵌套数组。
console.log(([1,2,[3,[4,5]]]).flat(2))  // [1, 2, 3, 4, 5]

// 如果不管有多少层嵌套,都要转成一维数组,可以用`Infinity`关键字作为参数
console.log([1,[2,[3]]].flat(Infinity)) // [1, 2, 3]

12. 数组的扩展 - at()

接受一个整数作为参数,返回对应位置的成员,并支持负索引。这个方法不仅可用于数组,也可用于字符串和类型数组(TypedArray)。

const arr = [5, 12, 8, 130, 44]
console.log(arr.at(2))  //8
console.log(arr.at(-2));  //130