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 相关文章推荐
Js+XML 操作
Sep 20 Javascript
经常用到的JavasScript事件的翻译
Apr 09 Javascript
JavaScript学习笔记(十)
Jan 17 Javascript
JavaScript中URL编码函数代码
Jan 11 Javascript
JS中实现replaceAll的方法(实例代码)
Nov 12 Javascript
js快速排序的实现代码
Dec 08 Javascript
JS动态改变表格边框宽度的方法
Mar 31 Javascript
JavaScript实现为input与textarea自定义hover,focus效果的方法
Aug 21 Javascript
深入剖析JavaScript面向对象编程
Jul 12 Javascript
AngularJS实现表单验证功能详解
Oct 12 Javascript
vue组件jsx语法的具体使用
May 21 Javascript
element表格翻页第2页从1开始编号(后端从0开始分页)
Dec 10 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读取文件内容的三种可行方法示例介绍
2014/02/08 PHP
Linux下 php7安装redis的方法
2018/11/01 PHP
模仿jQuery each函数的链式调用
2009/07/22 Javascript
javascript小数计算出现近似值的解决办法
2010/02/06 Javascript
输入框的字数时时统计—关于 onpropertychange 和 oninput 使用
2011/10/21 Javascript
验证码按回车不变解决方法
2013/03/29 Javascript
jQuery实现简单二级下拉菜单
2015/04/12 Javascript
javascript实现模拟时钟的方法
2015/05/13 Javascript
javascript记住用户名和登录密码(两种方式)
2015/08/04 Javascript
完美实现bootstrap分页查询
2015/12/09 Javascript
AngularJS控制器详解及示例代码
2016/08/16 Javascript
在Docker快速部署Node.js应用的详细步骤
2016/09/02 Javascript
jQuery Mobile漏洞会有跨站脚本攻击风险
2017/02/12 Javascript
nodejs开发微信小程序实现密码加密
2017/07/11 NodeJs
浅谈Vue组件及组件的注册方法
2018/08/24 Javascript
深入学习Vue nextTick的用法及原理
2019/10/08 Javascript
使用 JavaScript 创建并下载文件(模拟点击)
2019/10/25 Javascript
JS实现横向轮播图(中级版)
2020/01/18 Javascript
Javascript生成器(Generator)的介绍与使用
2021/01/31 Javascript
python在linux中输出带颜色的文字的方法
2014/06/19 Python
Python跳出循环语句continue与break的区别
2014/08/25 Python
为Python的web框架编写MVC配置来使其运行的教程
2015/04/30 Python
举例讲解Python中的Null模式与桥接模式编程
2016/02/02 Python
用Django实现一个可运行的区块链应用
2018/03/08 Python
对python中Json与object转化的方法详解
2018/12/31 Python
让你Python到很爽的加速递归函数的装饰器
2019/05/26 Python
Python循环中else,break和continue的用法实例详解
2019/07/11 Python
Python实现JS解密并爬取某音漫客网站
2020/10/23 Python
HTML最新标准HTML5总结(必看)
2016/06/13 HTML / CSS
保加利亚服装和鞋类购物网站:Bibloo.bg
2020/11/08 全球购物
学校消防演习方案
2014/02/19 职场文书
蓝颜请假条
2014/04/11 职场文书
学生无故旷课检讨书
2014/09/20 职场文书
涉外离婚协议书怎么写
2014/11/20 职场文书
Mysql - 常用函数 每天积极向上
2021/04/05 MySQL
解析MySQL binlog
2021/06/11 MySQL