ES5中数组新增的方法说明
一、前言-索引
ES5中新增的不少东西,了解之对我们写JavaScript会有不少帮助,比如数组这块,我们可能就不需要去有板有眼地for
循环了。
ES5中新增了写数组方法,如forEach (js v1.6), map (js v1.6) ,filter (js v1.6),some (js v1.6),every (js v1.6),indexOf (js v1.6),lastIndexOf (js v1.6),reduce (js v1.8),reduceRight (js v1.8)
浏览器支持
- Opera 11+
- Firefox 3.6+
- Safari 5+
- Chrome 8+
- Internet Explorer 9+
二、
- forEach
forEach
是Array新方法中最基本的一个,就是遍历,循环。例如下面这个例子:[1, 2 ,3, 4].forEach(alert);
等同于下面这个传统的
for
循环:var array = [1, 2, 3, 4]; for (var k = 0, length = array.length; k < length; k++) {
alert(array[k]);
}Array在ES5新增的方法中,参数都是
function
类型,默认有传参,这些参数分别是?见下面:[1, 2 ,3, 4].forEach(console.log); // 结果: // 1, 0, [1, 2, 3, 4]
// 2, 1, [1, 2, 3, 4]
// 3, 2, [1, 2, 3, 4]
// 4, 3, [1, 2, 3, 4]显而易见,
forEach
方法中的function
回调支持3个参数,第1个是遍历的数组内容;第2个是对应的数组索引,第3个是数组本身。因此,我们有:
[].forEach(function(value, index, array) {
// ...
});对比jQuery中的
$.each
方法:$.each([], function(index, value, array) {
// ...
});会发现,第1个和第2个参数正好是相反的,大家要注意了,不要记错了。后面类似的方法,例如
$.map
也是如此。现在,我们就可以使用
forEach
卖弄一个稍显完整的例子了,数组求和:var sum = 0; [1, 2, 3, 4].forEach(function (item, index, array) {
console.log(array[index] == item); // true
sum += item;
}); alert(sum); // 10再下面,更进一步,
forEach
除了接受一个必须的回调函数参数,还可以接受一个可选的上下文参数(改变回调函数里面的this
指向)(第2个参数)。array.forEach(callback,[ thisObject])
例子更能说明一切:
var database = {
users: ["张含韵", "江一燕", "李小璐"],
sendEmail: function (user) {
if (this.isValidUser(user)) {
console.log("你好," + user);
} else {
console.log("抱歉,"+ user +",你不是本家人");
}
},
isValidUser: function (user) {
return /^张/.test(user);
}
}; // 给每个人法邮件
database.users.forEach( // database.users中人遍历
database.sendEmail, // 发送邮件
database // 使用database代替上面标红的this
); // 结果:
// 你好,张含韵
// 抱歉,江一燕,你不是本家人
// 抱歉,李小璐,你不是本家如果这第2个可选参数不指定,则使用全局对象代替(在浏览器是为
window
),严格模式下甚至是undefined
.另外,forEach不会遍历纯粹“占着官位吃空饷”的元素的,例如下面这个例子:
var array = [1, 2, 3]; delete array[1]; // 移除 2
alert(array); // "1,,3" alert(array.length); // but the length is still 3 array.forEach(alert); // 弹出的仅仅是1和3 - map
这里的map
不是“地图”的意思,而是指“映射”。[].map();
基本用法跟forEach
方法类似:array.map(callback,[ thisObject]);
callback
的参数也类似:[].map(function(value, index, array) {
// ...
});map
方法的作用不难理解,“映射”嘛,也就是原数组被“映射”成对应新数组。下面这个例子是数值项求平方:var data = [1, 2, 3, 4]; var arrayOfSquares = data.map(function (item) {
return item * item;
}); alert(arrayOfSquares); // 1, 4, 9, 16callback
需要有return
值,如果没有,就像下面这样:var data = [1, 2, 3, 4];
var arrayOfSquares = data.map(function() {}); arrayOfSquares.forEach(console.log);结果如下图,可以看到,数组所有项都被映射成了
undefined
:在实际使用的时候,我们可以利用
map
方法方便获得对象数组中的特定属性值们。例如下面这个例子(之后的兼容demo也是该例子):var users = [
{name: "张含韵", "email": "zhang@email.com"},
{name: "江一燕", "email": "jiang@email.com"},
{name: "李小璐", "email": "li@email.com"}
]; var emails = users.map(function (user) { return user.email; }); console.log(emails.join(", ")); // zhang@email.com, jiang@email.com, li@email.com - filter
filter
为“过滤”、“筛选”之意。指数组filter
后,返回过滤后的新数组。用法跟map
极为相似:array.filter(callback,[ thisObject]);
filter
的callback
函数需要返回布尔值true
或false
. 如果为true
则表示,通过!如果为false
,可能会疑问,一定要是
Boolean
值吗?我们可以简单测试下嘛,如下:var data = [0, 1, 2, 3];
var arrayFilter = data.filter(function(item) {
return item;
});
console.log(arrayFilter); // [1, 2, 3]有此可见,返回值只要是弱等于
== true/false
就可以了,而非非得返回=== true/false
. - some
some
意指“某些”,指是否“某些项”合乎条件。与下面的every
算是好基友,every
表示是否“每一项”都要靠谱。用法如下:array.some(callback,[ thisObject]);
例如下面的简单使用:
var scores = [5, 8, 3, 10];
var current = 7; function higherThanCurrent(score) {
return score > current;
} if (scores.some(higherThanCurrent)) {
alert("朕准了!");
}结果弹出了“朕准了”文字。
some
要求至少有1个值让callback
返回true
就可以了。显然,8 > 7
,因此scores.some(higherThanCurrent)
值为true
.我们自然可以使用
forEach
进行判断,不过,相比some
, 不足在于,some
只有有true
即返回不再执行了。 - every
跟some
的基友关系已经是公开的秘密了,同样是返回Boolean值,不过,every
需要每一个妃子都要让朕满意,否则——“来人,给我拖出去砍了!”结果是:
- indexOf
indexOf
方法在字符串中自古就有,string.indexOf(searchString, position)
。数组这里的indexOf
方法与之类似。array.indexOf(searchElement[, fromIndex])
返回整数索引值,如果没有匹配(严格匹配),返回
-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")下图为ietester IE6下的截图:
- lastIndexOf
lastIndexOf
方法与indexOf
方法类似:array.lastIndexOf(searchElement[, fromIndex])
只是
lastIndexOf
是从字符串的末尾开始查找,而不是从开头。还有一个不同就是fromIndex
的默认值是array.length - 1
而不是0
.IE6等浏览器如下折腾:
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 (未找到) - reduce
reduce
是JavaScript 1.8中才引入的,中文意思为“减少”、“约简”。不过,从功能来看,我个人是无法与“减少”这种含义联系起来的,反而更接近于“迭代”、“递归(recursion)”,擦,因为单词这么接近,不会是ECMA-262 5th制定者笔误写错了吧~~此方法相比上面的方法都复杂,用法如下:
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 (退出)有了
reduce
,我们可以轻松实现二维数组的扁平化: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-IE8:
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;
};
}然后,测试整合,demo演示,您可以狠狠地点击这里:兼容IE6的reduce方法测试demo
IE6浏览器下结果如下图:
- 因为
- reduceRight
reduceRight
跟reduce
相比,用法类似: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结果
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;
};
}您可以狠狠地点击这里:reduceRight简单使用demo
对比FireFox浏览器和IE7浏览器下的结果:
三、更进一步的应用
我们还可以将上面这些数组方法应用在其他对象上。
例如,我们使用forEach遍历DOM元素。
var eleDivs = document.getElementsByTagName("div");
Array.prototype.forEach.call(eleDivs, function(div) {
console.log("该div类名是:" + (div.className || "空"));
});
可以输出页面所有div
的类名,您可以狠狠地点击这里:Array新方法forEach遍历DOM demo
结果如下,IE6下,demo结果:
等很多其他类数组应用。
以上为转载,来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
原文地址:http://www.zhangxinxu.com/wordpress/?p=3220
ES5中数组新增的方法说明的更多相关文章
- ES6中数组新增的方法-超级好用
Array.find((item,indexArr,arr)=>{}) 掌握 找出第一个符合条件的数组成员. 它的参数是一个回调函数,对所有数组成员依次执行该回调函数. 直到找出第一个返回值为t ...
- es5中数组的遍历方法
//for循环 const arr = [1,2,3,4,5] for(let i = 0; i < arr.length; i++){ if(arr[i] === 2){ //break // ...
- JS中数组和字符串方法的简单整理
一.数组: 数组的基本方法: 1.增:arr.unshift() /push() 前增/后增 2.删:arr.shift() /pop ...
- ES6中数组的新方法
数组的扩展 1.1扩展运算符 1.1.1:... 扩展运算符(spread)是三个点(...).它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列. <body> < ...
- JS中数组的迭代方法和归并方法
昨天总结的JavaScript中的数组Array方法 数组的迭代方法 ES5中为数组定义了5个迭代方法.每个方法都要接收两个参数:要在每一项上面运行的函数和(可选的)运行该函数的作用域对象---影响t ...
- javascript中数组常用的方法
在JavaScript中,数组可以使用Array构造函数来创建,或使用[]快速创建,这也是首选的方法.数组是继承自Object的原型,并且他对typeof没有特殊的返回值,他只返回'object'. ...
- javascript中数组Array的方法
一.常用方法(push,pop,unshift,shift,join)push pop栈方法,后进先出var a =[1,2,3];console.log(a.push(40)); //4 返回数组的 ...
- javascript中数组的concat()方法 - 数组连接
<html> <head> <title>数组的concat()方法</title> <script> /* 数组的concat()方法: ...
- javascript中数组常用的方法和属性
前言 在javascript中,数组是一种非常重要的数据类型,我们时常会和它打交道,最近在开发项目中频繁的使用到数组,但是自己对数组的众多方法已经是非常模糊了,为了方便自己以后能够更好的使用数组中的属 ...
随机推荐
- SSL 通信及 java keystore 工具介绍
http://www.javacodegeeks.com/2014/07/java-keystore-tutorial.html Table Of Contents 1. Introduction 2 ...
- Altium Designer6打印PCB 设置
1.File-->Page Setup Printer Paper一栏是打印纸的设置,不再罗嗦. 主要是Scaling一栏:ScaleMode项选择:ScaledPrint ...
- jetty之建立多Connector
转自:http://blog.csdn.net/kongxx/article/details/7218787 在嵌入运行Jetty的时候,有时候想要启动两个端口,或者通过一个Jetty server提 ...
- MD5是什么,怎么用着怪怪的
写作目的 通常我们在使用加密算法时,都是直接调用一个方法,比如Base64,直接把待加密的字符串给加密好了.对于某些使用公私钥的算法,最多再传入一段公钥即可.但是在使用MD5算法的时候,总是需要用到一 ...
- mac下教你如何开源项目托管GitHub
自从google code关闭了下载服务了之后,GitHub作为了目前最好用的免费开源项目托管站点,众多开源项目都托管在github,其中不乏著名的播放器MPC-HC. 这里教大家如何把代码库上传到G ...
- PAT---1050. String Subtraction (20)
#include<iostream> #include<string.h> #include<stdio.h> using namespace std; #defi ...
- Robotium---环境搭建及入门示例
Robotium是一款基于控件的Android自动化测试框架 环境搭建(window): 安装JDK以及集成Android Sdk的eclipise. 入门: 1,下载Robotium Solo 5. ...
- Linux性能及调优指南(翻译)
http://blog.csdn.net/ljianhui/article/details/46718835 http://blog.chinaunix.net/uid-26000296-id-406 ...
- JavaScript 应用开发 #3:应用的主视图
目前为止,我们已经在应用里面,创建了表示数据的模型,表示数据列表的集合,组织模型显示的视图与模板.下面, 我们要想办法,去把模型的列表显示在应用的界面上.这样我们就可以再去为应用创建一个主要的视图,用 ...
- 需要重新启动计算机.必须重新启动计算机才能安装 SQL Server
在开始运行中输入regedit找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager 在右边窗口找到PendingFi ...