前言
在 js 数组方法中,有七个方法对数组进行操作会直接改变原数组,就是这七个:
push、pop、shift、unshift、splice、sort、reverse。我们都知道vue2.x中是通过Object.defineProperty实现数据的响应式,但是Object.definePropety方法是不能直接操作原数组的,比如如果使用这七个方法去改变原数组,改变之后的数据并不会实现响应式,所以vue2.x是对数组这七个方法做了重写的,实际上你调用的这几个方法并不是原生的,而且vue2.x重写的方法。那就让我们来看看这几个方法的作用吧。
1.push
向数组的末尾添加一个或更多元素,并返回新的长度。改变原数组。这个方法应该是数组中常用的一个之一,这个方法类似栈中的
入栈。
let arr = [1,2,3];
// 向数组末尾添加一个 4,原数组arr 变成 [1,2,3,4],并且返回新数组的长度:n = 4
let n = arr.push(4);
// arr 还可以传入多个参数,会按照顺序依次 push 到数组末尾
// 向数组 [1,2,3,4] 添加 1,2,3,4,原数组arr变成[1,2,3,4,1,2,3,4],返回新数组长度:m = 8
let m = arr.push(...arr);
console.log(arr); // [1,2,3,4,1,2,3,4]
console.log(n); // 4
console.log(m); // 8
2.pop
删除并返回数组的最后一个元素。改变原数组。这个方法类似栈中的
出栈
let arr = [1,2,3];
// 删除并返回该数组中的最后一个元素,原数组arr变成[1,2]; cur: 3
let cur = arr.pop();
console.log(arr); // [1,2]
console.log(cur); // 3
- 使用
push和pop实现类似栈的行为: 后进先出
// 栈是行为就类似咱们生活中的叠盘子,先放进去的最后拿出来
let arr = [];
arr.push(1); // [1]
arr.push(2); // [1,2]
arr.push(3); // [1,2,3]
arr.pop(); // 3
arr.pop(); // 2
arr.pop(); // 1
3.shift
删除并返回数组的第一个元素。改变原数组。
let arr = [1,2,3];
// 删除并返回该数组中的第一个元素,原数组变成 [2,3]; n: 1
let n = arr.shift();
console.log(arr); // [2,3]
console.log(n); // 1
4.unshift
向数组的开头添加一个或更多元素,并返回新的长度。改变原数组。
let arr = [1,2,3];
// 向原数组的开头添加一个4并返回新数组的长度, 原数组变为 [4,1,2,3]; n: 4
let n = arr.unshift(4);
// 向原数组的开头添加 4,1,2,3,并返回新数组的长度,原数组变为[4,1,2,3,4,1,2,3]; m: 8
let m = arr.unshift(...arr);
console.log(arr); // [4,1,2,3,4,1,2,3]
console.log(n); // 4
console.log(m); // 8
5.splice
用于删除、添加或者替换数组中的某些元素; 返回被删除或被替换元素组成的数组。改变原数组。 用法
// howmany 和 item 都是可选
// howmany 没传就是删除从 index 开始到原数组结尾的所有元素
// item 没传就是删除后不往删除的位置里添加元素
arr.splice(index, [howmany], [...item])
- 1.删除数组中的某些元素
let arr = [1,2,3,4];
// 从原数组的下标为 2 开始,删除length - 2个元素,原数组变成 [1,3];返回 [3,4]
// 这里 arr.splice(2) 等价于 arr.splice(2, arr.length - 2)
let m = arr.splice(2);
console.log(arr); // [1,2]
console.log(m); // [3,4]
- 2.删除数组中的某些元素并替换成新的元素
let arr = [1,2,3,4];
let arr1 = [1,2,3];
// 原数组从下标为 1开始,删除两个元素,并且在删除的位置添加 1,2,3,原数组变成 [1,1,2,3,4];返回 [2,3]
let newArr = arr.splice(1,2, ...arr1);
console.log(arr); // [1,1,2,3,4]
console.log(newArr); // [2,3]
- 3.更新数组中的某一个元素
let arr = [1,2,3,4];
// 原数组从下标2开始,删除一个元素,并且在 2 下标的为添加 8,来达到一个更新数组中的一个元素
let newArr = arr.splice(2, 1, 8);
console.log(arr); // [1,2,8,4]
console.log(newArr); // [3]
- 4.当指定的开始下标(index)不存在时,会在原数组的末尾添加一个或多个新元素,此时它的作用和
push一样。
let arr = [1,2,3,4];
// 下标 6 不存在,往数组末尾添加 9,删除的元素为空,所以返回空数组
let n = arr.splice(6,1,9);
console.log(arr); // [1,2,3,4,9]
console.log(n); // []
6.sort
对数组的元素进行排序并返回排序后的数组。改变原数组。
- 基本使用
let arr = [1,5,3,7,6];
let n = arr.sort();
console.log(arr); // [1, 3, 5, 6, 7]
console.log(n); // [1, 3, 5, 6, 7]
再看下面一个例子
let arr = [6,8,1,30,5];
arr.sort();
console.log(arr); // [1, 30, 5, 6, 8]
看着上面排序的结果是不是感觉和奇怪,并不是自己想像的结果。其实数组的sort方法当没有参数传入的时候,其排序顺序默认为,将待排序数据转换为字符串,并按照Unicode序列排序;所以这里sort默认的排序并不是按照值来排序,想要实现值的排序就需要传入一个比较函数了。该函数比较两个值的大小,然后返回一个用于说明这两个值的相对顺序的数字。具体是排序原理是用的 v8 引擎里的插入排序和快速排序,v8引擎排序源码。当数组长度小于等于10的时候,采用插入排序,大于10的时候,采用快排。
比较函数有两个参数 a 和 b,其返回值如下:
若 a 小于 b,即 a - b 小于零,则返回一个小于零的值,数组将按照升序排列。
若 a 等于 b,则返回 0,数组顺序不变。
若 a 大于 b, 即 a - b 大于零,则返回一个大于零的值,数组将按照降序排列。
let arr = [1,5,3,7,6];
arr.sort((a,b) => 0);
console.log(arr); // [1, 5, 3, 7, 6]
arr.sort((a,b) => a - b);
console.log(arr); // [1, 3, 5, 6, 7]
arr.sort((a,b) => b - a);
console.log(arr); // [7, 6, 5, 3, 1]
7.reverse
反转数组中元素的顺序并返回新数组。改变原数组。
let arr = [3,8,7,6];
let newArr = arr.reverse();
console.log(arr); // [6, 7, 8, 3]
console.log(newArr); // [6, 7, 8, 3]