Proxy 能夠理解成,在目標對象以前架設一層「攔截」,外界對該對象的訪問,都必須先經過這層攔截,所以提供了一種機制,能夠對外界的訪問進行過濾和改寫。Proxy 這個詞的原意是代理,用在這裏表示由它來「代理」某些操做,能夠譯爲「代理器」vue
監視某個對象的屬性讀寫Object.defineProperty (vue3.0以前,3.0以後使用proxy)es6
簡單介紹下 Object.defineProperty
ecmascript
Object.defineProperty(obj,"key",{ enumerable:false, //key屬性是否能夠在for..in || Object.keys()中被枚舉 configurable:false, //key屬性是否可被刪除,以及除 value 和 writable 特性外的其餘特性是否能夠被修改 writable:false, //不可寫入,也就是不可更改obj.key value:undefined, get:undefined, set:undefined })
初始化一個 new Proxy實例函數
const person ={ name:"mcgee", age:18 } //建立proxy構造函數,參數1代理的對象,參數2執行對象 const personProxy = new Proxy(person,{ get(target,property){ // console.log(target,property); //{ name: 'mcgee', age: 18 } name // return 100 //外部訪問屬性的返回值 返回值能夠是任意類型 return property in target ? target[property]:'default' }, set(target,property,value){ // console.log(target,property,value); if(property === "age" && !Number.isInteger(value)){ throw new Error(`${value} is not an int`) } return target[property] == value //返回值能夠是任意類型 } }) console.log(personProxy.name) //100 "mcgee" console.log(personProxy.xxx); //default personProxy.render = true console.log(personProxy); //添加了個render爲true的屬性 // personProxy.age = "aa" //Error: aa is not an int
ES6阮一峯教程代理
靜態類,不能經過 new 構造實例對象,只能調靜態類的靜態方法,相似於Math對象code
內部封裝了一系列對對象的底層操做對象
Reflect成員方法就是Proxy處理對象的默認實現,它的價值,統一提供了一套用於操做對象的API教程
const obj = { name:"mcgee", age:18 } const proxy1 = new Proxy(obj,{ get(target,property){ //若是沒添加get方法,內部默認使用了添加了reflect的方法 return Reflect.get(target,property) } }) console.log(proxy1.name);
//傳統的訪問 console.log("name" in proxy1); console.log(delete obj['age']); console.log(Object.keys(obj)); //使用reflect訪問 Reflect.has(obj,"name") Reflect.deleteProperty(obj,"age") Reflect.ownKeys(obj)