您的位置:首页 > Web前端 > JavaScript

Javascript学习---Array数组方法详解

2018-02-04 15:17 633 查看

数组修改方法

在数组那一章已经介绍了push,pop,shift和unshift方法,接下来这里再记录数组的其他常用方法。

splice()

前面我们知道要删除对象的属性可以用delete关键字,数组也一样,例如:
let arr = ["I", "go", "home"];

delete arr[1]; // remove "go"

alert( arr[1] ); // undefined

// now arr = ["I",  , "home"];
alert( arr.length ); // 3

这里要注意的是,delete只是移除了数组指定索引号的元素的值,此时该元素还占据着索引位置,只不过为空,数组的length还是没变。

splice方法的出现可以解决这种问题,它彻底地移除了指定的数组元素,同时数组的length也会修改,例如:
let arr = ["I", "study", "JavaScript"];

arr.splice(1, 1); // from index 1 remove 1 element

alert( arr ); // ["I", "JavaScript"]
这里arr.splice(1,1)的第一个1表示索引号,第二个1表示要移除元素的个数

splice方法还可以用来添加元素,例如:
let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 3 first elements and replace them with another
arr.splice(0, 3, "Let's", "dance");

alert( arr ) // now ["Let's", "dance", "right", "now"]


或者在不删除元素的情况下来添加元素,例如:
let arr = ["I", "study", "JavaScript"];

// from index 2
// delete 0
// then insert "complex" and "language"
arr.splice(2, 0, "complex", "language");

alert( arr ); // "I", "study", "complex", "language", "JavaScript"


也可以使用负数索引号,表示从数组尾部开始,例如:
let arr = [1, 2, 5];

// from index -1 (one step from the end)
// delete 0 elements,
// then insert 3 and 4
arr.splice(-1, 0, 3, 4);

alert( arr ); // 1,2,3,4,5


这里我们可以看出splice()方法返回的是被移除的元素,例如:
let arr = ["I", "study", "JavaScript", "right", "now"];

// remove 2 first elements
let removed = arr.splice(0, 2);

alert( removed ); // "I", "study" <-- array of removed elements

slice()

slice()用来截取数组,它返回一个新的数组,这一点slice()和字符串的slice()很像,例如:
let str = "test";
let arr = ["t", "e", "s", "t"];

alert( str.slice(1, 3) ); // es
alert( arr.slice(1, 3) ); // e,s

alert( str.slice(-2) ); // st
alert( arr.slice(-2) ); // s,t

concat()

concat()方法用来连接其它数组,例如:
let arr = [1, 2];

// merge arr with [3,4]
alert( arr.concat([3, 4])); // 1,2,3,4

// merge arr with [3,4] and [5,6]
alert( arr.concat([3, 4], [5, 6])); // 1,2,3,4,5,6

// merge arr with [3,4], then add values 5 and 6
alert( arr.concat([3, 4], 5, 6)); // 1,2,3,4,5,6


也可以用来连接对象,例如:
let arr = [1, 2];

let arrayLike = {
0: "something",
length: 1
};

alert( arr.concat(arrayLike) ); // 1,2,[object Object]
//[1, 2, arrayLike]


但是,如果被连接对象里有[Symbol.isConcatSpreadable]属性,则该属性不会被连接进去,例如:
let arr = [1, 2];

let arrayLike = {
0: "something",
1: "else",
[Symbol.isConcatSpreadable]: true,
length: 2
};

alert( arr.concat(arrayLike) ); // 1,2,something,else

数组元素查找

indexOf()/lastIndexOf()/includes()

数组的元素查找方法和字符串的查找很像,例如:
let arr = [1, 0, false];

alert( arr.indexOf(0) ); // 1
alert( arr.indexOf(false) ); // 2
alert( arr.indexOf(null) ); // -1

alert( arr.includes(1) ); // true


有一点要注意的是,这些方法内部都是用了===来判断,如果数组元素为特殊关键字NaN,includes()会正确处理,而indexOf()和lastIndexOf()则不会,例如:
const arr = [NaN];
alert( arr.indexOf(NaN) ); // -1 (should be 0, but === equality doesn't work for NaN)
alert( arr.includes(NaN) );// true (correct)


find()/findIndex()

