JavaScript 数组详解


Posted in Javascript onOctober 10, 2013

在程序语言中数组的重要性不言而喻,JavaScript中数组也是最常使用的对象之一,数组是值的有序集合,由于弱类型的原因,JavaScript中数组十分灵活、强大,不像是Java等强类型高级语言数组只能存放同一类型或其子类型元素,JavaScript在同一个数组中可以存放多种类型的元素,而且是长度也是可以动态调整的,可以随着数据增加或减少自动对数组长度做更改。

创建数组

在JavaScript多种方式创建数组

构造函数

1.无参构造函数,创建一空数组

var a1=new Array();

2.一个数字参数构造函数,指定数组长度(由于数组长度可以动态调整,作用并不大),创建指定长度的数组

var a2=new Array(5);

3.带有初始化数据的构造函数,创建数组并初始化参数数据

var a3=new Array(4,'hello',new Date());

字面量

1.使用方括号,创建空数组,等同于调用无参构造函数

var a4=[];

2.使用中括号,并传入初始化数据,等同于调用调用带有初始化数据的构造函数

var a5=[10];

注意点

1.在使用构造函数创建数组时如果传入一个数字参数,则会创建一个长度为参数的数组,如果传入多个,则创建一个数组,参数作为初始化数据加到数组中

var a1=new Array(5);
            console.log(a1.length);//5
            console.log(a1); //[] ,数组是空的
            var a2=new Array(5,6);
            console.log(a2.length);//2
            console.log(a2); //[5,6]

但是使用字面量方式,无论传入几个参数,都会把参数当作初始化内容

var a1=[5];
            console.log(a1.length);//1
            console.log(a1); //[5]
            var a2=[5,6];
            console.log(a2.length);//2
            console.log(a2); //[5,6]

2.使用带初始化参数的方式创建数组的时候,最好最后不要带多余的”,”,在不同的浏览器下对此处理方式不一样

var a1=[1,2,3,];
console.log(a1.length);
console.log(a1);

这段脚本在现代浏览器上运行结果和我们设想一样,长度是3,但是在低版本IE下确实长度为4的数组,最后一条数据是undefined

数组的索引与长度

数组的值可以通过自然数索引访问进行读写操作,下标也可以是一个得出非负整数的变量或表达式

var a1=[1,2,3,4];
console.log(a1[0]); //1
var i=1;
console.log(a1[i]); //2
console.log(a1[++i]); //3

数组也是对象,我们可以使用索引的奥秘在于,数组会把索引值转换为对应字符串(1=>”1”)作为对象属性名

console.log(1 in a1);//true,确实是一个属性
索引特殊性在于数组会自动更新length属性,当然因为JavaScript语法规定数字不能作为变量名,所以我们不能显示使用array.1这样的格式。由此可见其实负数,甚至非数字”索引“都是允许的,只不过这些会变成数组的属性,而不是索引

var a=new Array(1,2,3);
            a[-10]="a[-10]";
            a["sss"]="sss";

JavaScript 数组详解

这样我们可以看出所有的索引都是属性名,但只有自然数(有最大值)才是索引,一般我们在使用数组的时候不会出现数组越界错误也正是因为此,数组的索引可以不是连续的,访问index不存在的元素的时候返回undefined

var a=new Array(1,2,3);
            a[100]=100;
            console.log(a.length); //101
            console.log(a[3]); //undefined
            console.log(a[99]); //undefined
            console.log(a[100]); 100

JavaScript 数组详解

上面的例子中,虽然直接对a[100]赋值不会影响a[4]或a[99],但数组的长度却受到影响,数组length属性等于数组中最大的index+1,我们知道数组的length属性同样是个可写的属性,当强制把数组的length属性值设置为小于等于最大index值时,数组会自动删除indexd大于等于length的数据,在刚才代码中追加几句

a.length=2
console.log(a);//[1,2]

