前端总结系列
- 前端总结·基础篇·CSS(一)布局
- 前端总结·基础篇·CSS(二)视觉
- 前端总结·基础篇·CSS(三)补充
- 前端总结·基础篇·JS(一)原型、原型链、构造函数和字符串(String)
- 前端总结·基础篇·JS(二)数组深拷贝、去重以及字符串反序和数组(Array)
目录
这是《前端总结·基础篇·JS》系列的第二篇,主要总结一下JS数组的使用、技巧以及常用方法。
一、数组使用
1.1 定义数组
1.2 使用数组
1.3 类型检测
二、常用技巧
2.1 数组去重
2.2 数组深拷贝
2.3 字符串反序
三、方法列表
3.1 存取
3.2 字符串
3.3 修改
3.4 ES5
3.5 ES2015(ES6)
3.6 ES2016
一、数组使用
数组不是基本数据类型,但是非常常用,所以提前总结。
基本数据类型是String,Number,Boolean,null,undefined。
- Boolean只有两个状态,true/false
- null一般是开发者定义
- undefined是JS引擎抛出的异常,通常在发现调用未声明的变量时抛出
1.1 定义数组
数组用中括号括起来,不同的值用逗号隔开。数组内的值有字符串需要用单引号或者双引号引起来。
var arr = [3,6,8,9] // 直接定义数组并且赋值给变量
var arr = new Array(3,6,8,9) // 创建一个数组对象并赋值
1.2 使用数组
数组的下标是从0开始的,最后一个值的下标是数组长度减去1。访问数组可以直接访问具体下标的一个值,也可以直接访问整个数组的值。
console.log(arr) // 直接访问数组
console.log(arr[0]) // 通过下标访问
console.log(arr.length) // 访问数组的长度
/* 使用for in遍历访问数组中的值 */
for(x in arr){
console.log(arr[x])
}
ES6
/* 使用for of遍历访问数组中的值 */
for(x in arr){
console.log(x)
}
1.3 类型检测
检测一个对象有以下方法。更精确的检测数组请见请见jwalden
* typeof [] // object
* [] instanceof Array // false
* Array.isArray([]) // true 通常用来检测数组
* Array.isArray(Array.prototype) // true 这是一个例外情况
二、常用技巧
2.1 数组合并
用concat方法进行数组合并。
var a = [1,2,3]
var b = [4,5,6]
Array.prototype.push.call(a,b)
console.log(a) // [1, 2, 3, 4, 5, 6]
2.2 数组深拷贝
我们可以根据concat/slice方法返回新数组的特性来进行深拷贝。
var arr = [1,2,3,4]
var newArr = arr.concat() // 此处使用arr.slice()效果一致
arr.pop()
console.log(arr) // [1, 2, 3]
console.log(newArr) // [1, 2, 3, 4]
2.3 数组去重
排序后去重,更多请见脚本之家
var newArr = arr.sort() // 排好序再比较
var newArrSaved = [newArr[0]] // 初始化为数组,用来存储最后的数据
for(var i =2;i<arr.length;i++){ // 从第二个开始
if(newArr[i]!==newArr[i-1]) // 判断当前值和上一个值是否一致
newArrSaved.push(newArr[i]) // 不一致则存在newArrSaved
}
2.4 字符串反序
首先将字符串序列化成数组,通过数组方法对数组反序,最后把数组转换成字符串。
'I See U.'.split('').reverse().join('') // ".U eeS I"
三、方法列表
ES5和ES6部分就当作参考手册吧,有时间再琢磨一下应用场景。
以下实例在此基础上进行
arr = [1,2,3,4]
3.1 存取
push在尾部添加,pop从尾部删除。
尾存取
push(element1, ..., elementN)
* arr.push(8) // [1, 2, 3, 4, 5]
pop()
* arr.pop() // [1, 2, 3, 4]
首存取
unshift在首部添加,shift从首部删除。
unshift(element1, ..., elementN)
* arr.unshift(5) // [5, 1, 2, 3, 4]
shift
* arr.shift() // [1, 2, 3, 4]
3.2 转换
字符串
join默认以逗号分隔连接的字符串,传入参数可以进行自定义分割方式。
toString()
* arr.toString() // "1,2,3,4"
toLocalString()
* arr.toLocalString() // 和上面的效果一致,此方法仅在特殊语言中需要
join(separator)
* arr.join() // "1,2,3,4"
* arr.join('') // "1234"
* arr.join('-') // "1-2-3-4"
3.3 修改
排序
reverse把数组颠倒,sort对数组排序。sort默认按照unicode排序,传入function(a,b)可以自定义排序。更多请见MDN(内有对象按属性值排序的方法)
reverse()
* arr.reverse() // [4, 3, 2, 1]
sort()
* arr.sort() // [1, 2, 3, 4] 这个已经排好了序,所以不变
连接
concat连接数组,并返回一个新的数组。
concat(value1[, value2[, ...[, valueN]]])
arr.concat(9) // [1, 2, 3, 4, 9]
切割
切割比上面的稍微复杂点
-
slice为提取元素,splice为删除指定范围元素并添加新元素。slice的第二个参数,是结束的位置标记,不会包括在返回值内。
-
slice的返回值是提取元素组成的新数组。splice的返回值是删除元素组成的新数组,原始元素被修改。
-
slice在IE<9下使用时,会出现一些问题,需要使用腻子脚本。详见MDN
slice(begin,end)
* arr.slice(1,3) // [2, 3]
splice(start, deleteCount, item1, item2, ...)
* arr.splice(1,3,5) // [2, 3, 4] 返回值
* console.log(arr) // [1, 5] 原始元素被修改
3.4 ES5
需要精确检测数组请见jwalden
数组检查
Array.isArray(obj) // 检查是否为数组,返回值为true/false,兼容IE9+
* Array.isArray([1,2,3]) // true
* Array.isArray('123') // false
* Array.isArray(Array.prototype) // true
arr.every(callback[, thisArg])
* function isNotZero(element, index, array){return element!==0}
* arr.every(isNotZero) // true
arr.map(callback[, thisArg]) // 每个值都调用一次函数并且返回新数组
* function twice(element, index, array){return element*element}
* arr.map(twice) // [1, 4, 9, 16]
arr.reduce(callback,[initialValue]) // 将多维数组转为一维数组
arr.some(callback[, thisArg]) // 测试元素是否通过指定测试
arr.indexOf(searchElement[, fromIndex = 0]) // 返回满足条件的第一个索引,不存在返回-1
* arr.indexOf(3) // 2
arr.lastIndexOf(searchElement[, fromIndex = arr.length - 1]) // 由后向前查找
arr.forEach(callback[, thisArg]) // 对数组每个元素执行一次函数
3.5 ES2015(ES6)
Array.of(element0[, element1[, ...[, elementN]]]) // 创建新数组
* Array.of(3) // [3]
* Array(3) // [undefined × 3]
* Array.of([1,2,3]) // [Array[3]]
* Array([1,2,3]) // [Array[3]]
Array.from(arrayLike[, mapFn[, thisArg]]) // 从类数组对象或可遍历对象中创建数组
* Array.from('berg') // ["b", "e", "r", "g"]
arr.copyWithin(target, start, end) // 选定数组值,在一定范围内全部粘贴选定值
* arr.copyWithin(1,2,3) // [1, 3, 3, 4]
arr.entries() // 返回新的数组迭代器(一定得复制给变量再迭代)
* var newArr = arr.entries()
* newArr.next().value // [0, 1]
* newArr.next().value // [1, 2]
* newArr.next().value // [2, 3]
* newArr.next().value // [3, 4]
arr.keys() // 返回新的数组迭代器
arr.fill(value, start, end) // 用指定值填充一定范围数组
* arr.fill(0,1,3) // [1, 0, 0, 4]
arr.filter(callback[, thisArg]) // 将满足条件的元素返回成新数组
* function isNotZero(element){return element!==0}
* arr.filter(isNotZero) // [1, 2, 3, 4]
arr.find(callback[, thisArg]) // 返回满足条件的第一个值,不存在返回undefined
* function isNotZero(element){return element!==0}
* arr.find(isNotZero) // 1
arr.findIndex(callback[, thisArg]) // 返回满足条件的第一个元素的索引
* function isNotZero(element){return element!==0}
* arr.findIndex(isNotZero) // 0
3.6 ES2016
arr.includes(searchElement, fromIndex) // 判断数组是否包含指定值,返回true/false
arr.includes(2) // true
总结
- 上一周一直在忙活Note这个小项目,现在已经上线了。以后会逐步增大项目复杂度。并且尝试用Vue和RN来分别对项目进行重构,后端则逐步接入Node.js和mongoDB。兼容性支持IE9及以上,根据IE7/8访客基数决定是否兼容。
- 接下来的时间就安心的总结JS和更博客吧。关于Note开发过程中遇到的问题,以及解决方案,等整理好了再发出来。
文章主要参考的站点
ES5
前端兼容性方案