1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| class DeepProxy { constructor (target, handler) { this._preproxy = new WeakMap() this._handler = handler return this.deepProxy(target, []) }
deepProxy (obj, path) { for (let key of Object.keys(obj)) { if (typeof obj[key] === 'object') { obj[key] = this.deepProxy(obj[key], [...path, key]) } } let p = new Proxy(obj, this.makeHandler(path)) this._preproxy.set(p, obj) return p }
deleteProxy (obj, key) { if (this._preproxy.has(obj[key])) { obj[key] = this._preproxy.get(obj[key]) this._preproxy.delete(obj[key]) } for (let k of Object.keys(obj[key])) { if (typeof obj[key][k] === 'object') { this.deleteProxy(obj[key], k) } } }
makeHandler (path) { return { set: (target, key, value, receiver) => { if (typeof value === 'object') { value = this.deepProxy(value, [...path, key]) } target[key] = value if (this._handler.set) { this._handler.set(target, [...path, key], value, receiver) } return true }, get: (target, key, value, receiver) => { if (!Reflect.has(target, key)) { target[key] = this.deepProxy({}, [...path, key]) } if (this._handler.get) { this._handler.get(target, [...path, key], value, receiver) } return target[key] }, deleteProperty: (target, key) => { if (Reflect.has(target, key)) { this.deleteProxy(target, key) const deleted = Reflect.deleteProperty(target, key) if (deleted && this._handler.deleteProperty) { this._handler.deleteProperty(target, [...path, key]) } return deleted } return false } } } }
|