深入探密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 相关文章推荐
jQuery 源码分析笔记(7) Queue
Jun 19 Javascript
js中设置元素class的三种方法小结
Aug 28 Javascript
JavaScript控制listbox列表框的项目上下移动的方法
Mar 18 Javascript
微信小程序开发之入门实例教程篇
Mar 07 Javascript
通过源码分析Vue的双向数据绑定详解
Sep 24 Javascript
JS排序算法之希尔排序与快速排序实现方法
Dec 12 Javascript
在vue中读取本地Json文件的方法
Sep 06 Javascript
Intellij IDEA搭建vue-cli项目的方法步骤
Oct 20 Javascript
微信小程序用户位置权限的获取方法(拒绝后提醒)
Nov 15 Javascript
微信小程序扫描二维码获取信息实例详解
May 07 Javascript
vue实现PC端录音功能的实例代码
Jun 05 Javascript
解决Vue调用springboot接口403跨域问题
Sep 02 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和MySql来与ODBC数据连接
2006/10/09 PHP
php递归使用示例(php递归函数)
2014/02/14 PHP
PHP+Mysql实现多关键字与多字段生成SQL语句的函数
2014/11/05 PHP
利用PHP生成静态html页面的原理
2016/09/30 PHP
magento后台无法登录解决办法的两种方法
2016/12/09 PHP
Thinkphp3.2简单解决多文件上传只上传一张的问题
2017/09/26 PHP
php数据结构之顺序链表与链式线性表示例
2018/01/22 PHP
Laravel 微信小程序后端搭建步骤详解
2019/11/26 PHP
Jquery 数据选择插件Pickerbox使用介绍
2012/08/24 Javascript
Jquery post传递数组方法实现思路及代码
2013/04/28 Javascript
javascript原型模式用法实例详解
2015/06/04 Javascript
jquery控制页面的展开和隐藏实现方法(推荐)
2016/10/15 Javascript
js canvas实现擦除效果示例代码
2017/04/26 Javascript
EasyUI的TreeGrid的过滤功能的解决思路
2017/08/08 Javascript
JavaScript中附件预览功能实现详解(推荐)
2017/08/15 Javascript
Bootstrap实现翻页效果
2017/11/27 Javascript
微信小程序 slot踩坑的解决
2019/04/01 Javascript
Vue中keep-alive 实现后退不刷新并保持滚动位置
2020/03/17 Javascript
Vue项目利用axios请求接口下载excel
2020/11/17 Vue.js
JavaScript async/await原理及实例解析
2020/12/02 Javascript
Python实现朴素贝叶斯分类器的方法详解
2018/07/04 Python
Django REST framework视图的用法
2019/01/16 Python
Python unittest框架操作实例解析
2020/04/13 Python
python实现在线翻译
2020/06/18 Python
解决TensorFlow调用Keras库函数存在的问题
2020/07/06 Python
python 多线程共享全局变量的优劣
2020/09/24 Python
CSS3中设置3D变形的transform-style属性详解
2016/05/23 HTML / CSS
请解释接口的显式实现有什么意义
2012/05/26 面试题
幼儿园教师培训方案
2014/02/04 职场文书
马智宇婚礼主持词
2014/03/22 职场文书
大专生求职信
2014/06/29 职场文书
个人对照检查剖析材料
2014/10/13 职场文书
五年级上册复习计划
2015/01/19 职场文书
聚众斗殴罪辩护词
2015/05/21 职场文书
纪委立案决定书
2015/06/24 职场文书
标枪加油稿
2015/07/22 职场文书