find()的语法如下:
let result = arr.find(function(item, index, array) {
// should return true if the item is what we are looking for
});
item:要查找的元素对象;
index:查找元素的索引号;
array:数组本身;

如果数组里的元素是对象,例如方法等,这时候我们就要用find()/findIndex()了,例如:
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];

let user = users.find(item => item.id == 1);

alert(user.name); // John


findIndex()用于返回要查找元素对象的索引号,由于它和find()很像,就不详解

filter()

filter()的语法如下:
let results = arr.filter(function(item, index, array) {
// should return true if the item passes the filter
});


上面的find()查找的是一个元素,filter()用于查找多个元素,例如:
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];

// returns array of the first two users
let someUsers = users.filter(item => item.id < 3);

alert(someUsers.length); // 2

数组的转换

map()

map()的语法如下:
let result = arr.map(function(item, index, array) {
// returns the new value instead of item
})


map()会遍历数组的每个元素并返回新的数组,返回数组的值就是你在map方法里操作的结果,而原数组内容不会发生变化,例如:
let arr = ["Bilbo", "Gandalf", "Nazgul"];
let lengths = arr.map(item => item.length);
alert(lengths); // 5,7,6
alert(arr);  // Bilbo,Gandalf,Nazgul

sort()

sort()方法默认是以string的类型进行排序,例如:
let arr = [ 1, 2, 15 ];

// the method reorders the content of arr (and returns it)
arr.sort();

alert( arr );  // 1, 15, 2


为了能够对数字类型进行排序,我们需要再定义一个比较函数作为sort()的参数,例如:
function compare(a, b) {
if (a > b) return 1;
if (a == b) return 0;
if (a < b) return -1;
}

function compareNumeric(a, b) {
if (a > b) return 1;
if (a == b) return 0;
if (a < b) return -1;
}

let arr = [ 1, 2, 15 ];

arr.sort(compareNumeric);

alert(arr);  // 1, 2, 15


比较函数还有以下两种推荐的简便写法,例如:
let arr = [ 1, 2, 15 ];

arr.sort(function(a, b) { return a - b; });

alert(arr);  // 1, 2, 15

arr.sort( (a, b) => a - b );


reserve()

我们可以使用reserve()方法来对数组内容进行反转,例如:
let arr = [1, 2, 3, 4, 5];
arr.reverse();

alert( arr ); // 5,4,3,2,1


reduce()和reduceRight()

reduce()用来遍历数组并且设置一个变量来记录操作结果,它的语法如下:
let value = arr.reduce(function(previousValue, item, index, arr) {
// ...
}, initial);
previousValue:我们设置的变量;
item:数组遍历到的当前元素;
index:当前元素的索引;
arr:当前数组;
initial:表示设置的变量的初始值;

下面这个例子就很详细了:
let arr = [1, 2, 3, 4, 5];

let result = arr.reduce((sum, current) => sum + current, 0);

alert(result); // 15


数组遍历

forEach()

forEach()可以用来遍历数组,它的语法如下:
arr.forEach(function(item, index, array) {
// ... do something with item
});


要注意的是,方法参数里的操作不会修改原数组的内容,例如:
let arr = ["Bilbo", "Gandalf", "Nazgul"]

arr.forEach((item, index, array) => {
item = "111";
});

alert(arr);  // Bilbo,Gandalf,Nazgul

Array.isArray()

用typeof来判断对象是否为数组并不能达到我们的预想,因为数组也是对象,例如:
alert(typeof {}); // object
alert(typeof []); // object


不过Array提供了一个内置方法来判断数组,例如:
alert(Array.isArray({})); // false

alert(Array.isArray([])); // true


可选方法参数thisArg

前面的数组方法都默认支持thisArg这个参数,只不过一般我们很少用,例如:
arr.find(func, thisArg);
arr.filter(func, thisArg);
arr.map(func, thisArg);
// ...
// thisArg is the optional last argument
thisArg表示this对象,用于绑定方法里的this,例如:
let user = {
age: 18,
younger(otherUser) {
return otherUser.age < this.age;
}
};

let users = [
{age: 12},
{age: 16},
{age: 32}
];

// find all users younger than user
let youngerUsers = users.filter(user.younger, user);

alert(youngerUsers.length); // 2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: