前端总结系列

目录

这是《前端总结·基础篇·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 = []  // 声明一个空数组
var arr = [3,6,8,9] // 声明一个包含值3,6,8,9的数组
var arr = new Array(3,6,8,9) // 创建一个数组对象

1.2 访问数组

下标访问

数组的下标是从0开始的,最后一个值的下标是数组长度减去1。访问数组可以直接访问具体下标的一个值,也可以直接访问整个数组的值。


var arr = [1,2,3,4] console.log(arr) // 直接访问数组 | [1, 2, 3, 4]
console.log(arr[0]) // 通过下标访问 | 1
console.log(arr.length) // 访问数组的长度 | 4

遍历访问

如果需要逐个的访问数组中的值,你需要对数组进行遍历。可以用一般的for循环、for in或者ES6中的for of。


var arr = [1,2,3,4] // for
for(var x = 0; x < arr.length; x++){
console.log(arr[x]) // 通过下标访问
} // for in
for(x in arr){
console.log(arr[x]) // 通过下标访问
} // for of (ES6)
for(x of arr){
console.log(x) // 不需要通过下标访问
}

1.3 类型检测

检测一个对象有以下方法。更精确的检测数组请见请见jwalden


* typeof [] // object
* [] instanceof Array // false
* Array.isArray([]) // true | 通常用来检测数组
* Array.isArray(Array.prototype) // true | 这是一个例外情况

二、常用技巧

2.1 数组合并

可以用concat/push合并。concat返回合并后的新数组,push保存在原数组里。

  • 感谢园友 @loveyatou 提醒。在push方法中把apply写成了call,导致结果不符合预期。现已修正。 2017/03/17 13:45

  • PS:call和apply都是用来改变函数作用域的,用法基本一致,唯独传递参数的方法不一致。call是逐个输入,逗号隔开。apply是全部放在一个数组内。


var a = [1,2,3]
var b = [4,5,6] // concat 方法 var c = a.concat(b)
console.log(c) // [1, 2, 3, 4, 5, 6] // push 方法 Array.prototype.push.apply(a,b)
console.log(a) // [1, 2, 3, 4, 5, 6]

2.2 数组深拷贝

我们可以根据concat/slice方法返回新数组的特性来进行深拷贝,也可以直接用循环语句暴力深拷贝。

  • 把数组赋值给一个变量,只是复制了一个指向数组的指针(又叫引用)
  • 当我们改变原数组的值,新数组的值也跟着改变
  • 为了避免这样,你需要对数组进行深拷贝

// 深拷贝前 var arr = [1,2,3,4]
var newArr = arr // 把原数组赋值给新数组 arr.pop() // 删除原数组的一个值
console.log(arr) // 测试原数组的值 [1, 2, 3]
console.log(newArr) // 测试新数组的值 [1, 2, 3] // 深拷贝后 var arr = [1,2,3,4]
var newArrCopy = arr.concat() // 开始深拷贝,此处也可以使用arr.slice() arr.pop() // 删除原数组的一个值
console.log(arr) // 测试原数组的值 [1, 2, 3]
console.log(newArrCopy) // 测试新数组的值 [1, 2, 3, 4] // 暴力深拷贝 var arr = [1,2,3,4]
var newArr = [] // 为了使用数组的push方法,一定要定义数据类型为数组
for (var x = 0; x < arr.length; x++){
newArr.push(arr[x]) // 用循环逐个把值保存在新数组内
} 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

前端兼容性方案