这时候会发现a[2]和a[100]被自动删除了,同理,如果把length设置为大于最大index+1的值的时候,数组也会自动扩张,但是不会为数组添加新元素,只是在尾部追加空空间

a.length=5;
console.log(a); //[1,2] //后面没有3个undefined

元素添加/删除

基本方法

上面例子已经用到向数组内添加元素方法,直接使用索引就可以(index没必要连续)

var a=new Array(1,2,3);
a[3]=4;
console.log(a);//[1, 2, 3, 4]

前面提到数组也是对象,索引只是特殊的属性,所以我们可以使用删除对象属性的方法,使用delete 删除数组元素

delete a[2];
console.log(a[2]); //undefined

这样和直接把a[2]赋值为undefined类似,不会改变数组长度,也不会改变其他数据的index和value对应关系

JavaScript 数组详解

栈方法

上面例子总有同学就发现了,尤其是其删除方法,并不是我们希望的表现形式,我们很多时候希望删除中间一个元素后,后面元素的index都自动减一,数组length同时减一,就好像在一个堆栈中拿去的一个,数组已经帮我们做好了这种操作方式,pop和push能够让我们使用堆栈那样先入后出使用数组

var a=new Array(1,2,3);
            a.push(4);
            console.log(a);//[1, 2, 3, 4] 
            console.log(a.length);//4
            console.log(a.pop(a));//4
            console.log(a); //[1, 2, 3] 
            console.log(a.length);//3

队列方法

既然栈方法都实现了,先入先出的队列怎么能少,shift方法可以删除数组index最小元素,并使后面元素index都减一,length也减一,这样使用shift/push就可以模拟队列了,当然与shift方法对应的有一个unshift方法,用于向数组头部添加一个元素

var a=new Array(1,2,3);
            a.unshift(4);
            console.log(a);//[4, 1, 2, 3] 
            console.log(a.length);//4
            console.log(a.shift(a));//4
            console.log(a); //[1, 2, 3] 
            console.log(a.length);//3

终极神器

JavaScript提供了一个splice方法用于一次性解决数组添加、删除(这两种方法一结合就可以达到替换效果),方法有三个参数

1.开始索引

2.删除元素的位移

3.插入的新元素,当然也可以写多个

splice方法返回一个由删除元素组成的新数组,没有删除则返回空数组

var a=new Array(1,2,3,4,5);

删除

指定前两个参数,可以使用splice删除数组元素,同样会带来索引调整及length调整

var a=new Array(1,2,3,4,5);
            console.log(a.splice(1,3));//[2, 3, 4] 
            console.log(a.length);//2
            console.log(a);//[1,5]

如果数组索引不是从0开始的,那么结果会很有意思,有一这样数组

var a=new Array();
        a[2]=2;
        a[3]=3;
        a[7]=4;
        a[8]=5;

JavaScript 数组详解

console.log(a.splice(3,4)); //[3] 
        console.log(a.length); //5
        console.log(a); //[2: 2, 3: 4, 4: 5]

JavaScript 数组详解

上面例子可以看到,splice的第一个参数是绝对索引值,而不是相对于数组索引,第二个参数并不是删除元素的个数,而是删除动作执行多少次,并不是按数组实际索引移动,而是连续移动。同时调整后面元素索引,前面索引不理会

插入与替换

只要方法第二个参数,也就是删除动作执行的次数设为0,第三个参数及以后填写要插入内容就splice就能执行插入操作,而如果第二个参数不为0则变成了先在该位置删除再插入,也就是替换效果

var a=new Array(1,2,3,4,5);
       a.splice(1,0,9,99,999);
       console.log(a.length); //8
       console.log(a);//[1, 9, 99, 999, 2, 3, 4, 5] 
       a.splice(1,3,8,88,888);
       console.log(a.length);//8
       console.log(a);//[1, 8, 88, 888, 2, 3, 4, 5]

常用方法

join(char)

这个方法在C#等语言中也有,作用是把数组元素(对象调用其toString()方法)使用参数作为连接符连接成一字符串

