简介

数组是编程语言中应用最广泛的存储结构,在 ECMAScript 中数组是非常常用的引用类型。很有必要将数组的内容捋一遍,加深印象。

数组属性

  • constructor 表示引用数组对象的构造函数
  • length 表示数组的长度,即其中元素的个数。注意在js中length属性是可变的,当设置一个数组的length值变大时,数组内容不会改变,仅仅是length更改,但当length设置小于实际数组的时候,则原数组中索引大于或等于length的元素的值全部被丢失。
  • prototype属性是object共有的,可以通过增加属性和方法扩展数组定义。

基本操作

一、创建方法

创建一个空数组

1
2
3
4
5
var arr = [];
var arr = new Array(); // 创建一个空数组
````

#### 创建一个指定长度的数组

var arr = new Array(size) // size 表示数组的长度

1
#### 创建一个指定元素的数组

var arr = new Array(1,2,3,4,5) //创建数组并赋值 [1,2,3,4,5]

1
2
3
4
5
6
7
8
9
<!-- more -->

### 二、检测方法



#### 1、利用 instanceof 操作符

instanceof操作符是检测对象的原型链是否指向构造函数的prototype对象,

var arr =[1,2,3]; console.log(arr instanceof Array) // true

1
#### 2、通过对象自身的 constructor 属性

var arr =[1,2,3]; console.log(arr.constructor === Array) // true

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
**跨frame实例化对象带来的问题**

`constructor` 和 `instanceof` 貌似很好的两个检测数组的方法,但实际上还是有些漏洞的,当你在多个frame中回来跳的时候,这两种方法就惨了。

由于每一个frame都有自己的一套执行环境,跨frame实例化的对象彼此并不共享原型链,通过 `instanceof` 操作符和 `constructor` 属性检测的方法自然会失败。

那么第三种方法就比较好了,如下

#### 3、对象原生toString检测

`Object.prototype.toString` 的行为:首先,取得对象的一个内部属性 [[Class]],然后依据这个属性,返回一个类似于"[object Array]"的字符串作为结果(看过ECMA标准的应该都知道,[[]]用来表示语言内部用到的、外部不可直接访问的属性,称为“内部属性”)。利用这 个方法,再配合call,我们可以取得任何对象的内部属性[[Class]],然后把类型检测转化为字符串比较,以达到我们的目的。

var arr =[1,2,3]; console.log(Object.prototype.toString.call(arr) === ‘[object Array]‘); //true

1
可以将判断方法封装一个函数

function isArray(obj) { return Object.prototype.toString.call(obj) === ‘[object Array]‘; } var arr =[1,2,3]; console.log(isArray(arr)); // true

1
2
3
4
5
#### 4、ECMAScript 5的isArray函数

为了让数组检测更方便,ECMAScript5新增了Array.isArray()方法。该方法的目的是最终确定某个值到底是不是数组,而不管它在哪个全局环境中创建的。

**注:此方法在IE8之前的版本是不支持的**

var arr =[1,2,3]; console.log(Array.isArray(arr)); // true

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
## ECM3方法

### 1、Array.prototype.join()

`join()` 方法将数组(或一个类数组对象)的所有元素连接到一个字符串中。此方法不会改变原数组。也就是说所有的数组元素被转换成字符串,再用一个分隔符将这些字符串连接起来。如果元素是undefined 或者null, 则会转化成空字符串。

`arr.join(separator)` 参数 `separator`

- 指定一个字符串来分隔数组的每个元素
- 如果省略(),数组元素用逗号分隔。默认为 ","
- 如果separator是空字符串(""),则所有元素之间都没有任何字符

var arr = [‘a1’, ‘b2’, ‘c3’]; var myArr1 = arr.join(); var myArr2 = arr.join(‘, ‘); var myArr3 = arr.join(’ + ‘); var myArr4 = arr.join(“);

console.log(myArr1); // a1,b2,c3 console.log(myArr2); // a1, b2, c3 console.log(myArr3); // a1 + b2 + c3 console.log(myArr4); // a1b2c3

1
2
3
4
5
### 2、Array.prototype.push()

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

**添加元素:**可以添加新的元素到数组

// 添加元素 var letter = [“a”, “b”]; var total = letter.push(“c”,“d”); console.log(total); // 4 console.log(letter); // [“a”, “b”, “c”, “d”]

