摘要:從的代理看的代理如何實現(xiàn)的代理方法被攔截。。。對代理的實現(xiàn)要說到的代理實現(xiàn),其中比較有名的就算是的雙向綁定中到了和的代理攔截實現(xiàn)了,下面是一個仿照該技術(shù)的一個實現(xiàn)攔截器可枚舉不能再新的值是的話,進行監(jiān)聽通知訂閱者攔截器的出口
從ES6的Proxy代理看ES5的代理如何實現(xiàn) ES6的Proxy代理
Example
var person = {name:""}; var personCopy = new Proxy(person,{ get(target,key,receiver){ console.log("get方法被攔截。。。"); return Reflect.get(target,key,receiver); }, set(target,key,value,receiver){ console.log("set方法被攔截。。。") return Reflect.set(target,key,value,receiver); } }) person.name = "arvin"; // 未有攔截日志打出 personCopy.name = "arvin"; // set方法被攔截。。。 console.log(person.name); // 未有攔截日志打出 console.log(personCopy.name); // get方法被攔截。。。
代碼解讀:從上述的例子可以看出,被代理對象person的get和set不會經(jīng)過代理攔截器get,set,而只有代理對象personCopy在get和set方法調(diào)用的時候才會經(jīng)過攔截器,由此可見ES6的代理Proxy并不是一個類似JAVA的AOP,而其實只是將person的引用賦值給了personCopy,讓代理對象personCopy和被代理對象person指向了同一個內(nèi)存空間,下面是我實現(xiàn)的一個用ES5寫的Proxy攔截,供大家參考理解Proxy實現(xiàn)原理提供思路:
Example:
/**淺拷貝工具方法**/ function clone(myObj){ if(typeof(myObj) != "object" || myObj == null) return myObj; var newObj = new Object(); for(var i in myObj){ newObj[i] = clone(myObj[i]); } return newObj; } /*代理實現(xiàn)類*/ function ProxyCopy(target,handle){ var targetCopy = clone(target); Object.keys(targetCopy).forEach(function(key){ Object.defineProperty(targetCopy, key, { get: function() { return handle.get && handle.get(target,key); }, set: function(newVal) { handle.set && handle.set(); target[key] = newVal; } }); }) return targetCopy; } var person = {name:""}; var personCopy = new ProxyCopy(person,{ get(target,key){ console.log("get方法被攔截。。。"); return target[key]; }, set(target,key,value){ console.log("set方法被攔截。。。") // return true; } }) person.name = "arvin"; // 未有攔截日志打出 personCopy.name = "arvin"; // set方法被攔截。。。 console.log(person.name); // 未有攔截日志打出 console.log(personCopy.name); // get方法被攔截。。。ES5對Proxy代理的實現(xiàn)
要說到ES5的代理實現(xiàn),其中比較有名的就算是vue的雙向綁定中到了get和set的代理攔截實現(xiàn)了,下面是一個仿照該技術(shù)的一個實現(xiàn):
Example
// 攔截器 function Observer(data) { this.data = data; this.walk(data); } (function($Observer){ $Observer.prototype = { walk: function(data) { var me = this; Object.keys(data).forEach(function(key) { me.convert(key, data[key]); }); }, convert: function(key, val) { this.defineReactive(this.data, key, val); }, defineReactive: function(data, key, val) { var childObj = observe(val); Object.defineProperty(data, key, { enumerable: true, // 可枚舉 configurable: false, // 不能再define get: function() { return val; }, set: function(newVal) { if (newVal === val) { return; } val = newVal; console.log("新的值是object的話,進行監(jiān)聽"); console.log("通知訂閱者"); dep.notify(); } }); } }; })(Observer); // 攔截器的出口 function observe(value) { if (!value || typeof value !== "object") { return; } return new Observer(value); };
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84224.html
摘要:所以整個過程只涉及三個輸入狀態(tài),中間狀態(tài),輸出狀態(tài)關(guān)鍵是是如何生成,如何應(yīng)用修改,如何生成最終的。至此基本把上的模式解析完畢。結(jié)束實現(xiàn)還是相當巧妙的,以后可以在狀態(tài)管理上使用一下。 開始 在函數(shù)式編程中,Immutable這個特性是相當重要的,但是在Javascript中很明顯是沒辦法從語言層面提供支持,但是還有其他庫(例如:Immutable.js)可以提供給開發(fā)者用上這樣的特性,所...
摘要:所以整個過程只涉及三個輸入狀態(tài),中間狀態(tài),輸出狀態(tài)關(guān)鍵是是如何生成,如何應(yīng)用修改,如何生成最終的。至此基本把上的模式解析完畢。結(jié)束實現(xiàn)還是相當巧妙的,以后可以在狀態(tài)管理上使用一下。 開始 在函數(shù)式編程中,Immutable這個特性是相當重要的,但是在Javascript中很明顯是沒辦法從語言層面提供支持,但是還有其他庫(例如:Immutable.js)可以提供給開發(fā)者用上這樣的特性,所...
閱讀 2997·2021-10-19 11:46
閱讀 989·2021-08-03 14:03
閱讀 2949·2021-06-11 18:08
閱讀 2921·2019-08-29 13:52
閱讀 2774·2019-08-29 12:49
閱讀 493·2019-08-26 13:56
閱讀 934·2019-08-26 13:41
閱讀 857·2019-08-26 13:35