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 相关文章推荐
Prototype 学习 工具函数学习($w,$F方法)
Jul 12 Javascript
将中国标准时间转换成标准格式的代码
Mar 20 Javascript
JS实现关键字搜索时的相关下拉字段效果
Aug 05 Javascript
javascript和jquery实现设置和移除文本框默认值效果代码
Jan 13 Javascript
详解AngularJS中的作用域
Jun 17 Javascript
Bootstrap 附加导航(Affix)插件实例详解
Jun 01 Javascript
angular源码学习第一篇 setupModuleLoader方法
Oct 20 Javascript
ajax分页效果(bootstrap模态框)
Jan 23 Javascript
微信小程序中button组件的边框设置的实例详解
Sep 27 Javascript
VUE前端cookie简单操作
Oct 17 Javascript
Vue不能检测到Object/Array更新的情况的解决
Jun 26 Javascript
vue组件开发props验证的实现
Feb 12 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加MYSQL服务器
2006/10/09 PHP
php一些公用函数的集合
2008/03/27 PHP
APACHE的AcceptPathInfo指令使用介绍
2013/01/18 PHP
PHP中is_dir()函数使用指南
2015/05/08 PHP
利用js获取服务器时间的两个简单方法
2010/01/08 Javascript
Jquery中获取iframe的代码
2011/01/11 Javascript
JavaScript原型继承之基础机制分析
2011/08/26 Javascript
js隐藏与显示回到顶部按钮及window.onscroll事件应用
2013/01/25 Javascript
jquery showModelDialog的使用方法示例详解
2013/11/19 Javascript
JS实现点击颜色块切换指定区域背景颜色的方法
2015/02/25 Javascript
javascript检测两个数组是否相似
2015/05/19 Javascript
深入浅析JavaScript中对事件的三种监听方式
2015/09/29 Javascript
JSON 的正确用法探讨:Pyhong、MongoDB、JavaScript与Ajax
2016/05/15 Javascript
浅谈JavaScript 浏览器对象
2016/06/03 Javascript
微信小程序首页的分类功能和搜索功能的实现思路及代码详解
2018/09/11 Javascript
浅谈vue同一页面中拥有两个表单时,的验证问题
2018/09/18 Javascript
Vue监听一个数组id是否与另一个数组id相同的方法
2018/09/26 Javascript
javascript跳转与返回和刷新页面的实例代码
2019/11/20 Javascript
vue如何实现动态加载脚本
2020/02/05 Javascript
Python实现给qq邮箱发送邮件的方法
2015/05/28 Python
Python中shutil模块的常用文件操作函数用法示例
2016/07/05 Python
对python 匹配字符串开头和结尾的方法详解
2018/10/27 Python
Python图像处理实现两幅图像合成一幅图像的方法【测试可用】
2019/01/04 Python
canvas学习笔记之绘制简单路径
2019/01/28 HTML / CSS
如何提高MySql的安全性
2014/06/19 面试题
电气工程及其自动化学生实习自我鉴定
2013/09/19 职场文书
财务会计实习报告体会
2013/12/20 职场文书
超市重阳节活动方案
2014/02/10 职场文书
小露珠教学反思
2014/04/30 职场文书
本科生自荐信
2014/06/18 职场文书
检讨书模板大全
2015/05/07 职场文书
刑事附带民事起诉状
2015/05/19 职场文书
音乐剧猫观后感
2015/06/04 职场文书
读《人生的智慧》有感:闲暇是人生的精华
2019/12/25 职场文书
MySQL kill不掉线程的原因
2021/05/07 MySQL
详解CSS中的特指度和层叠问题
2021/07/15 HTML / CSS