JavaScript中数组对象的那些自带方法介绍


Posted in Javascript onMarch 12, 2013

/**
* 本文纯粹是梳理一下目前W3C标准中Array对象的自带Method。
* 全文没啥营养,不过最后性能测试的部分,倒是抛出了一些疑问。
*/
赋值方法 (Mutator methods)
这些方法直接修改数组自身
pop 和 push
Array.pop(); // 删除数组最后一个元素,返回被删除的元素
Array.push(element1, ..., elementN); // 在数组尾部插入1-N个元素,返回操作后数组的length
通过这 pop 和 push ,就能把数组模拟成 堆栈(stack) 来进行操作。
堆栈这种数据结构的特点,就是“后进先出”(LIFO, Last In First Out)。
shift 和 unshift
Array.shift(); // 删除数组第一个元素,返回被删除的元素
Array.unshift(element1, ..., elementN) ; // 在数组头部插入1-N个元素,返回操作后数组的length
利用 shift 和 unshift 则可以实现 队列(queue) 的操作。
队列的操作方式和堆栈相反,采用“先进先出”(FIFO, First-In-First-Out)。
splice

Array.splice(index , howMany[, element1[, ...[, elementN]]]); 
Array.splice(index);

参数:
index:规定从何处添加/删除元素。
howmany:规定应该删除多少元素。
elements:规定要添加到数组的新元素,从 index 所指的下标处开始插入。
splice方法是对 pop、push、shift、unshift 的一个补充。
返回值是被删除的元素。
reverse
Array.reverse(); // 颠倒数组中元素的顺序,并返回逆序后的数组

sort
Array.sort([compareFunction]);

如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序。
说得更精确点,是按照字符编码的顺序进行排序。
如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
•若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
•若 a 等于 b,则返回 0。
•若 a 大于 b,则返回一个大于 0 的值。
--------------------------------------------------------------------------------
访问方法(Accessor methods)
这些方法只是返回相应的结果,而不会修改数组本身
concat
Array.concat(value1, value2, ..., valueN); // 链接2个或多个数组,并返回合并后的数组

但有一个需要注意的地方,用下面的例子说明:
var arr = [1, 2, 3]; 
arr.concat(4, 5); // return [1, 2, 3, 4, 5] 
arr.concat([4, 5]); // return [1, 2, 3, 4, 5] 
arr.concat([4, 5], [6, 7]); // return [1, 2, 3, 4, 5, 6, 7] 
arr.concat(4, [5, [6, 7]]); // return [1, 2, 3, 4, 5, [6, 7]]

join
string = Array.join(separator);
把数组中的所有元素放入一个字符串。其中,元素之间是通过指定的分隔符进行分隔的。
默认的分隔符是逗号(,),返回值是合并后字符串。
[1, 2, 3].join(); // return "1,2,3"Array.join()方法,实际上是String.splite()的逆向操作。
slice
Array.slice(begin[, end]); // 数组中返回选定的元素

toString
Array.toString(); // 这个就不说了,所有JavaScript都有toString这个方法

indexOf 和 lastIndexOf *[ECMAScript 5]
Array.indexOf(searchElement[, fromIndex]); // 从头开始搜索 
Array.lastIndexOf(searchElement[, fromIndex]); // 从尾开始搜索

searchElement:需要搜索的值
fromIndex:索引,指示搜索从哪里开始
--------------------------------------------------------------------------------
迭代方法(Iteration methods)
forEach *[ECMAScript 5]
Array.forEach(callback[, thisArg]); // 从头到尾遍历一次数组,并为数组中的每个元素,调用指定的函数

参数:
callback:遍历数组时调用的函数
thisArg:指定 callback 的作用域
另外,callback会调用三个参数:
value:数组元素
index:数组索引
array:数组本身
[1, 2].forEach(function(value, index, array) { 
console.log(value, index, array); 
}); 
// return 
// 1 0 [1, 2] 
// 2 1 [1, 2]

Note:forEach是无法通过break来中断数组的遍历。
解决方法:利用try方法来抛出异常,终止遍历。
try { 
[1,2,3].forEach(function(val) { 
console.log(val); 
throw(e) 
}); 
} catch(e) { 
console.log(e); 
}

