JavaScript 数组
数组是一种使用整数作为键 (integer-key-ed) 属性 和长度 (length) 属性 之间关联的常规对象。此外,数组对象还继承了 Array.prototype 的一些操作数组的便捷 方法 。——MDN
数组可以存放多个值。数组的 数 不是指数字,而是指 数据 ,数组可以存放任意数据类型的值。
从理论上讲,在内存允许的情况下,数组的长度是无限的。
1. 创建数组
数组由中括号 [] 包裹,每一项之间用逗号 , 分隔。
[ 第一项 , 第二项 , 第三项 , ... , 第n项 ]
创建数组最常见的方式是使用字面量。
var hobby = [ 'java' , 'c' , 'c++' , 'python' , 'javascript' , , , , true , false ] ; console . log ( hobby ) ;
通过直接描述 一个 数组的方式就可以创建 一个 数组。
2. 数组长度
数组的长度可以通过 length 属性 获取 。
var arr = [ , , , , ] ; console . log ( arr . length ) ; // 5
3. 访问数组成员
数组的每一项可以称之为 成员 。
数组成员可以通过 下标 访问,下标也可以称为 索引 。
下标可以理解成数组成员的编号,编号从 0 开始,到数组长度 -1 。
var arr = [ '第一项' , '第二项' , '第三项' ] ; var item1 = arr [ ] ; // 从0开始编号 第一项的下标是0 var item2 = arr [ ] ; var item3 = arr [ ] ; console . log ( item1 ) ; // 输出 :第一项 console . log ( item2 ) ; // 输出 :第二项 console . log ( item3 ) ; // 输出 :第三项
通过 数组[下标] 的方式即可访问到成员。
4. 遍历数组
数组遍历主要有两种方式:
for 循环 forEach 方法
4.1 for 循环
使用 for 循环,从数组下标 0 循环到最后一位,过程中通过下标访问成员。
var arr = [ '第一项' , '第二项' , '第三项' , '第四项' , '第五项' ] ; var i , len ; for ( i = , len = arr . length - ; i <= len ; i ++ ) { console . log ( arr [ i ] ) ; }@H_334_ 404 @4.2 forEach 方法
forEach 是数组原型上的 方法 ,所有数组都具有此 方法 。
forEach 接收 一个 函数 作为参数,在遍历每一项的时候,这个 函数 会被 调用 ,同时将当前遍历到的项、当前项的下标(索引)、遍历的数组作为 函数 参数传递过来。
var arr = [ '第一项' , '第二项' , '第三项' , '第四项' , '第五项' ] ; arr . forEach ( function ( item , index , arr ) { console . log ( '第' + ( index + ) + '项的值是:' + item ) ; } ) ;
第二个参数的值也是从 0 开始的。
通常第三个参数用到的比较少,没有用到可以没必要接收这个参数。
5. 修改 数组成员的值
成员的值可以通过 数组[下标] = 值 的方式进行 修改 。
var arr = [ '一' , '三' , '三' , '四' ] ; console . log ( arr [ ] ) ; // 输出 :"三" arr [ ] = '二' ; console . log ( arr [ ] ) ; // 输出 :"二"
6. 增减数组项
数组提供了很多方式来对成员进行增减操作,也可以依靠其他特性来 增加 减少数组成员。
6.1 增加
6.1.1 直接给指定位置赋值
通过下标,直接访问到 一个 不存在的成员,然后进行赋值,就可以为数组 增加 一项。
var arr = [ 'jquery' , 'react' ] ; arr [ ] = 'vue' ; arr [ ] = 'angular' ; console . log ( arr [ ] ) ; // 输出 :"angular" console . log ( arr . length ) ; // 输出 :36.1.2 push 方法
push 方法 接收任意个参数,这些参数会依次 添加 到数组的末尾, 添加 完后返回数组新的长度。
var arr = [ ] ; var length = arr . push ( , ) ; console . log ( arr ) ; // 输出 :[1, 2, 3] console . log ( length ) ; // 输出 :3
通常不会用到这个返回的长度,可以不需要接收返回值。
6.1.3 unshift 方法
unshift 接收任意个参数,这些参数会被 添加 到数组头部, 添加 完后返回数组新的长度。
var arr = [ ] ; var length = arr . unshift ( , ) ; console . log ( arr ) ; // 输出 :[1, 2, 3] console . log ( length ) ; // 输出 :3
6.2 删除
6.2.1 pop 方法
pop 方法 会 删除 数组最后一项,并将 删除 项作为返回值。
var arr = [ 'c++' , 'java' , 'javascript' ] ; var lastOne = arr . pop ( ) ; console . log ( lastOne ) ; // 输出 :"javascript"
如果数组是空的, 调用 pop 会返回 undefined 。
@H_ 419 _886@6.2.2 shift 方法
shift 方法 会 删除 数组的第一项,并将 删除 项作为返回值。
var arr = [ '996' , '007' ] ; const f irs t = arr . shift ( ) ; console . log ( f irs t ) ; // 输出 :"996"
与 pop 一样,如果是数组为空的情况下,会返回 undefined 。
6.3 在数组中间 删除 或 添加 值
splice 方法 可以在任意位置 添加 或 删除 值。
这个 方法 接受任意个参数,前两个为从哪里开始(从 0 开始计数), 删除 几个,从第三个开始则是要 添加 的项。
arr . splice ( 从第几个开始 , 要 删除 几个 , 要 添加 的项目 , 要 添加 的项目 , ... , 要 添加 的项目n ) ;
如果不需要 删除 ,只需要往数组中间插入值,只需要传递 0 给第二个参数即可。
// 在第二项之后插入3, 4, 5 var arr = [ , , ] ; arr . splice ( , , , , ) ;
因为第 一个 参数是从 0 开始计数,所以在第二项之后,就是要插入在第三项的位置,所以传递 2 ,不需要 删除 项目,所以第二个参数传递 0 ,之后就是要插入的项。
注意:往数组中间插入数据的情况相对较少,数组做这种操作是比较低效的,小量的操作对 性能 的影响可以忽略不计,但有超大量非首尾的增减操作,应考虑使用 链表 。
删除 项只需要指定从第几项开始 删除 ,要 删除 几项即可。
// 去除 '996'、'加班' var arr = [ '早睡早起' , '朝九晚五' , '996' , '加班' ] ; arr . splice ( , ) ;
'996’和’加班’是连续的,所以 一个 splice 就可以 删除 掉这 2 项,2 个参数的意思就是从第 2 项开始, 删除 2 项。
7. 清空数组
将数组所有成员全部 删除 就达到了清空的 效果 。
var arr = [ , , , ] ; arr . splice ( , arr . length ) ;
当然也可以使用 pop 一个 个 删除 ,但是通常都不会用这种方式。
清空数组最常用的方式是重新给变量赋值。
var arr = [ 'red' , 'green' , 'blur' ] ; arr = [ ] ; console . log ( arr ) ; // 输出 空数组:[]
通过给变量赋值 一个 新的空数组,达到清空数组的目的,但是这样会改变引用,新赋值的数组和之前的数组并不是同 一个 。
另一种方式可以让保持对当前数组的引用。
var arr = [ 'yellow' , 'black' ] ; arr . length = ;
通过给数组的 length 属性 重新赋值,也可以达到清空数组的 效果 。
这种方式相对灵活,假如需求是保留三项、五项,只需要给 length 赋值对应的值即可。
8. 使用 Array 创建数组
内建对象 Array 也可以用来创建数组。
var arr = new Array ( ) ;
如果什么参数都不传递,则返回 一个 空数组。
传参则有 2 种情况:
如果只传 一个 参数,并且这个参数的类型为数字,则会创建长度为这个数字的数组; 传入其他类型的 一个 或者多个参数,则会将这些参数组合成数组。
var arr = new Array ( ) ; console . log ( arr ) ; // 输出 :[empty × 10] console . log ( arr . length ) ; // 输出 :10
在控制台可以观察到这个数组长度为 10,但均为 empty 。
如果尝试着访问其中某一项,得到的值是 undefined 。
var arr1 = new Array ( 'item1' ) ; var arr2 = new Array ( , , 'item3' ) ; console . log ( arr1 ) ; // 输出 :["item1"] console . log ( arr2 ) ; // 输出 :[1, 2, "item3"]
这样创建的数组,成员与传参一致。
9. 数组中的 undefined 与 empty
在数组中 undefined 与 empty 是有区别的。
使数组项变成 empty 通常有两种方式。
使用 Array 对象同时提供了长度创建出来的数组 使用 delete 关键字 删除 的数组项
var arr1 = new Array ( ) ; arr1 [ ] = ; var arr2 = [ , , , , ] ; delete arr2 [ ] ; console . log ( arr1 ) ; console . log ( arr2 ) ;
虽然 empty 的项在访问的时候返回的是 undefined ,但其本身只做简单占位,\ 是遍历不到的。
var arr = [ , undefined , , , ] ; delete arr [ ] ; arr . forEach ( function ( item , index ) { console . log ( index , item ) ; } ) ; var i = ; for ( i in arr ) { console . log ( i , arr [ i ] ) ; }
上面两种遍历的方式都是遍历不到 empty 项的,而 undefined 是可以遍历到的,这是最主要的区别。
10. 使用数组
数组非常常用,大量的 HTML 字符串在做拼接的时候,就会使用到数组。
除了用于简单的存储数据,数组也可以被用来 解决 问题。
10.1 判断括号是否匹配
判断 一个 数学式子的括号匹配是否合法,如 (1 + 2) * (3 + 4)) ,这个式子就是不合法的。
校验括号合法不单单要看左括号和右括号的 数量 是否相等,还要看括号的顺序, ))(( 这样的括号顺序一定是 错误 的。
利用 JavaScript 数组的特性,可以很容易的实现。
// 空数组 var stack = [ ] ; // 一个 式子 var equation = '(1 + (2 - 3) * 4) / (1 - 3)' ; var i , len ; for ( i = , len = equation . length ; i < len ; i ++ ) { if ( equation [ i ] === '(' ) { // 如果碰到左括号 // 往数组里放个1 stack . push ( ) ; } else if ( equation [ i ] === ')' ) { // 如果碰到右括号 if ( ! stack . length ) { // 判断数组长度,如果是0,则肯定是出错的,数组长度0的时候说明没有左括号,没有左括号是不可能出现右括号的 // 随便放 一个 1 stack . push ( ) ; break ; } // 如果数组不是空的 就从数组末尾拿 一个 走。 stack . pop ( ) ; } } // 判断数组长度 if ( ! stack . length ) { // 如果数组已经空了,说明括号都一一对应,式子里的括号没问题。 console . log ( '括号合法' ) ; } else { console . log ( '括号不合法' ) ; }
使用数组实现的具体思路就是,碰到左括号就往数组里放 一个 成员,碰到 一个 右括号就拿掉 一个 成员。
这样如果最后有剩下,说明括号没有一一成对。
(1+2*(3+4))*1 如这样 一个 式子:
初始化操作: 定义数组 arr为空 从式子第 一个 字符开始循环 第一次循环: 数组的值为 [] 得到字符"(" 判断是左括号,往数组里放 一个 1,表示碰到了左括号 第二次循环 数组的值为 [1] 得到字符"+" 既不是左括号,又不是右括号,进行下一轮循环,不做操作 第三次循环 第四次循环 第五次循环 与第二次循环基本一致 第六次循环 数组的值为 [1] 得到字符"(" 是左括号 往数组里再放 一个 1,表示碰到了左括号 第七次循环 数组值为 [1, 1] 得到字符"3" 不是左括号,也不是右括号,进行下一轮循环 第八次循环 第九次循环 与第七次一致 第十次循环 数组的值为 [1, 1] 得到字符")" 是右括号,从数组末尾拿掉一项 第十一次循环 数组的值为 [1] 得到字符")" 是右括号,从数组末尾拿掉一项 第十二次循环 第十三次循环 数组值为 [] 都不是括号,不做操作 循环结束 判断数组值,如果是空的,说明括号匹配完了,显然 (1+2*(3+4))*1 是合法的
当然这种判断有局限性,假如碰到 ((1+)2)-3 这种非括号造成不合法的式子,就判断不出来了。
其实这里用到了 栈 这种数据结构,这个问题在栈的应用上很经典,是算法入门常见面试题之一。
11. 类数组
类数组并不是数组,而是长得像数组的对象。
var fakeArray = { : '第一项' , : '第二项' , : '第三项' , length : , } ; console . log ( fakeArray [ ] ) ; // 输出 :"第一项" console . log ( fakeArray . length ) ; // 输出 :3
上述例子中的 fakeArray 就是 一个 类数组, 属性 是以类型数组的 下标 的形式存在,同时也具有 length 属性 。
这种类数组对象,也被称为 array-like对象 ,部分文献也称为 伪数组 。
类数组对象可以转化为数组,许多 方法 在设计时也会考虑 支持 类数组。
12. 小结
JavaScript 中的数组非常灵活,可以存放任意类型、任意长度 (内存足够的情况下) 的数据,其下标从 0 开始,最大到数组长度减去 1 ,并提供了一系列 方法 ,来完成增、删、改、查操作。
数组项的 empty 和 undefined 的区别,是面试中常问的问题。
JavaScript switch 语句 ? ?JavaScript 数字声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did92411