深入探密Javascript数组方法


Posted in Javascript onJanuary 08, 2015

在JavaScript中,数组可以使用Array构造函数来创建,或使用[]快速创建,这也是首选的方法。数组是继承自Object的原型,并且他对typeof没有特殊的返回值,他只返回'object'。

1. Array.prototype.slice方法
数组的 slice 方法通常用来从一个数组中抽取片断。不过,它还有将“类数组”(比如arguments和​HTMLCollection​)转换为真正数组的本领。

 var nodesArr = Array.prototype.slice.call(document.forms);

 var argsArr = Array.prototype.slice.call(arguments);

我就好奇了为什么数组的slice方法有这样的本领,它在javascript引擎中是如何实现的?slice的兄弟方法有没有这样的本领?

带着好奇心,下载Google的V8 javascript引擎源码到本地,V8源码的下载地址:https://github.com/v8/v8。

在v8-master/src/array.js中查找“Array.prototype.slice”:

function ArraySlice(start, end) {

  CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice");

  ...

  var result = []; // 这句是关键

  if (end_i < start_i) return result;

  if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) {

     ...

    SparseSlice(array, start_i, end_i - start_i, len, result);

  } else {

    SimpleSlice(array, start_i, end_i - start_i, len, result);

  }

  ...

  return result;

接着猜想调用“类数组”走的应该是SimpleSlice方法,然后在源码查找“SimpleSlice“,发现Array.prototype.splice源码中也调用了SimpleSlice方法,且结果变量也初始化为空数组。不过,想用splice方法把“类数组”转化为真正数组,必须要传入起始位置参数为0,即:

 var nodesArr = Array.prototype.splice.call(document.forms, 0);

因为它的实现原理就是将被删除的数组项组成新数组。感兴趣的童鞋可以看下Array.prototype.splice的源码实现。
此外,slice还可以克隆一个数组:

 var arr = [1, 2, 3];

 var cloneArr = arr.slice(); // cloneArr:  [1, 2, 3]

2. Array.prototype.push 方法
使用 push方法可以合并数组:

 var arr1 = [1, 'str', {name: 'lang'}];

 var arr2 = [2, 'ing'];

 Array.prototype.push.apply(arr1, arr2);

 // 返回结果:[1, "str", {name: 'lang'}, 2, "ing"]

3. Array.prototype.sort 方法
先上代码:

var arr = ['1', '2', '10', '12'];

arr.sort();

// 返回结果:["1", "10", "12", "2"]

上面的结果通常不是我们想要的,那么如何按数值大小排序:

arr.sort(function(a, b) {

  return a - b;

})

// 返回结果:["1", "2", "10", "12"]

有了排序比较器函数之后,就可以自定义很多比较器,从而实现个性化的排序。

4. length 属性
数组的length属性,不是只读的,也就说还可写哦,比如使用length属性去截断数组:

 var arr = [1, 2, 3, 4];

 arr.length = 2;

 // arr: [1, 2]

 arr.length = 0;

 // arr: []

与此同时,如果把length属性变大,数组的长度值变会增加,且使用undefined来作为新的元素填充。

 var arr = [];

 arr.length = 3;

 // arr: [undefined, undefined, undefined]

好了,今天就总结到这里了,已经凌晨了,以后有什么新发现再append到这里。
之前,没有写博客的习惯,只习惯把平时的总结放到有道云笔记中,没想到把观点写出来着实要花点心思的,因为要考虑如何表达,才能让别人更好地理解。

有什么表达不对或理解错误的地方,还望大家帮忙指正出来。

另附上一些常用的javascript数组方法

concat()连接两个或更多的数组,并返回结果。
join()把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。
pop()删除并返回数组的最后一个元素
push()向数组的末尾添加一个或更多元素,并返回新的长度。
reverse()颠倒数组中元素的顺序。
shift()删除并返回数组的第一个元素
slice()从某个已有的数组返回选定的元素
sort()对数组的元素进行排序
splice()删除元素,并向数组添加新元素。
toSource()返回该对象的源代码
toString()把数组转换为字符串,并返回结果。
toLocaleString()把数组转换为本地数组,并返回结果。
unshift()向数组的开头添加一个或更多元素,并返回新的长度。
valueOf()返回数组对象的原始值

