Array对象

433 阅读4分钟

总结

  • 改变原数组的方法

    push、pop、shift、unshift、reverse、splice、sort

  • 不改变原数组

    join(),slice(),map(),filter

一、静态方法

  • Array.isArray()

返回Boolean可以识别数组, 弥补typeof

var arr = [1, 2, 3];

typeof arr // "object"
Array.isArray(arr) // true

二、实例方法

  1. ValueOf(), toString()

    valueOf方法是一个所有对象都拥有的方法,表示对该对象求值。不同对象的valueOf方法不尽一致,数组的valueOf方法返回数组本身。

    var arr = [1, 2, 3];
    arr.toString() // "1,2,3"
    
    var arr = [1, 2, 3, [4, 5, 6]];
    arr.toString() // "1,2,3,4,5,6"
    
  2. push(),pop(),shift(),unshift(),reverse(),splice(),sort() (改变原数组,经常用不做多余赘述)
  3. join(),slice(),map(),filter方法用于过滤数组成员,满足条件的成员组成一个新数组返回(不改变原数组)
    var a = [1, 2, 3, 4];
    
    a.join(' ') // '1 2 3 4'
    a.join(' | ') // "1 | 2 | 3 | 4"
    a.join() // "1,2,3,4"
    a // [1,2,3,4]
    
    • 注意

    如果数组成员是undefined或null或空位,会被转换为空字符串

    [undefined, null].join('#')
    // '#'
    
    ['a',, 'b'].join('-')
    // 'a--b'
    
    • 通过call方法,这个方法可以用于字符串或类似数组的对象
    Array.prototype.join.call('hello', '-')
    // "h-e-l-l-o"
    
    var obj = { 0: 'a', 1: 'b', length: 2 };
    Array.prototype.join.call(obj, '-')
    // 'a-b'
    
  4. concact() (原数组不变)

    concat方法用于多个数组的合并。它将新数组的成员,添加到原数组成员的后部,然后返回一个新数组,原数组不变。

    ['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}]
    [1, 2, 3].concat(4, 5, 6)
    // [1, 2, 3, 4, 5, 6]
    
    如果数组成员包括对象,concat方法返回当前数组的一个浅拷贝。所谓“浅拷贝”,指的是新数组拷贝的是对象的引用。
    var obj = { a: 1 };
    var oldArray = [obj];
    
    var newArray = oldArray.concat();
    
    obj.a = 2;
    newArray[0].a // 2
    

    上面代码中,原数组包含一个对象,concat方法生成的新数组包含这个对象的引用。所以,改变原对象以后,新数组跟着改变。

  5. slice() slice()方法用于提取目标数组的一部分,返回一个新数组,原数组不变

  6. map

map方法将数组的所有成员依次传入参数函数,然后把每一次的执行结果组成一个新的数组返回

var numbers = [1, 2, 3];

numbers.map(function (n) {
  return n + 1;
});
// [2, 3, 4]

numbers
// [1, 2, 3]

map方法接受一个函数作为参数,该函数调用时,map方法相它传入三个参数:当前成员、当前位置和数组本身

[1, 2, 3].map(function(elem, index, arr) {
return elem * index;
});
// [0, 2, 6]

map方法还可以接受第二个参数,用来绑定回调函数内部的this变量。

var arr = ['a', 'b', 'c'];

[1, 2].map(function (e) {
  return this[e];
}, arr)
// ['b', 'c']

如果数组有空位,map方法的回调函数在这个位置不会执行,会跳过数组的空位。

var f = function (n) { return 'a' };

[1, undefined, 2].map(f) // ["a", "a", "a"]
[1, null, 2].map(f) // ["a", "a", "a"]
[1, , 2].map(f) // ["a", , "a"]

上面代码中,map方法不会跳过undefined和null,但是会跳过空位

  1. forEach()

forEach方法与map方法很相似,也是对数组的所有成员依次执行参数函数。但是,forEach方法不返回值,只用来操作数据。这就是说,如果数组遍历的目的是为了得到返回值,那么使用map方法,否则使用forEach方法。 forEach的用法与map方法一致,参数是一个函数,该函数同样接受三个参数:当前值、当前位置、整个数组。

  • forEach方法也可以接受第二个参数,绑定参数函数的this变量。
var out = [];

[1, 2, 3].forEach(function(elem) {
  this.push(elem * elem);
}, out);

out // [1, 4, 9]

上面代码中,空数组out是forEach方法的第二个参数,结果,回调函数内部的this关键字就指向out

  • 注意,forEach方法无法中断执行,总是会将所有成员遍历完。如果希望符合某种条件时,就中断遍历,要使用for循环。
var arr = [1, 2, 3];

for (var i = 0; i < arr.length; i++) {
  if (arr[i] === 2) break;
  console.log(arr[i]);
}
// 1

forEach方法也会跳过数组的空位。forEach方法不会跳过undefined和null,但会跳过空位。

链式操作

上面这些数组方法之中,有不少返回的还是数组,所以可以链式使用。

var users = [
  {name: 'tom', email: 'tom@example.com'},
  {name: 'peter', email: 'peter@example.com'}
];

users
.map(function (user) {
  return user.email;
})
.filter(function (email) {
  return /^t/.test(email);
})
.forEach(function (email) {
  console.log(email);
});