map *[ECMAScript 5]
Array.map(callback[, thisArg]); // 遍历数组元素,调用指定函数,并以数组返回所有结果
参数:
callback:遍历数组时调用的函数
thisObject :指定 callback 的作用域
例子:
[1, 2, 3].map(function(num) { // return [2, 3, 4] 
return num + 1; 
});

filter *[ECMAScript 5]
Array.filter(callback[, thisObject]); // 遍历数组调用方法,满足条件(返回true)的元素,将被添加到返回值的数组中

参数:
callback:遍历数组时调用的函数
thisObject :指定 callback 的作用域
例子:
[1, 2, 3].filter(function(num) { // return [1] 
return num < 2; 
});

every 和 some *[ECMAScript 5]
Array.every(callback[, thisObject]); // “与” 
Array.some(callback[, thisObject]); // “或”

参数:
callback:遍历数组时调用的函数
thisObject:指定 callback 的作用域
every:当所有元素调用函数都返回true,结果才返回true,不然均返回false。
some:当所有元素调用函数都返回false,结果才返回false,不然均返回true。
一旦every和some的返回值确定,就会立刻停止遍历。
例子:
[1, 2, 3]. every(function(num) { // return false 
return num > 1; 
}); 
[1, 2, 3]. some(function(num) { // return true 
return num > 2; 
});

reduce 和 reduceRight *[ECMAScript 5]
Array.reduce(callback[, initialValue]); // 使用指定的方法将数组元素进行组合,按索引从低到高(从左到右) 
Array.reduceRight(callback[, initialValue]); // 使用指定的方法将数组元素进行组合,按索引从高到低(从右到左)

参数:
callback:遍历数组时调用的函数
initialValue:第一个次调用callback时传入的previousValue
另外,callback会调用四个参数:
previousValue:到目前为止的操作累积结果
currentValue:数组元素
index:数组索引
array:数组本身
例子:
[1, 2, 3]. reduce(function(x, y) { // return 106
return x + y;
}, 100);
--------------------------------------------------------------------------------
性能测试
测试系统:Windows 7
测试浏览器:Chrome 26.0.1386.0
var arr = []; for(var i = 0; i < 999999; i++) { 
arr.push(i); 
}

forEach
function forEachTest() { 
howTime("forEach", function() { 
var num = 0; 
arr.forEach(function(val, key) { 
num += val; 
}); 
}); 
howTime("for", function() { 
var num = 0; 
for(var i = 0, len = arr.length; i < len; i++) { 
num += arr[i]; 
} 
}); 
}

下面是随机进行的3次测试结果(具体结果与电脑配置有关,结果越小则性能越好):
time_forEach time_for
1421.000ms  64.000ms 
1641.000ms  63.000ms 
1525.000ms  63.000ms 

可以看到,Chrome并没有对forEach做专门的优化,和直接用for循环遍历相比,性能还是有很大的差距。
因为forEach是 ECMAScript 5 的东西,旧版浏览器并不支持。
不过MDN都有给出向下兼容的解决方法:
if(!Array.prototype.forEach) { 
Array.prototype.forEach = function(fn, scope) { 
for(var i = 0, len = this.length; i < len; ++i) { 
fn.call(scope, this[i], i, this); 
} 
} 
}

