浅谈Javascript数组的使用


Posted in Javascript onJuly 29, 2015

上一篇说了数组的索引,这一篇说下数组的使用。

数组的大小

js的数组可以动态调整大小,更确切点说,它没有数组越界的概念,a[a.length]没什么问题。比如声明一个数组a = [1, 3, 5],现在的数组大小是3,最后一个元素的索引是2,但是你依然可以使用a[3],访问a[3]返回的是undefined,给a[3]赋值:a[3] = 7,是给数组a添加了一个元素,现在数组a的长度是4了。你可以试试把下面这段代码放到浏览器里运行下:

var a = [];
  for(int i = 0; i <= a.length; i++)
  {
    a[a.length] = i;
  }

在我的电脑上,火狐会立马崩掉,chrome这一个标签cpu占用99%(使用chrome的任务管理器查看的)。

js的length的值会随着数组元素的改变而改变,当然你也可以手动设置数组的 length 属性,设置更大的length不会给数组分配更多的空间,但是设置更小的length则会导致所有下标大于等于新length的属性被删除。

另外有一点就是,数组的length值是怎么来的,有的资料说是最大一个数字索引值加一,应该是对的,不过如果把空槽也算数的话,length值就是数组的元素数。上张图解释下:

浅谈Javascript数组的使用

从图里可以看到,有个数组a,a[0]和a[10]都已赋值,这时候a的length是11,中间有9个empty slot(姑且就翻译为空槽好了)。那这九个空槽算不算数呢,我觉得应该算,这样就能合理的解释length值了。那这些空槽的值是什么呢?undefined!所以呢,如果在chrome里,使用foreach遍历(forin),那么这些空槽正好都能跳过,而使用for遍历,则会打印出undefined。至于在firefox里,表现不太一样,自己试吧。

数组的遍历

昨天在看微博上转的js教程的时候,里面说在遍历数组的时候,判断语句i<a.length会造成每循环一次都要计算一次长度,从而对性能有一点点影响。这一点我表示疑问,我不确定到底是不是这样,而且不同的浏览器对这种情况可能还有不同的优化,我在网上搜了下,找到了几个网页说了要缓存数组大小,但是都是抄的,没主见,也没说明原理,所以我表示很怀疑,而且我在chrome测试了下,性能上没什么明显差异。关键是我觉得,length是个数组的属性,每次调用a.length的时候,只是访问这个属性而已,属性都是用hash的方式存储的,所以访问的时间复杂度是O(1)。这是我的看法,如果不对,请告诉我。

关于数组的foreach遍历,js的方式相对于java/c#等语言是很奇怪的:

for(var name in ['huey', 'dewey', 'louie']) {
      console.log(name);
    }
    /*
      打印结果:
      0
      1
      2
    */

可以看到,打印的结果不是数组的元素,而是数字索引值(感觉这好像也可以说明,js的数组也是用hash的方式存储的),不管怎样,这一点要注意。(至于为什么这样,我觉得数组元素都是数组的属性,这个遍历是遍历的length值,从0到length。而不是逐个输出数组的元素,因为元素是属性,数组又不只数字索引这一种属性,那么为什么这样遍历的时候只输出它们呢,而不是length,push,join等方法?公平起见,只好输出数组的数字索引了。当然,这只是我自己的看法,具体怎么样我没研究。)

数组的一些方法

数组有push和pop方法,这样数组就像堆栈一样了。对数组使用delete,可以将数组中某个元素移除,但是那样会在数组中留下一个空洞(也就是说delete也可以删除数组中的元素,但是只是删除该位置的值,不改变数组大小,原位置类型是undefined),这是因为排在被删除元素之后的元素保留着它们最初的属性,所以应该使用splice对进行过delete操作的数组进行瘦身,它会将被删除的属性移除,但这样效率并不是很高。数组中还有map、reduce、filter等方法,这里就不多说了(跟python中的list挺像的)。

补充

最后补充一点,我前面说过,js中的数组就是对象(废话,本来就是对象),那么是不是说,数组和对象可以互相互替换着用呢?答案是可以的。不过为了明确,还是分开用比较好,下面说下什么时候该用数组,什么时候该用对象(参考《javascript语言精粹》):

当属性名是小而连续的整数时,应该使用数组,否则,使用对象。
另外由于js中对数组和对象使用 typeof 的结果都是 Object,因此判断一个对象是否为数组的方法:

var is_array = function(value) {
  return Object.prototype.toString.apply(value) === '[object Array]';
  };

番外

