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 相关文章推荐
Jquery ajax执行顺序 返回自定义错误信息(实例讲解)
Nov 06 Javascript
iScroll中事件点击触发两次解决方案
Mar 11 Javascript
深入解析Javascript闭包的功能及实现方法
Jul 10 Javascript
jQuery 3.0中存在问题及解决办法
Jul 15 Javascript
AngularJS 输入验证详解及实例代码
Jul 28 Javascript
纯js实现倒计时功能
Jan 06 Javascript
jQuery+koa2实现简单的Ajax请求的示例
Mar 06 jQuery
vue3.0 CLI - 2.3 - 组件 home.vue 中学习指令和绑定
Sep 14 Javascript
探秘vue-rx 2.0(推荐)
Sep 21 Javascript
vue路由守卫及路由守卫无限循环问题详析
Sep 05 Javascript
JS中FormData类实现文件上传
Mar 27 Javascript
Vue数据双向绑定原理实例解析
May 15 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
Joomla数据库操作之JFactory::getDBO用法
2016/05/05 PHP
IE 上下滚动展示模仿Marquee机制
2009/12/20 Javascript
js各种验证文本框输入格式(正则表达式)
2010/10/22 Javascript
Jquery知识点二 jquery下对数组的操作
2011/01/15 Javascript
jQuery 选择表格(table)里的行和列及改变简单样式
2012/12/15 Javascript
js形成页面的一种遮罩效果实例代码
2014/01/04 Javascript
jquery 获取 outerHtml 包含当前节点本身的代码
2014/10/30 Javascript
jQuery插件bgStretcher.js实现全屏背景特效
2015/06/05 Javascript
javascript实现图片上传前台页面
2015/08/18 Javascript
jQuery实现鼠标悬停背景翻转的黑色导航菜单代码
2015/09/14 Javascript
分享两段简单的JS代码防止SQL注入
2016/04/12 Javascript
jquery输入数字随机抽奖特效的简单实现代码
2016/06/10 Javascript
Bootstrap3多级下拉菜单
2017/02/24 Javascript
JS生成随机打乱数组的方法示例
2017/12/23 Javascript
Vue在页面数据渲染完成之后的调用方法
2018/09/11 Javascript
vue解决跨域问题(推荐)
2020/11/10 Javascript
python的re模块应用实例
2014/09/26 Python
python使用post提交数据到远程url的方法
2015/04/29 Python
Python 基础教程之str和repr的详解
2017/08/20 Python
详解python基础之while循环及if判断
2017/08/24 Python
django认证系统实现自定义权限管理的方法
2018/07/16 Python
详解pandas库pd.read_excel操作读取excel文件参数整理与实例
2019/02/17 Python
简单了解Django应用app及分布式路由
2019/07/24 Python
如何用Python编写一个电子考勤系统
2021/02/08 Python
使用CSS3来匹配横屏竖屏的简单方法
2015/08/04 HTML / CSS
彪马美国官网:PUMA美国
2017/03/09 全球购物
Vans奥地利官方网站:美国原创极限运动潮牌
2018/09/30 全球购物
现代化办公人员工作的自我评价
2013/10/16 职场文书
前台文员岗位职责
2013/12/28 职场文书
考察邀请函范文
2015/01/31 职场文书
2016年学校“3.12”植树节活动总结
2016/03/16 职场文书
导游词之无锡华莱坞
2019/12/02 职场文书
Qt自定义Plot实现曲线绘制的详细过程
2021/11/02 Python
springboot入门 之profile设置方式
2022/04/04 Java/Android
零基础学java之带参数以及返回值的方法
2022/04/10 Java/Android
Python实现数据的序列化操作详解
2022/07/07 Python