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 相关文章推荐
jQuery实现form表单reset按钮重置清空表单功能
Dec 18 Javascript
js获取GridView中行数据的两种方法 分享
Jul 13 Javascript
js中判断用户输入的值是否为空的简单实例
Dec 23 Javascript
IE中图片的onload事件无效问题和解决方法
Jun 06 Javascript
jquery提示效果实例分析
Nov 25 Javascript
jQuery中$.click()无效问题分析
Jan 29 Javascript
jquery ajax局部加载方法详解(实现代码)
May 12 Javascript
jQuery操作cookie
Aug 08 Javascript
Node.js中路径处理模块path详解
Nov 14 Javascript
详解Vue2 添加对scss的支持
Jan 02 Javascript
微信小程序以7天为周期连续签到7天功能效果的示例代码
Aug 20 Javascript
解决Antd Table表头加Icon和气泡提示的坑
Nov 17 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程序--记数器
2006/10/09 PHP
PHP 数组入门教程小结
2009/05/20 PHP
php学习笔记之基础知识
2014/11/08 PHP
PHP实现批量上传单个文件
2015/12/29 PHP
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
2016/12/14 PHP
javascript实现的动态添加表单元素input,button等(appendChild)
2007/11/24 Javascript
jquery1.4 教程二 ajax方法的改进
2010/02/25 Javascript
解析window.open的使用方法总结
2013/06/19 Javascript
jquery配合css简单实现返回顶部效果
2013/09/30 Javascript
jquery 合并内容相同的单元格(示例代码)
2013/12/13 Javascript
单击和双击事件的冲突处理示例代码
2014/04/03 Javascript
jQuery实现表格行上下移动和置顶效果
2015/06/05 Javascript
使用AngularJS和PHP的Laravel实现单页评论的方法
2015/06/19 Javascript
js判断某个字符出现的次数的简单实例
2016/06/03 Javascript
剖析Angular Component的源码示例
2018/03/23 Javascript
js中时间格式化的几种方法
2018/07/22 Javascript
vue使用rem实现 移动端屏幕适配
2018/09/26 Javascript
微信小程序功能之全屏滚动效果的实现代码
2018/11/22 Javascript
nodejs对项目下所有空文件夹创建gitkeep的方法
2019/08/02 NodeJs
Python浅拷贝与深拷贝用法实例
2015/05/09 Python
Python使用MONGODB入门实例
2015/05/11 Python
Python2.x利用commands模块执行Linux shell命令
2016/03/11 Python
详解使用pymysql在python中对mysql的增删改查操作(综合)
2017/01/18 Python
PyQt5每天必学之关闭窗口
2018/04/19 Python
python实现排序算法解析
2018/09/08 Python
基于python历史天气采集的分析
2019/02/14 Python
Python实现socket非阻塞通讯功能示例
2019/11/06 Python
基于python的docx模块处理word和WPS的docx格式文件方式
2020/02/13 Python
python爬虫开发之Beautiful Soup模块从安装到详细使用方法与实例
2020/03/09 Python
文化建设工作方案
2014/05/12 职场文书
助人为乐模范事迹材料
2014/06/02 职场文书
党员个人对照检查材料思想汇报
2014/09/16 职场文书
党的群众路线教育实践活动个人整改落实情况汇报
2014/10/28 职场文书
2014年信贷员工作总结
2014/11/18 职场文书
《搭石》教学反思
2016/02/18 职场文书
从零开始在Centos7上部署SpringBoot项目
2022/04/07 Servers