let arrKeys = ["push", "pop", "shift", "unshift", "splice", "sort", "reverse"];const extendArr = [];接着,就是在extendArr对象上,一一监听arrKeys中的方法了,与$set方法类似,整体结构如下:
!function(){arrKeys.forEach(function(key){proxyObject(extendArr, key, function(){//TODO});});}();注:proxyObject方法其实核心就是Object.defineProperty,详见"模拟Vue之数据驱动3".
!function(){arrKeys.forEach(function(key){proxyObject(extendArr, key, function(){console.log("Fun " + key + " is observed");let result;let arrProto = Array.prototype;let ob = this.$Observer;let arr = arrProto.slice.call(arguments);let inserted;let index;switch(key){case "push": {inserted = arr;index = this.length;break;}case "unshift": {inserted = arr;index = 0;break;}case "splice": {inserted = arr.slice(2);index = arr[0];break;}}result = arrProto[key].apply(this, arguments);if(inserted){inserted.forEach(val => {ob.observe(val);ob.convert(index++, val);});}return result;});});}();最后,就是在需要监听的对象上继承这些变异方法咯,如下:
//observer.jsfunction Observer(data){if(!(this instanceof Observer)){return new Observer(data);}data.__proto__ = extendObj;//继承变异方法push、pop等等if(Array.isArray(data)){data.__proto__.__proto__ = extendArr;}this.data = data;this.walk(data);}好了,一切完毕,接下来就测试下呗:
<script src="./extendObj.js"></script><script src="./observer.js"></script><script>"use strict";let data = {msg: [5, 2, 0],user: {name: "Monkey",age: 24},lover: {name: "Dorie",age: 23}};Observer(data);</script>效果如下:
Perfect,此时,你可能会想,数组方法中仅有push、unshift、splice会为数组新增属性,那么我们又何必将其他方法,例如sort、reverse重写呢,也没发现有什么猫腻呢?
不错,在此时,并没有什么卵用,但是,你要知道sort、reverse等这些方法,可是会引起数组变化的,那么就会影响视图展现,这些变化,又怎么通知数组呢?就是下篇随笔会具体说明的。
该篇随笔代码,详情见github.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。