Vue变异数组
我们知道在Vue中是通过Object.defineProperty()来实现数据的响应式,因为它可以很好的监听数据的修改(setter,getter)。
但是对于数组这一数据类型较为特殊,它只能监听到数组本身的变化,而对于数组内的元素变化是无法监听到的,也就是无法实现响应式:
由于 JavaScript 的限制, Vue 不能检测以下变动的数组:
当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength
对于想要实现数组的响应式,也就是在保持原数组不变的前提下延伸数组的方法,官方为我们提供了下面七个方法:
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
至此,我们可以先思考下对于一个普通的方法,如何在保证不改变方法本身的前提下对它进行拓展呢?
看下面的例子:
function original() { console.log("abc"); } const newA = original; original = function () { console.log("def"); newA(); } original(); //expected output:>abc >def
我们设置了原始方法original,它输出的是abc,我们想在不改变这个基本逻辑的前提下,让它再输出def“:
1.缓存原方法;
2.重新定义原方法;
3.在新定义的原方法中调用缓存方法;
在数组中,我们也可以按照这个思路来进行数组的功能扩展:
1.设置一个变量存储原数组的方法:
var oldArray = Array.prototype; var newArray = Object.create(oldArray);
2.重新定义原数组方法:
//需要进行功能扩展的方法 var someMethods={ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' } //遍历重新定义原方法 someMethods.foreach((index,items)=>{ let oldContent = oldArray[items]; newArray = function (...args) { let result = oldContent.apply(this,args); return result; } }
3.调用方法
let arr = []; arr._proto_ = newArray;
学吧,学无止境,太深了