1
**合并数组**:可以使用 apply() 添加第二个数组的所有元素

// 合并数组 var arr1 = [1, 2]; var arr2 = [“a”, “b”];

// 将第二个数组融合进第一个数组 // 相当于 arr1.push(‘a’, ‘b’); Array.prototype.push.apply(arr1, arr2);

console.log(arr1); // [1, 2, “a”, “b”]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
### 3、Array.prototype.pop()

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

如果你在一个空数组上调用 pop(),它返回  undefined。


### 4、Array.prototype.unshift()

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

var arr = [1, 2];

arr.unshift(0); //arr is [0, 1, 2]

arr.unshift(-2, -1); // = 5 //arr is [-2, -1, 0, 1, 2]

arr.unshift( [-3] ); //arr is [[-3], -2, -1, 0, 1, 2]

1
2
3
### 5、Array.prototype.shift()

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

let myFish = [‘angel’, ‘clown’, ‘mandarin’, ‘surgeon’];

console.log(‘调用 shift 之前: ‘ + myFish); // “调用 shift 之前: angel,clown,mandarin,surgeon”

var shifted = myFish.shift();

console.log(‘调用 shift 之后: ‘ + myFish); // “调用 shift 之后: clown,mandarin,surgeon”

console.log(‘被删除的元素: ‘ + shifted); // “被删除的元素: angel”

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
### 6、Array.prototype.sort()

sort(compareFunction) 方法在适当的位置对数组的元素进行排序,并返回数组。

sort 排序不一定是稳定的。默认排序顺序是根据字符串Unicode码点。

一般我们给sort带入个比较函数来替代原来的默认的比较方法,比较方法接受两个参数:

- 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
- 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。
- 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。
- compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。

var numbers = [4, 2, 5, 1, 3]; numbers.sort(function(a, b) { return a - b; }); console.log(numbers); // [1, 2, 3, 4, 5]

1
2
3
4
5
### 7、Array.prototype.reverse()

reverse() 方法颠倒数组中元素的位置。第一个元素会成为最后一个,最后一个会成为第一个。

下例将会创建一个数组 myArray,其包含三个元素,然后颠倒该数组。

var myArray = [‘a’, ‘b’, ‘c’]; myArray.reverse(); console.log(myArray); // [‘c’, ‘b’, ‘a’]

1
2
3
### 8、Array.prototype.concat()

concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。

var arr1 = [“a”, “b”, “c”]; var arr2 = [“d”, “e”, “f”];

var arr3 = arr1.concat(arr2);

console.log(arr3); // 返回结果是一个新数组 // [ “a”, “b”, “c”, “d”, “e”, “f” ]

// 原数组没有改变 console.log(arr1); // [“a”, “b”, “c”] console.log(arr2); // [“d”, “e”, “f”]

1
2
3
4
5
6
7
### 9、Array.prototype.slice()

`slice(start, end)` 方法将数组的一部分浅拷贝, 返回到从开始到结束(不包括结束)选择的新数组对象。原始数组不会被修改。

- slice()
- slice(start)
- slice(start,end)

var arr = [‘one’,‘two’,‘three’,‘four’];

//如果不传参数,表示从数组0开始到到end(包含end) var newArr1 = arr.slice(); console.log(newArr1) // [“one”, “two”, “three”, “four”]

//如果省略 end,则表示从start开始到end(包含end) var newArr2 = arr.slice(1); console.log(newArr2) // [“two”, “three”, “four”]

//如果传人star、end,则表示从start到end不包含end var newArr3 = arr.slice(1, 3); console.log(newArr3) // [“two”, “three”]

console.log(arr) // [“one”, “two”, “three”, “four”]

1
2
3
4
5
6
7
8
9
### 10、Array.prototype.splice()

splice() 方法通过删除现有元素和/或添加新元素来更改数组的内容。

**注意:splice 方法直接更改原数组内容**

- array.splice(start)
- array.splice(start, deleteCount)
- array.splice(start, deleteCount, item1, item2, ...)

var myFish = [“angel”, “clown”, “mandarin”, “surgeon”];

