JS笔记《Array对象》

87 阅读8分钟

构造函数

  • Array是JS的原生对象,同时也是一个构造函数,可以用它生成新的数组。
var arr = new Array(2);
arr.length  // 2
arr  // [空属性 × 2]

var arr = Array(2);
//等同于
var arr = new Array(2); 
  • 构造函数有个缺陷是不同的参数个数会导致不一致的行为,建议使用字面量的方式创建数组,详见《数据类型—数组》一章。
new Array()      // []  无参数时返回空数组
new Array(2)     // [空属性 × 2] 创建指定长度的空数组
new Array(3.2)   // 报错
new Array('abc') // ['abc'] 单个非数值(比如字符串、布尔值、对象等)作为参数,则返回包含该参数的新数组
new Array(1,2,)  // [1, 2]  多参数时,所有参数都是返回的新数组的成员

静态方法

Array.isArray()

  • 返回boolean值,判断变量是否是数组。
var arr = [1, 2, 3];
Array.isArray(arr);  // true

实例方法

改变原数组

push()

  • 在数组末端添加一个或多个元素,并返回添加后的数组长度此方法会改变原数组
var arr = [];
arr.push(1, 'a', true)  // 3
arr   // [1, a, true]

pop()

  • 删除数组的最后一个元素,并返回该元素此方法会改变原数组
var arr = [1,2];
arr.pop()   // 2
arr // [1]

[].pop()  // undefined 不会报错

shift()

  • 删除数组的第一个元素,并返回该元素此方法会改变原数组
var arr = ['a', 'b', 'c'];
a.shift()   // 'a'
arr // ['b', 'c']

unshift()

  • 在数组的第一个位置添加元素,可添加一个或多个。并返回添加后的数组长度此方法会改变原数组
var arr = [1,2,3]
arr.unshift(-1, 0);
arr  // [-1, 0, 1, 2, 3]

reverse()

  • 颠倒数组元素的排列,返回改变后的数组。此方法会改变原数组
var a = ['a', 'b', 'c'];

a.reverse() // ["c", "b", "a"]
a           // ["c", "b", "a"]

splice(start, end, addEl1, addEl2...)

  • 删除原数组的一部分成员,并可以在删除位置添加新的成员。返回被删除的元素。此方法会改变原数组
  • start: 起始索引位置,会包含在删除内。
  • end: 被删除的元素个数,从起始位置算起。
  • addEl:要添加的元素,可以是多个。
var arr = ['a', 'b', 'c', 'd', 'e'];
arr.splice(1, 2, 'bb', 'cc');  // ['b', 'c']
arr  // ['a', 'bb', 'cc', 'd', 'e']

// 如果第一个参数为负数表示从倒数第几个开始
arr.splice(-4, 2, 'a', 'b');    // ['bb', 'cc']  
arr  // ['a', 'a', 'b', 'd', 'e']

// 如果只有第一个参数等同于将原数组在指定位置拆分成两个数组
arr.splice(2);  // ['b', 'd', 'e']
arr  // ['a', 'a']

sort()

  • 对数组成员进行排序,默认是按照字典顺序排序。此方法会改变原数组
['d', 'c', 'b', 'a'].sort()  // ['a', 'b', 'c', 'd']
[4, 3, 2, 1].sort()    // [1, 2, 3, 4]
[11, 101].sort()       // [101, 11]
[10111, 1101, 111].sort() // [10111, 1101, 111]

是按照字典排序而不是按照大小。数值会被先转为字符串然后再按照字典比较。

  • 自定义排序方式:传入一个函数作为参数,函数接受两个参数(a, b),表示进行比较的两个数组成员。
[
  { name: "张三", age: 30 },
  { name: "李四", age: 24 },
  { name: "王五", age: 28 }
].sort(function (a, b) {
  return a.age - b.age; 
  
    // 正数,b在前  
    // 负数,a在前  
    // 0,不变  
    // return a - b;   // 升序 a-b > 0 b在前,即升序; a-b < 0 a在前,还是升序;  
    // return b - a;   // 降序 b-a > 0 b在前,即降序; b-a < 0 a在前,还是降序。
})

// [
//   { name: "李四", age: 24 },
//   { name: "王五", age: 28  },
//   { name: "张三", age: 30 }
// ]

slice(start, end)

  • 提取目标数组的一部分,返回一个新数组
  • start:起始索引位置,会包含在提取内。
  • end:终止索引位置,不包含在提取内。如果省略则一直提取到数组的最后一位。
var arr = ['a', 'b', 'c', 'd', 'e'];
arr.slice(1, 3);   //  ['b', 'c']
arr.slice(1);      //  ['b', 'c', 'd', 'e']
arr.slice();       //  ['a', 'b', 'c', 'd', 'e'] 如果有对象,则相当于原数组的浅拷贝

arr.slice(-2, -1); //  ['d']  负数则表示倒数计算的位置,从倒数第二开始提取到倒数第一

类数组转为数组

  • arguments、DOM对象等都是类数组。
Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 })  // ['a', 'b']

join()

  • 以指定参数作为分隔符,将数组成员连接为一个字符串并返回。
var arr = ['a', 'b', 'c'];
arr.join('-');  // 'a-b-c'

arr.join()  // 'a,b,c' 未传参数默认以逗号分隔

concat()

  • 用于多个数组的合并,将传入的数组添加到原数组的末尾然后返回一个新数组
var arr = ['a', 'b', 'c'];
arr.concat('abc'); // ['a', 'b', 'c', 'abc']

// 也接受其他类型的值作为参数,添加到目标数组尾部
var arr = [1, 2, 3];
arr.concat(4, 5, 6);  // [1, 2, 3, 4, 5, 6]

