slice
slice 作为动词的中文含义是“切片”
在 JavaScript 中,slice() 方法用于提取出数组的某一段区间 [begin, end)
该方法不改变原数组,而是返回提取后的新数组
注意,若数组元素是对象,只会执行浅拷贝
对于字符串,String.prototype.slice() 的基本用法和规则与 Array.prototype.slice() 相同
splice
splice 作为动词的中文含义则是“拼接”
它有两重功能:
- 从数组中删除掉一个指定区间(改变原数组)
- 允许传入一段新的元素区间,放入删去的位置
总结
| slice | splice | |
|---|---|---|
| 含义 | 切片 | 拼接 |
| 功能简述 | 提取 [begin,end) | 删除一段区间,允许插入替换元素 |
| 改变原数组 | 否 | 是 |
| 返回值 | 浅拷贝得到的新区间 | 删除掉的区间 |
| 字符串同名方法 | 有 | 无 |
在 Vue 数组变化监测中的应用
我们知道,Vue 数组变化侦测的方式是拦截某几个改变数组的方法,具体包括:
const methodsToPatch = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
]
可以看到这里边有 splice 而没有 slice,因为 Vue 只关心改变数组的行为,而 slice 执行的只是 区间选取 + 浅拷贝 的行为,并没有改变原数组
我们还可以再看看拦截数组的具体实现代码
// 源码位置:vue-2.6.14/src/core/observer/array.js
/**
* Intercept mutating methods and emit events
*/
methodsToPatch.forEach(function (method) {
// cache original method
const original = arrayProto[method]
def(arrayMethods, method, function mutator (...args) {
const result = original.apply(this, args)
const ob = this.__ob__
let inserted
switch (method) {
case 'push':
case 'unshift':
inserted = args
break
case 'splice':
inserted = args.slice(2)
break
}
if (inserted) ob.observeArray(inserted)
// notify change
ob.dep.notify()
return result
})
})
可以看到,当对数组执行 push,unshift,splice 方法时,都会(有可能)插入新的元素
当使用 push 和 unshift 方法时,方法参数 args就是要新插入的元素的数组
当我们使用 splice 时,我们会在第三个参数开始传入我们想插入的元素,因此这里的 args.slice(2) 意在提取我们调用 splice() 时传入的第三个到最后一个参数(也就是我们希望插入的新元素)组成的数组