离谱的是,原生的 forEach 方法,在性能上,居然比不上自己构造的 forEach!
还有,其他Array对象其他的迭代方法呢?
大家看看这个Demo就基本清楚了:http://maplejan.sinaapp.com/demo/ArratMethod.html
另外,还发现了一个有意思的情况。
如果直接在控制台运行Demo的JavaScript代码,你会发现性能上有很大差异!
这个时候,直接用for循环写的方法,性能会更差。
对于这个疑问,在知乎上提问了,问题地址:http://www.zhihu.com/question/20837774
Javascript 相关文章推荐
JavaScript 一行代码,轻松搞定浮动快捷留言-V2升级版
Apr 02 Javascript
jquery用get实现ajax在ie里面刷新不进入后台解决方法
Aug 12 Javascript
js同比例缩放图片的小例子
Oct 30 Javascript
IE8下String的Trim()方法失效的解决方法
Nov 08 Javascript
javascript删除数组元素并且数组长度减小的简单实例
Feb 14 Javascript
jQuery表格行上移下移和置顶的实现方法
Oct 08 Javascript
JavaScript实现的MD5算法完整实例
Feb 02 Javascript
node.js微信公众平台开发教程
Mar 04 Javascript
简单实现js浮动框
Dec 13 Javascript
JavaScript 程序错误Cannot use 'in' operator to search的解决方法
Jul 10 Javascript
js实现提交前对列表数据的增删改查
Jan 16 Javascript
Openlayers3实现车辆轨迹回放功能
Sep 29 Javascript
P3P Header解决Cookie跨域的问题
Mar 12 #Javascript
解决JS浮点数运算出现Bug的方法
Mar 12 #Javascript
JS实现悬浮移动窗口(悬浮广告)的特效
Mar 12 #Javascript
js弹出模式对话框,并接收回传值的方法
Mar 12 #Javascript
js 获取class的元素的方法 以及创建方法getElementsByClassName
Mar 11 #Javascript
.net,js捕捉文本框回车键事件的小例子(兼容多浏览器)
Mar 11 #Javascript
JS中Iframe之间传值的方法
Mar 11 #Javascript
You might like
php中使用Akismet防止垃圾评论的代码
2011/06/10 PHP
Linux下PHP安装mcrypt扩展模块笔记
2014/09/10 PHP
php解析字符串里所有URL地址的方法
2015/04/03 PHP
老生常谈PHP面向对象之解释器模式
2017/05/17 PHP
JavaScript Event学习补遗 addEventSimple
2010/02/11 Javascript
Jquery插件之打造自定义的select标签
2011/11/30 Javascript
Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法
2016/06/23 Javascript
AngularJs Dependency Injection(DI,依赖注入)
2016/09/02 Javascript
从零学习node.js之利用express搭建简易论坛(七)
2017/02/25 Javascript
javascript实现日期三级联动下拉框选择菜单
2020/12/03 Javascript
详解angularJS自定义指令间的相互交互
2017/07/05 Javascript
基于BootStrap的文本编辑器组件Summernote
2017/10/27 Javascript
Vue.js自定义事件的表单输入组件方法
2018/03/08 Javascript
node 使用 async 控制并发的方法
2018/05/07 Javascript
vue 使用自定义指令实现表单校验的方法
2018/08/28 Javascript
angularJs自定义过滤器实现手机号信息隐藏的方法
2018/10/08 Javascript
微信小程序系列之自定义顶部导航功能
2019/05/21 Javascript
JS数组中对象去重操作示例
2019/06/04 Javascript
JavaScript生成随机验证码代码实例
2019/09/28 Javascript
javascript 内存模型实例详解
2020/04/18 Javascript
[06:06]2018DOTA2亚洲邀请赛主赛事第四日战况回顾 全明星赛欢乐上演
2018/04/07 DOTA
python实现根据用户输入从电影网站获取影片信息的方法
2015/04/07 Python
Python3使用requests包抓取并保存网页源码的方法
2016/03/15 Python
Python计时相关操作详解【time,datetime】
2017/05/26 Python
Django使用Celery异步任务队列的使用
2018/03/13 Python
Python3中的bytes和str类型详解
2019/05/02 Python
keras 权重保存和权重载入方式
2020/05/21 Python
Python-openCV开运算实例
2020/07/05 Python
谈谈python垃圾回收机制
2020/09/27 Python
比利时网上药店: Drogisterij.net
2017/03/17 全球购物
世界上最全面的草药补充剂和顶级品牌维生素网站:HerbsPro
2019/01/20 全球购物
大学毕业感言一句话
2014/02/06 职场文书
安全生产活动月方案
2014/03/09 职场文书
安全标语大全
2014/06/10 职场文书
2014年学生资助工作总结
2014/12/18 职场文书
优秀范文:读《红岩》有感3篇
2019/10/14 职场文书