觉得闭包被神化了,可能语言层面上的实现有技术,但是在应用层面我觉得就应该那样啊,使用的时候都感觉不到那是在用闭包。但是这个闭包却几乎成了面试前端必问的概念了。

以上所述就是本文的全部内容了,希望大家能够喜欢。

Javascript 相关文章推荐
阻止JavaScript事件冒泡传递(cancelBubble 、stopPropagation)
May 08 Javascript
js字符串转成JSON
Nov 07 Javascript
javascript通过className来获取元素的简单示例代码
Jan 10 Javascript
JavaScript怎么判断图片是否加载完成以便获取其尺寸
May 08 Javascript
javascript使用switch case实现动态改变超级链接文字及地址
Dec 16 Javascript
JavaScript中的setUTCDate()方法使用详解
Jun 11 Javascript
React-intl 实现多语言的示例代码
Nov 03 Javascript
基于滚动条位置判断的简单实例
Dec 14 Javascript
React精髓!一篇全概括小结(急速)
May 23 Javascript
js与jquery获取input输入框中的值实例讲解
Feb 27 jQuery
jQuery 添加元素和删除元素的方法
Jul 15 jQuery
js实现简单的无缝轮播效果
Sep 05 Javascript
举例讲解Node.js中的Writable对象
Jul 29 #Javascript
浅谈Javascript数组索引
Jul 29 #Javascript
JQ实现新浪游戏首页幻灯片
Jul 29 #Javascript
JavaScript中几种排序算法的简单实现
Jul 29 #Javascript
详解JavaScript中数组的相关知识
Jul 29 #Javascript
javascript+canvas实现刮刮卡抽奖效果
Jul 29 #Javascript
js实现登陆遮罩效果的方法
Jul 28 #Javascript
You might like
php面向对象全攻略 (十五) 多态的应用
2009/09/30 PHP
php下保存远程图片到本地的办法
2010/08/08 PHP
php获取json数据所有的节点路径
2015/05/17 PHP
PHP根据树的前序遍历和中序遍历构造树并输出后序遍历的方法
2017/11/10 PHP
PHP小程序支付功能完整版【基于thinkPHP】
2019/03/26 PHP
ThinkPHP5+UEditor图片上传到阿里云对象存储OSS功能示例
2019/08/05 PHP
php实现断点续传大文件示例代码
2020/06/19 PHP
不懂JavaScript应该怎样学
2008/04/16 Javascript
jquery复选框CHECKBOX全选、反选
2008/08/30 Javascript
基于jQuery的简单的列表导航菜单
2011/03/02 Javascript
JS 无限级 Select效果实现代码(json格式)
2011/08/30 Javascript
js动态添加事件并可传参数示例代码
2013/10/21 Javascript
JS中获取函数调用链所有参数的方法
2015/05/07 Javascript
表单验证正则表达式实例代码详解
2015/11/09 Javascript
jQuery+CSS3+Html5实现弹出层效果实例代码(附源码下载)
2016/05/16 Javascript
JavaScript遍历Json串浏览器输出的结果不统一问题
2016/11/03 Javascript
JavaScript组成、引入、输出、运算符基础知识讲解
2016/12/08 Javascript
微信小程序实现顶部普通选项卡效果(非swiper)
2020/06/19 Javascript
javaScript中的空值和假值
2017/12/18 Javascript
react 创建单例组件的方法
2018/04/26 Javascript
Vue中使用better-scroll实现轮播图组件
2020/03/07 Javascript
[01:28:56]2014 DOTA2华西杯精英邀请赛 5 24 CIS VS DK
2014/05/26 DOTA
Python isinstance判断对象类型
2008/09/06 Python
Python基于百度云文字识别API
2018/12/13 Python
python实现贪吃蛇游戏
2020/03/21 Python
End Clothing美国站:英国男士潮牌商城
2018/04/20 全球购物
Dower & Hall官网:英国小众轻奢珠宝品牌
2019/01/31 全球购物
法国房车租赁网站:Yescapa
2019/08/26 全球购物
介绍下Java中==和equals的区别
2013/09/01 面试题
个人存款证明书
2014/10/18 职场文书
刑事和解协议书范本
2014/11/19 职场文书
如果用一句诗总结你的上半年,你会用哪句呢?
2019/07/16 职场文书
导游词之杭州岳王庙
2019/11/13 职场文书
使用python向MongoDB插入时间字段的操作
2021/05/18 Python
Pytorch 如何加速Dataloader提升数据读取速度
2021/05/28 Python
SQL实现LeetCode(177.第N高薪水)
2021/08/04 MySQL