// 如果数组中有对象,则相当于浅拷贝
var obj = { a: 1 };
var oldArray = [obj];

var newArray = oldArray.concat();

obj.a = 2;
newArray[0].a  // 2 

map()

  • 循环!将数组的所有成员依次传入参数函数,然后把每次执行的结果组成一个新数组并返回。
var numbers = [1, 2, 3];
var newNumbers = numbers.map(function (n) {
  return n + 1;
});

newNumbers // [2, 3, 4]
number // [1, 2, 3] 原数组没变化

// 3个参数
numbers.map(function(item, index, array){
    console.log(item);  // 1 2 3
    console.log(index)  // 0 1 2
    console.log(array)  // [1, 2, 3] [1, 2, 3] [1, 2, 3]
})

forEach()

  • 循环!对数组的所有成员依次执行参数函数,但是此方法不返回值,只用来遍历、操作数据
var numbers = [1, 2, 3];
numbers.forEach(function(item, index, array){
    console.log(item);  // 1 2 3
    console.log(index)  // 0 1 2
    console.log(array)  // [1, 2, 3] [1, 2, 3] [1, 2, 3]
})

filter()

  • 循环!用于过滤数组成员,满足条件的成员组成一个新数组返回。
[1, 2, 3, 4, 5].filter(function (item) {
  return (item > 3);
})
// [4, 5]

// 返回偶数位置的成员组成的新数组
[1, 2, 3, 4, 5].filter(function (elem, index, arr) {
  return index % 2 === 0;
});
// [1, 3, 5]

some()

  • 判断数组成员是否符合某种条件,只要有一个成员的返回值是true就返回true
[1,2,3,4,5].some(function(item){
    return item > 1;  // 是否存在值 > 1的成员
})
// true

every()

  • 判断数组成员是否符合某种条件,必须所有成员的返回值都是true才返回true
[1,2,3,4,5].every(function(item){
    return item > 2;   // 是否所有成员值都 > 2
})
// false 

reduce()

  • 循环!依次处理数组的每个成员,最终累计为一个值返回。reduce的第一个参数是一个函数,数组每个成员都会依次执行这个函数。如果数组有n个成员,这个函数就会执行n-1次。
var arr = [1,2,3,4,5];
arr.reduce(function(prev, curr){
    return prev + curr;
})
// 15 
// 第一次执行:prev是arr[0],curr是arr[1]
// 第二次执行:prev是上一轮累加的返回值(3),curr是arr[2]
// 第三次执行:prev是上一轮累加的返回值(6),curr是arr[3]
// 第三次执行:prev是上一轮累加的返回值(10),curr是arr[4],已到达数组末尾,方法执行完成。返回这一轮的累加值(15)

// 4个参数(prev、curr必填)
arr.reduce(function(prev, curr, index, array){
    console.log(prev);   // 1 3 6 10 15  
    // 累加值  默认为数组的第一个成员;以后每次执行时,都是上一轮的返回值。
    
    console.log(curr);   // 2 3 4 5 
    // 当前变量。第一次执行时,默认为数组的第二个成员;以后每次执行时,都是下一个成员。
    
    console.log(index);  // 1 2 3 4
    // 当前位置。表示第二个参数(curr)的索引位置,默认为`1`。
    
    console.log(array); // [1,2,3,4,5];
    // 原数组
    
    return prev + curr;
})
  • 如果要对累加变量指定初始值可以设置reduce的第二个参数。如果设置了第二个参数,则curr默认从数组第一个成员开始,也就是n个成员的数组,当前函数会执行n次。建议使用
[1, 2, 3, 4, 5].reduce(function (a, b) {
  return a + b;
}, 10);
// 25
// 

reduce应用

// 找到最长的字符串
var arr = ['a', 'bb', 'ccc', 'dddd', 'e']
var str = arr.reduce(function(prev, curr){
  return prev.length > curr.length ? prev : curr;
}, '')

// 找到最大的数值
var arr2 = [1, 4, 643, 23, 64]
var max = arr2.reduce(function(prev, curr){
  return prev > curr ? prev : curr;
}, 0);

reduceRight()

  • reduce功能一致,区别是reduce从左向右依次执行,而reduceRight是从右向左执行。
// 从左向右
[1, 2, 3].reduce(function(prev, curr){
    return prev - curr;
}, 0) 
// -6:  0-1-2-3  
// 如果不设置初始值则是-4: 1-2-3

// 从右向左
[1, 2, 3].reduceRight(function(prev, curr){
    return prev - curr;
}, 0)
// -6: 0-3-2-1
// 如果不设置初始值则是0: 3-2-1

indexOf()

  • 返回给定元素在数组中第一次出现的索引,如果没有出现则返回-1
var arr = ['a', 'bb', 'ccc', 'dddd', 'e']
arr.indexOf('bb')  // 1
arr.indexOf('c')   // -1

// 第二个参数表示搜索的开始位置
arr.indexOf('ccc', 2)   // 2  
arr.indexOf('ccc', 3)   // -1

不能用来搜索NaN的位置,因为内部使用===来判断,NaN不等于任何值,包括自身。

lastIndexOf()

  • 返回给定元素在数组中最后一次出现的位置,如果没有出现则返回-1
var arr = ['a', 'b', 'c', 'd', 'a']
arr.lastIndexOf('a')  // 4
arr.indexOf('a')    // 0

valueOf()

  • valueOf()是所有对象都有的一个方法,表示对该对象求值。数组的valueOf()返回数组本身。
var arr = [1, 2, 3];
arr.valueOf()  // [1, 2, 3]

toString()

  • toString()也是对象的通用方法,数组的toString()返回数组的字符串形式。
var arr = [1, 2, 3];
arr.toString()   // '1, 2, 3'
[].toString()    // ''