(撰写中)JavaScript海底两万里:Array和String
争取一文帮自己搞清楚JavaScript中的Array和String。
在算法中,各种复杂的方案往往都基于数组;在业务中,各种复杂的逻辑往往都在加工字符串。
数组
数组可以说是我们接触数据结构和算法时学习的第一种数据结构了,而在JavaScript中,数组作为一种对象,它的能力远超我们对数组朴素的认知。
创建一个空数组有两种方式:
1 | |
或
1 | |
前一种称作字面量的声明方式,后一种则是通过构造方法来创建的。不过在实际应用中很少采用构造方法的形式来创建数组,因为以来不够简洁,二来参数中可以传入数字来创建一定长度的空数组,但每个元素都是undefined,这会带来不安全因素,所以更多还是通过字面量的方式来创建数组。
在声明数组的同时可以在方括号中添加元素,由于JavaScript是动态类型的,这就赋予了JavaScript一个Java没有的能力,你甚至可以在数组中存任意类型:
1 | |
对于很大一部分别的语言,比如C/C++和Java,数组是一个比较单纯的东西,像数组拷贝啊动态长度数组啊之类的概念都是需要开发者手动实现的,而更进一步的数据结构诸如栈和队列,则是基于数组设计的结构。而在JavaScript中,数组拥有很强大的能力,能够直接被当作栈和队列来使用。
作为队列,数组提供这些方法:
psuh在末端添加一个元素shift取出队列首端的第一个元素,整个队列前移。
作为栈,数组提供这些方法:
push在末端添加一个元素pop从末端取出一个元素
对于数组的首端,不仅能够取出元素,自然也能够添加元素:
unshift在首端添加一个元素
所以,JavaScript允许对数组的头尾进行添加或删除的操作,也就很容易实现比如双端队列这样的数据结构。
从性能的角度来说,用于对数组首端操作的shift/unshift性能开销会更大,因为会移动所有的数组元素。
如果要遍历数组,可以通过普通的for循环,这也是运行最快的方式,同时也最自由。当然,自由的代价是开发者需要关注一些细节,比如循环的起始位置,迭代的步长等等,而对于简单的遍历数组所有元素,现代JavaScript提供了for..of语法,可以遍历所有的元素值:
1 | |
数组方法中存在一把瑞士军刀 —— splice方法:
1 | |
splice方法从start开始修改arr:删除deleteCount个元素,在当前位置插入元素elem1, ..., elemN,其返回值为由被删除元素组成的数组。
如果deleteCount为0,则表示在start位置插入元素。
1 | |
如果start为负数,则表示倒数的位置。
1 | |
需要注意,splice方法改变了原来的数组。
slice方法:
1 | |
它返回一个arr中从start到end(不包括end)的元素组成的新数组。
如果start和end为负数则为倒数。
可见方法参数是可选的,所以如果不传参,那就相当于复制arr。
1 | |
concat方法:
1 | |
用于合并多个数组,参数可以是数组或数值,参数数量不限。
这个方法不会修改现有数组,而是返回包含arr本身以及所有参数的新数组。
1 | |
forEach