//从第 2 位开始删除 0 个元素,插入 “drum” var removed = myFish.splice(2, 0, “drum”); console.log(myFish); //运算后的 myFish:[“angel”, “clown”, “drum”, “mandarin”, “surgeon”] //被删除元素数组:[],没有元素被删除

//从第 3 位开始删除 1 个元素 removed = myFish.splice(3, 1); //运算后的myFish:[“angel”, “clown”, “drum”, “surgeon”] //被删除元素数组:[“mandarin”]

//从第 2 位开始删除 1 个元素,然后插入 “trumpet” removed = myFish.splice(2, 1, “trumpet”); //运算后的myFish: [“angel”, “clown”, “trumpet”, “surgeon”] //被删除元素数组:[“drum”]

//从第 0 位开始删除 2 个元素,然后插入 “parrot”, “anemone” 和 “blue” removed = myFish.splice(0, 2, “parrot”, “anemone”, “blue”); //运算后的myFish:[“parrot”, “anemone”, “blue”, “trumpet”, “surgeon”] //被删除元素的数组:[“angel”, “clown”]

//从第 3 位开始删除 2 个元素 removed = myFish.splice(3, Number.MAX_VALUE); //运算后的myFish: [“parrot”, “anemone”, “blue”] //被删除元素的数组:[“trumpet”, “surgeon”]

1
2
3
4
5
6
7
--------

## ECM5方法

### 1、Array.prototype.indexOf()

indexOf()方法返回在数组中可以找到给定元素的第一个索引,如果不存在,则返回-1。

var a = [2, 6, 9, 6];

a.indexOf(2); // 0 a.indexOf(7); // -1 不存在 a.indexOf(6); // 1 返回指定元素的第一个索引值

1
**找出指定元素出现的所有位置**

// 找出 a 在 array 里的所有位置 var str = ‘a’; var array = [‘a’, ‘b’, ‘a’, ‘c’, ‘a’, ’d’];

var indices = []; var idx = array.indexOf(str);

while (idx != -1) { indices.push(idx); idx = array.indexOf(str, idx + 1); }

console.log(indices); // [0, 2, 4]

1
2
3
### 2、Array.prototype.lastIndexOf()

lastIndexOf() 方法返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始。

arr.lastIndexOf(searchElement[, fromIndex = arr.length - 1])

1
**定位数组中的值:**

var array = [2, 5, 9, 2]; var index = array.lastIndexOf(2); // index is 3 index = array.lastIndexOf(7); // index is -1 index = array.lastIndexOf(2, 3); // index is 3 index = array.lastIndexOf(2, 2); // index is 0 index = array.lastIndexOf(2, -2); // index is 0 index = array.lastIndexOf(2, -1); // index is 3

1
2
3
**查找所有元素**

下例使用 lastIndexOf 查找到一个元素在数组中所有的索引(下标),并使用 push 将所有添加到另一个数组中。

var element = ‘a’; var array = [‘a’, ‘b’, ‘a’, ‘c’, ‘a’, ’d’];

var indices = []; var idx = array.lastIndexOf(element);

while (idx != -1) { indices.push(idx); idx = (idx > 0 ? array.lastIndexOf(element, idx - 1) : -1); }

console.log(indices); // [4, 2, 0];

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
### 3、Array.prototype.every()

every() 方法测试数组的所有元素是否都通过了指定函数的测试。

every 方法为数组中的每个元素执行一次 callback 函数,直到它找到一个使 callback 返回 false(表示可转换为布尔值 false 的值)的元素。如果发现了一个这样的元素,every 方法将会立即返回 false。否则,callback 为每一个元素返回 true,every 就会返回 true。callback 只会为那些已经被赋值的索引调用。不会为那些被删除或从来没被赋值的索引调用。

callback 被调用时传入三个参数:元素值,元素的索引,原数组。

如果为 every 提供一个 thisArg 参数,在该参数为调用 callback 时的 this 值。如果省略该参数,则 callback 被调用时的 this 值,在非严格模式下为全局对象,在严格模式下传入 undefined。

every 不会改变原数组。

every 遍历的元素范围在第一次调用 callback 之前就已确定了。在调用 every 之后添加到数组中的元素不会被 callback 访问到。如果数组中存在的元素被更改,则他们传入 callback 的值是 every 访问到他们那一刻的值。那些被删除的元素或从来未被赋值的元素将不会被访问到。