前端总结·基础篇·JS(二)数组深拷贝、去重以及字符串反序和数组(Array)的更多相关文章

  1. 前端总结·基础篇·JS(一)五大数据类型之字符串(String)

    前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(二)补充 前端总结·基础篇·JS(一)五大数据类型之字符串(String) 目录 这是& ...

  2. 前端总结·基础篇·JS(三)arguments、callee、call、apply、bind及函数封装和构造函数

    前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...

  3. 前端总结·基础篇·JS(四)异步请求及跨域方案

    前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...

  4. 前端总结·基础篇·JS(一)原型、原型链、构造函数和字符串(String)

    前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·JS(一)原型.原型链.构造函数和字符串(String) 前 ...

  5. 前端总结·基础篇·CSS(二)视觉

    前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 前端总结·基础篇·CSS(四)兼容 目录 一.动画(animation)(IE ...

  6. 前端总结·基础篇·CSS(一)布局

    目录 这是<前端总结·基础篇·CSS>系列的第一篇,主要总结一下布局的基础知识. 一.显示(display) 1.1 盒模型(box-model) 1.2 行内元素(inline) &am ...

  7. 前端总结·基础篇·CSS(三)补充

    前端总结系列 前端总结·基础篇·CSS(一)布局 前端总结·基础篇·CSS(二)视觉 前端总结·基础篇·CSS(三)补充 目录 一.移动端 1.1 视口(viewport) 1.2 媒体查询(medi ...

  8. 前端总结·基础篇·CSS

    前端总结·基础篇·CSS 1 常用重置+重置插件(Normalize.css,IE8+) * {box-sizing:border-box;}  /* IE8+ */body {margin:0;}  ...

  9. 小猪猪逆袭成博士之C++基础篇(二) 常量、处理类型、自定义头文件

    小猪猪逆袭成博士之C++基础篇(二) const .auto. decltype 上一章我们介绍了一些常用的类型和常见的问题,下面再介绍一些学习的时候不是特别常用但是在实际工程中很有用的一些东西. 一 ...

随机推荐

  1. UWP必备知识:App File Explorer

    由来 应用在手机端出问题时如果查看LocalState文件夹的数据库文件与日志文件 如何查看应用在手机端占用带宽与占用CPU内存情况 介绍 [UWP开发之Mvvmlight实践七:如何查找设备(Mob ...

  2. Form开发:字段关系-消息-快速编码-参数和系统变量

     1.字段关系  清除依赖字段:在挂LOV的名称字段的WHEN-VALIDATE-ITEM调用:app_field.clear_dependent_fields    设置字段依赖:在主字段的WHEN ...

  3. 《JAVASCRIPT高级程序设计》第五章(2)

    一.Date类型 Date类型类型用于保存日期,有以下几种创建方式: //获取当前时间 var now = new Date(); //获取当前时间的毫秒数 var nowSecond = Date. ...

  4. (@WhiteTaken)设计模式学习——工厂方法模式

    这个工厂方法模式,是简单工厂的延伸,不同点在于,将某个具体的类继续细分,将核心部分抽象成一个接口.而简单工厂,把核心写在了一个类上,不利于拓展. 举个例子,简单工厂中有苹果类,香蕉类,我们创建了一个F ...

  5. Canvas + JavaScript 制作图片粒子效果

    首先看一下源图和转换成粒子效果的对比图:       左侧图片为源图,右侧图片为粒子效果图.该效果是在Canvas画布上制作的.将图片制作成粒子效果相对而言是比较简单的.重点了解两个知识点即可 1:图 ...

  6. form表单的两种提交方式,submit和button的用法

    1.当输入用户名和密码为空的时候,需要判断.这时候就用到了校验用户名和密码,这个需要在jsp的前端页面写:有两种方法,一种是用submit提交.一种是用button提交.方法一: 在jsp的前端页面的 ...

  7. ArcGIS快速制图插件介绍

    ArcGIS快速制图插件介绍 By 李远祥 作品背景 <快速制图插件增强版>在原有的<快速制图插件>基础上,加入植被乱序填充.生成立体楼快.等高线增强显示.一键导出地图和数据. ...

  8. Jasmine基础语法

    简介 Jasmine 是JavaScript的测试框架,它不依赖其他框架,也不依赖DOM,更重要的是它语法简单.以下实例都是基于Jasmine 2.5.2的,并且来自官网:https://jasmin ...

  9. HTML学习二

    继续上一次的学习: <html> <head> <title>新增雇员</title> <script language="javasc ...

  10. 第三章:初识Jquery

    一.Jquery的优势 体积小,压缩后只有100KB左右 强大的选择器 出色的DOM封装 可靠的事件处理机制 出色的浏览器兼容性 使用隐式迭代简化编程 丰富的插件支持 二.Jquery语法 三.DOM ...