var a=new Array(1,2,3,4,5);
       console.log(a.join(',')); //1,2,3,4,5 
       console.log(a.join(' ')); //1 2 3 4 5
slice(start,end)

不要和splice方法混淆,slice

var a=new Array(1,2,3,4,5);
            console.log(a); //[1, 2, 3, 4, 5] 
            console.log(a.slice(1,2));//
            console.log(a.slice(1,-1));//[2, 3, 4] 
            console.log(a.slice(3,2));//[]
            console.log(a); //[1, 2, 3, 4, 5]

方法用于返回数组中一个片段或子数组,如果只写一个参数返回参数到数组结束部分,如果参数出现负数,则从数组尾部计数(-3意思是数组倒第三个,一般人不会这么干,但是在不知道数组长度,想舍弃后n个的时候有些用,不过数组长度很好知道。。。。,好纠结的用法),如果start大于end返回空数组,值得注意的一点是slice不会改变原数组,而是返回一个新的数组。

concat(array)

看起来像是剪切,但这个真不是形声字,concat方法用于拼接数组,a.concat(b)返回一个a和b共同组成的新数组,同样不会修改任何一个原始数组,也不会递归连接数组内部数组

var a=new Array(1,2,3,4,5);
            var b=new Array(6,7,8,9);
            console.log(a.concat(b));//[1, 2, 3, 4, 5, 6, 7, 8, 9] 
            console.log(a); //[1, 2, 3, 4, 5] 
            console.log(b); //[6, 7, 8, 9]
reverse()

方法用于将数组逆序,与之前不同的是它会修改原数组

var a=new Array(1,2,3,4,5);
            a.reverse();
            console.log(a); //[5, 4, 3, 2, 1]

同样,当数组索引不是连续或以0开始,结果需要注意

var a=new Array();
        a[2]=2;
        a[3]=3;
        a[7]=4;
        a[8]=5;

JavaScript 数组详解

a.reverse();

JavaScript 数组详解

sort

sort方法用于对数组进行排序,当没有参数的时候会按字母表升序排序,如果含有undefined会被排到最后面,对象元素则会调用其toString方法,如果想按照自己定义方式排序,可以传一个排序方法进去,很典型的策略模式,同样sort会改变原数组。

var a=new Array(5,4,3,2,1);
       a.sort();
       console.log(a);//[1, 2, 3, 4, 5]

但是。。。

var a=new Array(7,8,9,10,11);
       a.sort();
       console.log(a);//[10, 11, 7, 8, 9]

因为按照字母表排序,7就比10大了,这时候我们需要传入自定义排序函数

var a=new Array(7,8,9,10,11);
           a.sort(function(v1,v2){
            return v1-v2;
           });
       console.log(a);//[7, 8, 9, 10, 11]

原理和C#中的sort类似(.NET Framework 中的设计模式——应用策略模式为List排序),只不过可以直接传递方法进去,以下内容纯属猜测

sort内部使用快速排序,每次比较两个元素大小的时候如果没有参数,则直接判断字母表,如果有参数,则把正在比较的两个参数传入自定义方法并调用(正在比较的两个数会传给自定义方法的v1、v2),如果返回值大于0表示v1>v2,如果等于0,表示v1=v2,如果小于0,表示v1<v2,其实我们传入的方法就是告诉sort怎么比较两个元素谁大谁小,至于排序移动元素过程人家写好了,猜测结束。

最后
了解了这些看看数组真的很了不得啊,即强大有灵活,但是在遍历元素,及获取元素位置等也有一定的不便,这些在ECMAScript中已经得到解决,熟练使用可以让我们的JavaScript优雅而高效。