Javascript 相关文章推荐
在JavaScript里防止事件函数高频触发和高频调用的方法
Sep 06 Javascript
js格式化时间小结
Nov 03 Javascript
jquery中$each()方法的使用指南
Apr 30 Javascript
javascript中的五种基本数据类型
Aug 26 Javascript
JS实现仿FLASH效果的竖排导航代码
Sep 15 Javascript
分享使用AngularJS创建应用的5个框架
Dec 05 Javascript
Ext JS框架中日期函数的用法及日期选择控件的实现
May 21 Javascript
使用jquery获取url以及jquery获取url参数的实现方法
May 25 Javascript
获取当前月(季度/年)的最后一天(set相关操作及应用)
Dec 27 Javascript
JavaScript中正则表达式使数字、中文或指定字符高亮显示
Oct 31 Javascript
详解Node.js 中使用 ECDSA 签名遇到的坑
Nov 26 Javascript
小程序实现订单倒计时功能
Apr 23 Javascript
用模版生成HTML的的框架jquery.tmpl使用详解
Jan 07 #Javascript
jQuery中parentsUntil()方法用法实例
Jan 07 #Javascript
jQuery中parents()方法用法实例
Jan 07 #Javascript
jQuery中parent()方法用法实例
Jan 07 #Javascript
jQuery中nextUntil()方法用法实例
Jan 07 #Javascript
jQuery中nextAll()方法用法实例
Jan 07 #Javascript
jQuery中next()方法用法实例
Jan 07 #Javascript
You might like
浅谈php的优缺点
2015/07/14 PHP
JavaScript 参数中的数组展开 [译]
2012/09/21 Javascript
jQuery Pagination Ajax分页插件(分页切换时无刷新与延迟)中文翻译版
2013/01/11 Javascript
JS 修改URL参数(实现代码)
2013/07/08 Javascript
JS实现的一个简单的Autocomplete自动完成例子
2014/04/16 Javascript
a标签click和href执行顺序探讨
2014/06/23 Javascript
node.js开机自启动脚本文件
2014/12/24 Javascript
javascript中call,apply,bind的用法对比分析
2015/02/12 Javascript
javascript实现下班倒计时效果的方法(可桌面通知)
2015/07/10 Javascript
javascript实现网页屏蔽Backspace事件,输入框不屏蔽
2015/07/21 Javascript
jQuery通过改变input的type属性实现密码显示隐藏切换功能
2017/02/08 Javascript
自定义PC微信扫码登录样式写法
2017/12/12 Javascript
javascript trie前缀树的示例
2018/01/29 Javascript
详解如何在vue项目中使用lodop打印插件
2018/09/27 Javascript
Vue从TodoList中学父子组件通信
2019/02/05 Javascript
vue-form表单验证是否为空值的实例详解
2019/10/29 Javascript
[01:28:43]2014 DOTA2华西杯精英邀请赛5 24 DK VS CIS
2014/05/25 DOTA
[01:00:17]DOTA2-DPC中国联赛 正赛 SAG vs Dynasty BO3 第二场 1月25日
2021/03/11 DOTA
Python备份目录及目录下的全部内容的实现方法
2016/06/12 Python
在IPython中执行Python程序文件的示例
2018/11/01 Python
Python3批量生成带logo的二维码方法
2019/06/24 Python
python3使用Pillow、tesseract-ocr与pytesseract模块的图片识别的方法
2020/02/26 Python
keras在构建LSTM模型时对变长序列的处理操作
2020/06/29 Python
基于python模拟TCP3次握手连接及发送数据
2020/11/06 Python
世界排名第一的万圣节服装店:Spirit Halloween
2018/10/16 全球购物
Nisbets法国:英国最大的厨房和餐饮设备供应商
2019/03/18 全球购物
化学教师自荐信范文
2013/12/28 职场文书
《长城》教学反思
2014/02/14 职场文书
党的群众路线教育实践活动公开承诺书
2014/03/28 职场文书
学习之星事迹材料
2014/05/17 职场文书
学习党代会心得体会
2014/09/05 职场文书
我的大学四年规划书范文2014
2014/09/26 职场文书
工作检讨书大全
2015/01/26 职场文书
2015员工年度考核评语
2015/03/25 职场文书
2015年校务公开工作总结
2015/05/26 职场文书
浅谈MySql整型索引和字符串索引失效或隐式转换问题
2021/11/20 MySQL