Array常用方法
那该多好 Lv2

Arrar 构造器私有方法

of

Array.of()用于将参数依次转化为数组中的一项,然后返回新数组。而不管这个参数是数字还是其他

1
2
3
4
5
6
7
8
Array.of(8.0); //[8]
Array(8.0); //[empty * 8]

Array.of(8.0, 5); // [8,5]
Array.of(8.0,5); // [8,5]

Array.of('8'); // ["8"]
Array('8'); // ["8"]

from

Array.from() 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。然后返回一个新数组,原数组不变。

语法 : Array.from(arrayLike, callbackFn, thisArg)
参数:

  • arrayLike : 必选,想要转换成数组的类数组对象或可迭代的对象
  • callbankFn : 可选,回调函数,新生成的数组会经过该函数的加工再返回
  • thisArg : 可选,回调函数执行时this指向的值
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var arg = {0:'a',1:'b',2:'c', length:3};
    Array.from(arg, function(value){
    // value: 每项的键值
    return value; // 必须指定返回值,否则返回的新数组元素都为undefined
    },arg)
    // String
    Array.from('abc'); //["a","b","c"]
    //Set
    Array.from(new Set(['abc','def'])); //["abc ","def"]
    // Map
    Array.from(new Map([[1,'ab'],[2,'cd']])) // [[1,'ab'],[2,'cd']]

    不改变原数组的方法

    concat()

    concat() 方法用于多个数组的合并。它将新数组的成员,添加到原数组成员的后部,然后返回一个新数组,原数组不变。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ['hello'].concat(['world'])
    // ["hello", "world"]

    ['hello'].concat(['world'], ['!'])
    // ["hello", "world", "!"]

    [].concat({a: 1}, {b: 2})
    // [{ a: 1 }, { b: 2 }]

    [2].concat({a: 1})
    // [2, {a: 1}]

    join()

    join()方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串,并返回这个字符串。如果数组只有一个项目,那么将直接返回该项目而不使用分隔符;
    如果没有传参,分隔符默认为逗号。
    1
    2
    3
    var arr = ['Fire','Air','Water'];
    arr.join() // "Fire,Air,Water"
    arr.join('') // "FireAirWater"

    slice()

    slice()方法返回一个新数组,这一对象是一个由beginend决定的原数组的浅拷贝(包括begin,不包括end).原数组不会被改变
    1
    2
    3
    var arr = [1,2,3,4,5];
    arr.slice(2) // [3,4,5]
    arr.slice(2,4) //[3,4]

    toString()

    toString()返回一个字符串,表示指定的数组及元素
    1
    2
    [1,2,'a','b'].toString()
    // "1,2,a,b"

    indexOf()

    indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
    第一个参数为要查找的元素(必选), 第二个参数是开始查询的位置(可选)
    1
    2
    3
    var arr = ['a','b','c','d','c'];
    arr.indexOf('c') // 2
    arr.indexOf('c',3) // 4

改变原数组的方法

pop()

pop()方法从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。

1
2
3
var arr = [1,2,3,4,5]
console.log(arr.pop()) // 5
console.log(arr) // [1,2,3,4]
pop()原理
1
2
3
4
5
6
7
8
9
10
11
12
Array.prototype.pop = function(){
let arr = this,
len = arr.length;
if(len == 0){
return undefined;
}
len--;
let value = arr[len];
delete arr[len]
arr.length = len;
return value;
}

push()

push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。

1
2
3
var arr = [1,2,3,4,5]
console.log(arr.push(1)) // 6
console.log(arr) // [1,2,3,4,5,1]
push()原理
1
2
3
4
5
6
7
8
9
10
11
Array.prototype._push = function(...items){
let arr = this,
len = arr.length,
argLen = items.length;
for(let i=0;i<argLen;i++){
arr[len+i] = items[i]
}
let newLength = len+argLen;
arr.length = newLength;
return newLength
}

reverse()

reverse() 方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。

1
2
3
var arr = [1,2,3,4,5]
console.log(arr.reverse()) // [5,4,3,2,1]
console.log(arr) // [5,4,3,2,1]

splice()

splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。

1
2
3
4
5
6
7
8
9
var arr = [1,2,3,4,5]
console.log(arr.splice(0,1)) // [1] 返回被删除的元素
console.log(arr) // [2,3,4,5]

console.log(arr.splice(0,0,'add1')) //[] 空数组
console.log(arr) // ['add1',1,2,3,4,5]

console.log(arr.splice(0,1,'add2')) //[1] 返回被替换的元素
console.log(arr) // ['add2',2,3,4,5]

shift()

shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

1
2
3
var arr = [1,2,3,4,5]
console.log(arr.shift()) // 返回删除元素的值
console.log(arr) // [2,3,4,5]

unshift()

unshift() 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)。

1
2
3
var arr = [1,2,3]
console.log(arr.unshift(0,1,2)) // 6 返回该数组的新长度
console.log(arr) // [0,1,2,1,2,3]

sort()

sort() 方法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的,该方法改变原数组

1
2
3
4
5
6
7
8
9
10
11
// 默认排序
var arr = [8,16,50,6,100]
console.log(arr.sort()) // [100, 16, 50, 6, 8]

// 升序
var arr = [8,16,50,6,100]
console.log(arr.sort( function(a,b){ return a-b })) // [5, 8, 16, 50, 100]

// 降序
var arr = [8,16,50,6,100]
console.log(arr.sort( function(a,b){ return b-a })) // [100,50,16,8,5]

迭代方法

遍历类型的方法最后返回的都是一个新数组。并不会改变原有数组的值

forEach()

forEach()方法用于调用数组的每一个元素,并将元素传递给回调函数。