Javascript 相关文章推荐
javascript StringBuilder类实现
Dec 22 Javascript
js中parseFloat(参数1,参数2)定义和用法及注意事项
Jan 27 Javascript
Javascript中实现String.startsWith和endsWith方法
Jun 10 Javascript
javascript比较两个日期相差天数的方法
Jul 24 Javascript
jQuery实现文件上传进度条特效
Aug 12 Javascript
详解Angular2响应式表单
Jun 14 Javascript
关于jQuery.ajax()的jsonp碰上post详解
Jul 02 jQuery
vue 数组和对象不能直接赋值情况和解决方法(推荐)
Oct 25 Javascript
js实现简单模态框实例
Nov 16 Javascript
JavaScript之Blob对象类型的具体使用方法
Nov 29 Javascript
vue中 this.$set的使用详解
Nov 17 Vue.js
webpack介绍使用配置教程详解webpack介绍和使用
Jun 25 Javascript
js导出table数据到excel即导出为EXCEL文档的方法
Oct 10 #Javascript
Jquery attr(&quot;checked&quot;) 返回checked或undefined 获取选中失效
Oct 10 #Javascript
Javascript Web Slider 焦点图示例源码
Oct 10 #Javascript
JS实现程序暂停与继续功能代码解读
Oct 10 #Javascript
js切换光标示例代码
Oct 10 #Javascript
jquery获取div距离窗口和父级dv的距离示例
Oct 10 #Javascript
jquery中常用的SET和GET$(”#msg”).html循环介绍
Oct 09 #Javascript
You might like
php使用websocket示例详解
2014/03/12 PHP
[原创]PHP实现SQL语句格式化功能的方法
2017/07/28 PHP
laravel 数据验证规则详解
2019/10/23 PHP
25个非常棒的jQuery滑块插件和教程小结
2011/09/02 Javascript
分享9个最好用的JavaScript开发工具和代码编辑器
2015/03/24 Javascript
jQuery实现滚动切换的tab选项卡效果代码
2015/08/26 Javascript
实例解析JS布尔对象的toString()方法和valueOf()方法
2015/10/25 Javascript
数据结构中的各种排序方法小结(JS实现)
2016/07/23 Javascript
Backbone View 之间通信的三种方式
2016/08/09 Javascript
Node.js的环境安装配置(使用nvm方式)
2016/10/11 Javascript
windows 下安装nodejs 环境变量设置
2017/02/02 NodeJs
node.js中axios使用心得总结
2017/11/29 Javascript
详解如何给React-Router添加路由页面切换时的过渡动画
2019/04/25 Javascript
react PropTypes校验传递的值操作示例
2020/04/28 Javascript
python利用不到一百行代码实现一个小siri
2017/03/02 Python
详解Python中where()函数的用法
2018/03/27 Python
基于python绘制科赫雪花
2018/06/22 Python
python实现文本进度条 程序进度条 加载进度条 单行刷新功能
2019/07/03 Python
PyTorch之图像和Tensor填充的实例
2019/08/18 Python
Python中的__init__作用是什么
2020/06/09 Python
CSS3 Media Queries(响应式布局可以让你定制不同的分辨率和设备)
2013/06/06 HTML / CSS
html2canvas截图空白问题的解决
2020/03/24 HTML / CSS
德国汉莎航空中国官网: Lufthansa中国
2017/03/30 全球购物
欧舒丹美国官网:L’Occitane美国
2018/02/23 全球购物
爱奇艺VIP会员:大剧抢先看
2018/07/11 全球购物
美国电力供应商店/电气批发商:USESI
2018/10/12 全球购物
写一个方法1000的阶乘
2012/11/21 面试题
程序员机试试题汇总
2012/03/07 面试题
大学生水果店创业计划书
2014/01/28 职场文书
校园十大歌手策划书
2014/02/01 职场文书
畜牧兽医本科生的自我评价
2014/03/03 职场文书
三好学生事迹材料
2014/12/24 职场文书
离婚代理词范文
2015/05/23 职场文书
毕业实习感受与体会
2015/05/26 职场文书
小学教师见习总结
2015/06/23 职场文书
cypress测试本地web应用
2022/06/01 Javascript