Proxy,Reflect

Proxy

Proxy 能夠理解成,在目標對象以前架設一層「攔截」,外界對該對象的訪問,都必須先經過這層攔截,所以提供了一種機制,能夠對外界的訪問進行過濾和改寫。Proxy 這個詞的原意是代理,用在這裏表示由它來「代理」某些操做,能夠譯爲「代理器」vue

監視某個對象的屬性讀寫Object.defineProperty (vue3.0以前,3.0以後使用proxy)es6

  • 簡單介紹下 Object.definePropertyecmascript

    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

    具體13個方法例子詳見此處es5

ES6阮一峯教程代理

Reflect

靜態類,不能經過 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)
相關文章
相關標籤/搜索