**检测所有数组元素的大小**

function isBigEnough(element, index, array) { return (element >= 10); } var passed = [12, 5, 8, 130, 44].every(isBigEnough); // passed is false passed = [12, 54, 18, 130, 44].every(isBigEnough); // passed is true

1
2
3
4
5
6
7
### 4、Array.prototype.some()

some() 方法测试数组中的某些元素是否通过了指定函数的测试。

some 为数组中的每一个元素执行一次 callback 函数,直到找到一个使得 callback 返回一个“真值”(即可转换为布尔值 true 的值)。如果找到了这样一个值,some 将会立即返回 true。否则,some 返回 false。callback 只会在那些”有值“的索引上被调用,不会在那些被删除或从来未被赋值的索引上调用。

callback 被调用时传入三个参数:元素的值,元素的索引,被遍历的数组。

arr.some(callback[, thisArg])

1
2
3
4
5
6
7
8
如果为 some 提供了一个 thisArg 参数,将会把它传给被调用的 callback,作为 this 值。否则,在非严格模式下将会是全局对象,严格模式下是 undefined。

some 被调用时不会改变数组。


**测试数组元素的值**

下面的例子检测在数组中是否有元素大于 10。

function isBigEnough(element, index, array) { return (element >= 10); } var passed = [2, 5, 8, 1, 4].some(isBigEnough); // passed is false passed = [12, 5, 8, 1, 4].some(isBigEnough); // passed is true

1
2
3
4
5
### 5、Array.prototype.filter()

filter() 方法使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组。

对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组。

var new_array = arr.filter(callback[, thisArg])

1
2
3
**筛选排除掉所有的小值**

下例使用 filter 创建了一个新数组,该数组的元素由原数组中值大于 10 的元素组成。

function isBigEnough(value) { return value >= 10; }

var filtered = [12, 5, 8, 130, 44].filter(isBigEnough); // filtered is [12, 130, 44]

1
2
3
4
5
6
7
### 6、Array.prototype.map()

map() 方法创建一个新数组,其结果是该数组中的每个元素调用一个提供的函数,**返回这个新数组**。

**求数组中每个元素的平方根**

下面的代码创建了一个新数组,值为原数组中对应数字的平方根。

var numbers = [1, 4, 9]; var roots = numbers.map(Math.sqrt); /* roots的值为[1, 2, 3], numbers的值仍为[1, 4, 9] */

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
**问答题**

问题:`["1","2","3"].map(parseInt)` 答案是多少?

答案是`[1,NaN,NaN]`

### 7、Array.prototype.forEach()

forEach() 方法对数组的每个元素执行一次提供的函数。

对数组中的每一项运行给定函数,这个方法没有返回值。本质上与使用 for 循环迭代数组一样。

array.forEach(callback(currentValue, index, array){ //do something }, this)

1
2
3
- currentValue(当前值) 数组中正在处理的当前元素。
- index(索引) 数组中正在处理的当前元素的索引。
- array forEach()方法正在操作的数组。

var arr=[2, 4, 5]; arr.forEach(function(elm,index, array) { console.log(index, elm); });

// 0 2 // 1 4 // 2 5

1
2
3
4
5
6
### 8、Array.prototype.reduce()

reduce() 方法对累加器和数组的每个值 (从左到右)应用一个函数,以将其减少为单个值。


**将数组所有项相加**

var sum = [0, 1, 2, 3].reduce(function(a, b) { return a + b; }, 0); // sum is 6

1
**数组扁平化**

var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) { return a.concat(b); }, []); // flattened is [0, 1, 2, 3, 4, 5]

1
2
3
### 9、Array.prototype.reduceRight()

reduceRight() 方法接受一个函数作为累加器(accumulator),让每个值(从右到左,亦即从尾到头)缩减为一个值。(与 reduce() 的执行方向相反)

var flattened = [[0, 1], [2, 3], [4, 5]].reduceRight(function(a, b) { return a.concat(b); }, []);

// flattened is [4, 5, 2, 3, 0, 1] ```


本文主要内容引用:

原文地址: http://zyj1022.github.io/posts/frontend/2017/js-array-base.html

转载时必须以链接形式注明原始出处及本声明