「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」。
vue2的实现(7)之数组劫持的考量
回顾
- 上次内容我们处理了一个问题,我们把
_data属性代理到了vm上,这样我们在取值的时候,就不需要从vm._data上取值了,只需要从vm上取值就可以了。下面是实现代码。 rewrite-vue/src/state.jsimport {observe} from './observe' export function initState(vm) { const opts = vm.$options if (opts.data) { initData(vm) } } function initData(vm) { let data = vm.$options.data data = typeof data === 'function'? data.call(vm) : data vm._data = data proxy(vm, '_data') observe(data) } function proxy(vm, target){ for(let key in vm[target]){ Object.defineProperty(vm,key,{ get(){ return vm[target][key] }, set(newValue){ vm[target][key] = newValue } }) } }
数组劫持的考量
-
我们用下面的代码测试一下,在浏览器打开
rewrite-vue/dist/index.html。 -
rewrite-vue/dist/index.html<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue2</title> </head> <body> <script src="./vue.js"></script> <script> const vm = new Vue({ data:{ name:'vue2', age: { num:666, key:'age' }, arr:[1, 2, 3, 4, 5, 6, 7, 8, 9] } }) </script> </body> </html> -
打开浏览器的控制台,我们对
vm.arr做截取操作,vm.arr.splice(0,1)从第0个位置开始,截取1个元素。数组也是对象类型的数据,所以也会经过obser方法,循环遍历每个属性。我们对数据做截取操作,数组默认后面的元素,都会往前移一位,从下面的图片可以看到,我们截取了第一位,但是后面的每一个元素都会往前移动一位,所以后面的每个元素的get与set方法都会触发,数组的第0个元素成了2。 -
可想而知,当我们数组的长度很长的话,我们每次有改变原素组索引的操作,都会引起大量的
get与set方法执行,这样的话性能会很不好。 -
回想我们对数组的操作,其实还是使用数组的原型上的方法比较多,直接通过索引的方式去操作数组的情况还是较少的。
-
我们数组的方法中,其中改变原数组的方法有七个,分别是
push unshift pop shift splice sort revers,所以Vue中对于数组的劫持主要还是通过重写数组原型上的方法来实现的。
往期精彩
今天是更文第十三天加油~
看到这里兄弟帮忙点个赞吧