ES6:Reflect

Lessong發表於2019-02-17

Reflect

  1. 概述。

Relflect物件與Proxy物件一樣,也是ES6為了操作物件而提供的新的API。Reflect物件的設計目的有幾個。
(1)將Object物件的一些明顯屬於語言內部的方法(比如Obejcet.defineProperty),放到Reflect物件上。現階段,某些方法同時在Object喝Reflect物件上部署,未來的新方法將只部署在Reflect物件上。也就是說,從reflect物件上可以拿到語言內部的方法。
(2)修改某些Object方法的返回結果,讓其變得更合理。比如,Object.defineProperty(obj,name,desc)在無法定義屬性時,會丟擲一個錯誤,而Reflect.defineProperty(obj,name,desc)則會返回false。

//老寫法
try{
    Object.defineProperty(target,property,attributes);
    //success
}catch(e){
    //failure
}

//新寫法
if(Reflect.defineProperty(target,property,attributes)){
    //success
}else{
    //failure
}

(3)讓Object操作都變成函式行為。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj,name)和Reflect.deleteProperty(obj,name)讓它們變成了函式行為。

//老寫法
`assign` in Object//true
//新寫法
Reflect.has(Object,`assign`)//true

(4)Reflect物件的方法與Proxy物件的方法一一對應,只要是Proxy物件的方法,就能在Reflect物件上找到對應的方法。這就讓Proxy物件可以方便地呼叫對應的Reflect方法,完成預設行為,作為修改行為的基礎。也就是說,不管Proxy怎麼修改預設行為,你總可以在Reflect上獲取預設行為。

Proxy(target, {
  set: function(target, name, value, receiver) {
    var success = Reflect.set(target,name, value, receiver);
    if (success) {
      console.log(`property ` + name + ` on ` + target + ` set to ` + value);
    }
    return success;
  }
});

上面程式碼中,Proxy方法攔截target物件的屬性賦值行為。它採用Reflect.set方法將值賦值給物件的屬性,確保完成原有的行為,然後再部署額外的功能。
下面是另一個例子。

var loggedObj = new Proxy(obj, {
  get(target, name) {
    console.log(`get`, target, name);
    return Reflect.get(target, name);
  },
  deleteProperty(target, name) {
    console.log(`delete` + name);
    return Reflect.deleteProperty(target, name);
  },
  has(target, name) {
    console.log(`has` + name);
    return Reflect.has(target, name);
  }
});

上面程式碼中,每一個Proxy物件的攔截操作(getdeletehas),內部都呼叫對應的Reflect方法,保證原生行為能夠正常執行。新增的工作,就是將每一個操作輸出一行日誌。

相關文章