数组的方法大概分es3、es5、es6版本了,各个版本都有一些新的定义。
鉴于es5 已经成为当前主流标准,所以不区分es3 和es5了,直接区分es5和es6。
es5数组内置方法:
1,Array.prototype.push(itemX, itemY) ---向数组的末尾添加一个或更多元素,并返回新的长度。
2,Array.prototype.pop() --删除并返回数组的最后一个元素。
3,Array.prototype.unshift(itemX, itemY) -- 向数组的开头添加一个或更多元素,并返回新的长度。
4,Array.prototype.shift() -- 删除并返回数组的第一个元素。
5,Array.prototype.concat(arrayX,arrayX,......,arrayX) --连接两个或更多的数组,并返回结果,把后面的数组追加到第一个数组。
6,Array.prototype.join(指定分隔符) -- 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
6.1,String.prototype.split(指定分隔符) -- 把字符串通过指定分隔符形成数组
7,Array.prototype.reverse() -- 颠倒数组中元素的顺序。
8,Array.prototype.sort(sortby) --对数组的元素进行排序
8,Array.prototype.slice(start, end) --从某个已有的数组返回选定的元素
9,Array.prototype.splice(index,howmany,item1,.....,itemX) --删除元素,并向数组添加新元素。
10,Array.prototype.toString() --把数组转换为字符串,并返回结果。
11,Array.prototype.toLocaleString() --把数组中每一元素转换为本地字符串,再拼接,返回结果,主要是时间类。
12,Array.prototype.valueOf --返回数组对象的原始值,内部用,其实就是返回它自己
13,Array.prototype.toSource --返回该对象的源代码。// 大部分不支持
新增方法(存在ie6-ie8不兼容问题):
14,Array.prototype.forEach() --是Array新方法中最基本的一个,就是遍历,循环
15,Array.prototype.map() --原数组被“映射”成对应新数组
16,Array.prototype.filter() -- 根据过滤条件对原数组进行过滤,形成新数组
17,Array.prototype.some() --是否“某些项”合乎条件 返回true/false
18,Array.prototype.every() --是否都符合条件 返回true/false
19,Array.prototype.indexOf() --包含指定元素的第一个位置
20,Array.prototype.lastIndexOf() --从数组后面找到该元素的第一个位置
21,Array.prototype.reduce() --迭代”、“递归(recursion), 返回一个回调函数结果
22,Array.prototype.reduceRight() --从数组的末端开始迭代”、“递归(recursion), 返回一个回调函数结果
改变数组的方法有以下
push
pop
unshift
shift
splice
reverse
sort
重点讲几个方法,存在混淆点
// push 可以向尾部添加1个或者多个
var arr = [1, 2, 3];
arr.push(4, 5) // arr = [1, 2, 3, 4, 5] 以前都是插入单个,还未插入多个
// unshift 可以向头部添加1个或者多个
arr.unshift(4, 5) // arr = [4, 5, 1, 2, 3, 4, 5]
//concat 并不会改变数组
var arr2 = [10, 11];
var arr3 = arr.concat(arr2) // arr 和 arr2并不会发生变化
//sort(sortby) sortby 是一个函数,返回值为大于0 小于0 等于0
sortby = function(a, b){
return a-b;
//a -b > 0 a排在b后面
// a-b = 0 不换位置
// a-b < 0 a在b前面
}
// slice(start, end) start,end 说明
/**
start 必选 ,end可选
*/
var arr = [1, 2, 3, 4];
//start 取值情况
var arr4 = arr.slice(0, 1) // arr4 = 1 从0开始,截取1位
var arr4 = arr.slice(1, 1) // arr4 = 2 从1开始,截取1位
var arr4 = arr.slice(-1, 1) // arr4 = 4 从倒数第一位开始,截取1位
var arr4 = arr.slice(5, 1) // arr4 = [] 超出数组长度,返回空数组
// end 取值情况
var arr4 = arr.slice(1) // arr4 = [2, 3, 4] end为空,从第一位开始,截取剩下的元素
var arr4 = arr.slice(1, 0) // arr4 = [] ,截取0个元素时,返回空数组
var arr4 = arr.slice(1,10) //arr4 = [2, 3, 4] end超出数组长度时,截取剩下的元素
var arr4 = arr.slice(1, -1) //arr4 = [2, 3] end为负数时,截取到数组长度+负数的位置,不包含该位置
var arr4 = arr.slice(-1, -1) // arr4 = [] start end 均为负数时,以start为开始,若end在start前返回空,在start后,获取剩下元素
//splice(index,howmany,item1,.....,itemX)
/**
index: 起始位
howmany: 多少个
item1...itemx:插入值
*/
var arr = [1, 2, 3, 4];
arr.splice(0) // arr = [] 为一个或两个参数时,是删除操作
arr.splice(1) // arr = [2, 3, 4]
arr.splice(-1) // arr = [1, 2, 3] 当index为负值时,则从length+index位开始计算
arr.splice(-2, 1) // arr = [1, 2, 4]
arr.splice(1, 0) //arr = [1, 2, 3 ,4] 为0时不删除
arr.splice(1, 5) // arr = [1] 超出长度,以最大长度计算
arr.splice(1, 1, 10) // arr = [1,10, 3, 4] 先删除,然后在指定位置插入值
arr.splice(1, 1, 10,20) // arr = [1,10,20, 3, 4] 有多个则依次插入多个
arr.splice(10, 1, 555) // arr = [1, 2, 3, 4, 555] 起始值超出长度时,则在最后面插入
es6的方法演示及兼容写法
- forEach(callback,[ thisObject])
callback回调函数 = function (item, index ,array)
thisObject 一个可选的上下文参数(改变回调函数里面的this指向)
var data = {
users: ['张含韵', '李小璐', '白百何'],
sendEmails: function(user){
if(this.isValidUser(user)){
console.log('你好' + user);
} else {
console.log('你好不是本家人')
}
},
isValidUser: function(user){
return /^张/.test(user)
}
}
data.users.forEach(data.sendEmails, data)
//此时,如果不带data,会报错的,执行sendEmails方法用到this.isValidUser方法,此时this指向window,带了data,指向data
//jquery中也有each方法。容易混淆
$.each([], function(index, item, array) {
// ...
});
//回调函数中的参数 第一位和第二位与数组中的顺序恰恰相反,使用的时候要注意一下
// 兼容IE6-8
if(typeof Array.prototype.forEach !== 'function'){
Array.prototype.forEach = function(fn, context){
for(var k = 0, len = this.length; k < len; k++){
if(typeof fn === 'function' && Object.prototype.hasOwnProperty.call(this, k)){
fn.call(context, this[k], k, this)
}
}
}
}
//this指向的是调用的数组
- array.map(callback,[ thisObject]); //返回新数组
[].map(function(value, index, array) {
// ...
});
var arr = [1, 2, 3];
var arr2 = arr.map(function(value, index, array){
return value * 2 // 必须要return 否者返回 undefined
})
// arr2 = [2, 4, 6]
// 兼容IE6-8
if(typeof Array.prototype.map != 'function'){
Array.prototype.map = function(fn, context) {
var arr = [];
if(typeof fn === 'function' ){
for(var k = 0, len = this.length; k < len; k++){
arr.push(fn.call(context, this[k], k, this))
}
}
return arr;
}
}
3.array.filter(callback,[ thisObject]); //返回符合条件的新数组
if(typeof Array.prototype.map != 'function'){
Array.prototype.map = function(fn, context) {
var arr = [];
if(typeof fn === 'function' ){
for(var k = 0, len = this.length; k < len; k++){
fn.call(context, this[k], k, this) && arr.push(this[k]) //fn返回为真 则插入该值
}
}
return arr;
}
}
- array.some(callback,[ thisObject]); // 其中某项符合, 返回true/false
var arr = [1, 4, 8];
var result = arr.some(function(item, index ,array){
if(item > 4){
return true;
}
})
result === true
// 兼容IE6-8
if(typeof Array.prototype.some!= 'function'){
Array.prototype.some = function(fn, context) {
var passed = false;
if(typeof fn === 'function'){
for(var k = 0, len = this.length; k < len; k++){
if(passed === true) {
break;
}
passed = !!fn(context, this[k], k, this);
}
}
return passed
}
}
- every(callback,[ thisObject]); //全部符合,返回true/false
var arr = [1, 4, 8];
var result = arr.every(function(item, index ,array){
if(item > 4){
return true;
}
})
result === false
// 兼容IE6-8
if(typeof Array.prototype.every!= 'function'){
Array.prototype.every= function(fn, context) {
var passed = true;
if(typeof fn === 'function'){
for(var k = 0, len = this.length; k < len; k++){
if(passed === false) {
break;
}
passed = !!fn(context, this[k], k, this);
}
}
return passed
}
}
- array.indexOf(searchElement[, fromIndex])
indexOf方法在字符串中自古就有,string.indexOf(searchString, position)。数组这里的indexOf方法与之类似。
返回整数索引值,如果没有匹配(严格匹配),返回-1. fromIndex可选,表示从这个位置开始搜索,若缺省或格式不合要求,使用默认值0,我在FireFox下测试,发现使用字符串数值也是可以的,例如"3"和3都可以。
var data = [2, 5, 7, 3, 5];
console.log(data.indexOf(5, "x")); // 1 ("x"被忽略)
console.log(data.indexOf(5, "3")); // 4 (从3号位开始搜索)
console.log(data.indexOf(4)); // -1 (未找到)
console.log(data.indexOf("5")); // -1 (未找到,因为5 !== "5")
// 兼容IE6-8
if (typeof Array.prototype.indexOf != "function") {
Array.prototype.indexOf = function (searchElement, fromIndex) {
var index = -1;
fromIndex = fromIndex * 1 || 0;
for (var k = 0, length = this.length; k < length; k++) {
if (k >= fromIndex && this[k] === searchElement) { //大于起始位且相等
index = k;
break;
}
}
return index;
};
}
- array.lastIndexOf(searchElement[, fromIndex])
lastIndexOf方法与indexOf方法类似:只是lastIndexOf是从字符串的末尾开始查找,而不是从开头。还有一个不同就是fromIndex的默认值是array.length - 1而不是0.
if (typeof Array.prototype.lastIndexOf != "function") {
Array.prototype.lastIndexOf = function (searchElement, fromIndex) {
var index = -1, length = this.length;
fromIndex = fromIndex * 1 || length - 1;
for (var k = length - 1; k > -1; k-=1) {
if (k <= fromIndex && this[k] === searchElement) {
index = k;
break;
}
}
return index;
};
}
var data = [2, 5, 7, 3, 5];
console.log(data.lastIndexOf(5)); // 4
console.log(data.lastIndexOf(5, 3)); // 1 (从后往前,索引值小于3的开始搜索)
console.log(data.lastIndexOf(4)); // -1 (未找到)
- array.reduce(callback[, initialValue])
callback函数接受4个参数:之前值、当前值、索引值以及数组本身。initialValue参数可选,表示初始值。若指定,则当作最初使用的previous值;如果缺省,则使用数组的第一个元素作为previous初始值,同时current往后排一位,相比有initialValue值少一次迭代。
var sum = [1, 2, 3, 4].reduce(function (previous, current, index, array) {
return previous + current;
});
console.log(sum); // 10
说明:
因为initialValue不存在,因此一开始的previous值等于数组的第一个元素。
从而current值在第一次调用的时候就是2.
最后两个参数为索引值index以及数组本身array.
执行过程:
// 初始设置
previous = initialValue = 1, current = 2
// 第一次迭代
previous = (1 + 2) = 3, current = 3
// 第二次迭代
previous = (3 + 3) = 6, current = 4
// 第三次迭代
previous = (6 + 4) = 10, current = undefined (退出)
var matrix = [
[1, 2],
[3, 4],
[5, 6]
];
// 二维数组扁平化
var flatten = matrix.reduce(function (previous, current) {
return previous.concat(current);
});
console.log(flatten); // [1, 2, 3, 4, 5, 6]
// 兼容ie6-8
if (typeof Array.prototype.reduce != "function") {
Array.prototype.reduce = function (callback, initialValue ) {
var previous = initialValue, k = 0, length = this.length;
if (typeof initialValue === "undefined") {
previous = this[0];
k = 1;
}
if (typeof callback === "function") {
for (k; k < length; k++) {
this.hasOwnProperty(k) && (previous = callback(previous, this[k], k, this));
}
}
return previous;
};
}
- array.reduceRight(callback[, initialValue])
reduceRight是从数组的末尾开始实现
var data = [1, 2, 3, 4];
var specialDiff = data.reduceRight(function (previous, current, index) {
if (index == 0) {
return previous + current;
}
return previous - current;
});
console.log(specialDiff); // 0
// 初始设置
index = 3, previous = initialValue = 4, current = 3
// 第一次迭代
index = 2, previous = (4- 3) = 1, current = 2
// 第二次迭代
index = 1, previous = (1 - 2) = -1, current = 1
// 第三次迭代
index = 0, previous = (-1 + 1) = 0, current = undefined (退出)
if (typeof Array.prototype.reduceRight != "function") {
Array.prototype.reduceRight = function (callback, initialValue ) {
var length = this.length, k = length - 1, previous = initialValue;
if (typeof initialValue === "undefined") {
previous = this[length - 1];
k--;
}
if (typeof callback === "function") {
for (k; k > -1; k-=1) {
this.hasOwnProperty(k) && (previous = callback(previous, this[k], k, this));
}
}
return previous;
};
}
应用场景举例:
var eleDivs = document.getElementsByTagName("div");
Array.prototype.forEach.call(eleDivs, function(div) {
console.log("该div类名是:" + (div.className || "空"));
});
网友评论