浅谈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脚本 Node.js 使用入门
Mar 07 Javascript
基于jQuery的公告无限循环滚动实现代码
May 11 Javascript
JavaScript NaN和Infinity特殊值 [译]
Sep 20 Javascript
js实现动态添加、删除行、onkeyup表格求和示例
Aug 18 Javascript
ajax提交表单实现网页无刷新注册示例
May 08 Javascript
12306验证码破解思路分享
Mar 25 Javascript
jQuery的Scrollify插件实现滑动到页面下一节点
Jul 05 Javascript
Bootstrap面板使用方法
Jan 16 Javascript
轻松理解JavaScript闭包
Mar 14 Javascript
学习使用Bootstrap栅格系统
May 11 Javascript
Vue.js中组件中的slot实例详解
Jul 17 Javascript
利用JS响应式修改vue实现页面的input值
Sep 02 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
咖啡豆的最常见发酵处理方法,详细了解一下
2021/03/03 冲泡冲煮
类的另类用法--数据的封装
2006/10/09 PHP
PHP连接MySQL的2种方法小结以及防止乱码
2014/03/11 PHP
php框架CI(codeigniter)自动加载与自主创建对象操作实例分析
2020/06/06 PHP
js和jquery中循环的退出和继续学习记录
2014/09/06 Javascript
JavaScript生成SQL查询表单的方法
2015/08/13 Javascript
使用jQuery.form.js/springmvc框架实现文件上传功能
2016/05/12 Javascript
jquery层级选择器(匹配父元素下的子元素实现代码)
2016/09/05 Javascript
前端面试知识点锦集(JavaScript篇)
2016/12/28 Javascript
js,jq,css多方面实现简易下拉菜单功能
2017/05/13 Javascript
Vue 组件(component)教程之实现精美的日历方法示例
2018/01/08 Javascript
详解ES6 系列之异步处理实战
2018/10/26 Javascript
VUE渲染后端返回含有script标签的html字符串示例
2019/10/28 Javascript
Bootstrap table 服务器端分页功能实现方法示例
2020/06/01 Javascript
[01:14]DOTA2亚洲邀请赛 ShowOpen
2015/02/07 DOTA
[01:57]DOTA2上海特锦赛小组赛解说单车采访花絮
2016/02/27 DOTA
[00:12]2018DOTA2亚洲邀请赛SOLO赛 MidOne是否中单第一人?
2018/04/05 DOTA
Python的迭代器和生成器
2015/07/29 Python
使用Python判断质数(素数)的简单方法讲解
2016/05/05 Python
python增加矩阵维度的实例讲解
2018/04/04 Python
Python中GeoJson和bokeh-1的使用讲解
2019/01/03 Python
python实现爬取百度图片的方法示例
2019/07/06 Python
Pandas-Cookbook 时间戳处理方式
2019/12/07 Python
详解canvas绘制网络字体几种方法
2019/08/27 HTML / CSS
佐卡伊官网:中国知名珠宝品牌
2017/02/05 全球购物
莱德杯高尔夫欧洲官方商店:Ryder Cup Shop
2019/08/14 全球购物
网络方面基础面试题
2012/11/16 面试题
应届生程序员求职信
2013/11/05 职场文书
四年大学生活的个人自我评价
2013/12/11 职场文书
捐资助学感谢信
2015/01/21 职场文书
建党伟业电影观后感
2015/06/01 职场文书
初中班主任培训心得体会
2016/01/07 职场文书
2019企业给员工的慰问信
2019/06/24 职场文书
pytorch 6 batch_train 批训练操作
2021/05/28 Python
Oracle安装TNS_ADMIN环境变量设置参考
2021/11/01 Oracle
详解nginx安装过程并代理下载服务器文件
2022/02/12 Servers