语法: array.forEach( callback(currentValue, index, array),thisArg)

  • callback: 为数组中每个元素执行的函数,该函数接收一至三个参数
    • currentValue : 必填,当前元素
    • index : 可选,当前元素的索引值
    • arr : 可选,当前元素所属的数组对象
    • thisArg : 可选,传递给函数的this值,如果参数为空,当前回调函数this指向window
      注意:
      1、forEach()对于空数组不会执行回调函数.
      2、for循环可以用continue跳过循环中的一个迭代,forEach()用continue会报错
      3、forEach()需要用return 跳过循环中的一个迭代,跳过之后会执行下一个迭代
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      var arr = [1,2,3];
      for(var i=0;i<arr.length;i++){
      if(arr[i] == 2){
      continue;
      }
      console.log(arr[i]) // 1 3
      }
      arr.forEach( function(value){
      if(value == 2){
      return;
      }
      console.log(value)// 1 3
      })
      forEach原理
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      Array.prototype._forEach = function(fn,thisArg){
      if(!thisArg){
      for(var i = 0; i<this.length; i++){
      fn(this[i],i,this)
      }
      }else{
      for(var i = 0; i<thisArg.length; i++){
      fn.call(thisArg,thisArg[i],i,thisArg)
      }
      }
      }

every()

every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试,返回一个布尔值。

语法 : arr.every(callback(value, index, array), thisArg)

1
[1,2,3].every( (value) => Number.isInteger(value) );  // true

可以将every()方法看做一个等价于逻辑与的数组

every 实现原理

为每个值执行回调,如果在任何时候返回false,则退出循环,整个方法返回false。如果循环终止都没有进入到if语句,说明每个条件都成立,则方法返回true

1
2
3
4
5
6
7
8
9
10
11
Array.prototype._every = function(callback){
var arr = this,
len = arr.length;
for(var i = 0; i<len;i++){
var value = arr[i];
if(!callback(value, i, arr)){
return false;
}
}
return true;
}

some()

some()方法every()刚好相反,即只要其中一个为true就会返回true。与every方法类似,可以将some方法看做一个等价的逻辑或数组

some 实现原理
1
2
3
4
5
6
7
8
9
10
11
Array.prototype._some = function(callback){
var arr = this,
len = arr.length;
for(var i = 0; I<len; i++){
var value = arr[i];
if(callback(value,i,arr)){
return true;
}
}
return false
}

filter()

filter() 方法创建一个新数组, filter会把传入的函数依次作用于每个元素,然后根据返回值是 true 还是false决定保留还是丢弃该元素。用于把Array的某些元素过滤掉,然后将剩下的元素放入新数组中返回。

语法: var newArr = arr.filter(callback(element, index, array),thisArg)
参数:

  • callback : 用来测试数组的每个元素的函数。返回 true 表示该元素通过测试,保留该元素,false 则不保留
    • element : 数组中正在处理的元素
    • index : 正在处理的元素在数组中的索引
    • array : 当前调用filter的数组本身
  • thisArg : 改变回调函数中this的指向
    filter()的原理
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Array.prototype._filter = function(callbackFn,thisArg){
    if(Object.prototype.toString.call(callbackFn) !== '[object Function]'){
    throw new TypeError(callbackFn + 'is not a function')
    }
    var arr = this,
    len = arr.length,
    newArr=[];
    for(var i = 0; i<len; i++){
    if(callbackFn(arr[i],i,arr)){
    newArr.push(arr[i])
    }
    }
    return newArr;
    }

map()

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

语法: var newArr = array.map( function(currentValue, index, arr),thisArg)
参数同forEach()

map()原理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Array.prototype._map = function(callbackFn, thisArg){
if(this === null || this === undefined){
throw new TypeError("Cannot read property '_map' of null")
}
if(Object.prototype.toString.call(callbackFn)!= '[object Function]'){
throw new TypeError(callbackFn+'is not a function')
}
let arr = this,
len = arr.length,
newArr = new Array(len);
for(let i = 0; i<len; i++){
if(i in arr){
let kValue = arr[i];
let mappedValue = callbackFn.call(thisArg,kValue,i,arr)
newArr[i] = mappedValue;
}
}
return newArr;
}
var a = [1, 2, 3]
var b = a._map(function (item, i, arr) {
return item * 2;
})
console.log(b); //[2,4,6]

reduce()

reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

语法 : var result = arr.reduce(callback(acc, cur, index, array), initValue)
参数:

  • callback : 执行数组中每个值得函数,包含四个参数
    • acc : 必选,initvalue提供的初始值,或者是 上一次电用的返回值(可以理解为收集箱,收集每次调用后的返回值)
    • cur : 必选,数组中当前被处理的元素
    • index : 可选,当前元素的索引
    • array : 可选,调用reduce()的数组
  • initValue : 可选,作为第一次调用时 callback的第一个参数
reduce()原理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Array.prototype._reduce = function(callbackFn, initValue){
// 异常处理,和map类似
if(this === null || this === undefined){
throw new TypeError("Cannot read property '_reduce' of null")
}
// 处理回调类型异常
if(Object.prototype.toString.call(callbackFn)!= '[object Function]'){
throw new TypeError(callbackFn+'is not a function')
}
let arr = this,
// 判断是否传入初始值,如果没有,初始值为当前数组的第一位,否则以传入的值当做初始值
acc = arguments.length === 1 ? arr[0] : initValue,
// 若没有传入初始值,数组第一位为初始值,所以遍历要从第二位开始,也就是下标为1的位置
startIdx = arguments.length === 1 ? 1 : 0;
for(var i = startIdx; i<arr.length; i++){
acc = callbackFn(acc,arr[i],i,arr);
}
return acc
}
 评论