ECMAScript 6入門Proxy與Reflect(上)

Proxy與Reflect

學習es6的新語法糖既能學習到新東西,又能使得本身的代碼更加優雅,逼格更高,爽
proxy與Reflect之間的運用就是Reflect對對象的操做觸發Proxy的攔截es6

  • Proxy是對對象進行代理,經過proxy生成的對象間接操做本來對象,最多見的就是get與set;語法形式var proxy = new Proxy(target, handler); target是須要操做的對象,而handler是包含操做target對象的一些方法的對象
  • Reflect是可以更加優雅的使用Object的相關方法

學習API

  • get

proxy: get(target, propKey, receiver)=>依次爲目標對象、屬性名和 proxy 實例自己(嚴格地說,是操做行爲所針對的對象),其中最後一個參數可選。數組

let obj = {
    a: 'foo',
    b: 'Proxy',
    foo: ''
 }
let proxy = new Proxy(obj, {
    get (target, proKey, receive) {
      console.log(target === obj)     //true
      return '當對proxy進行取值操做時會觸發這個get函數'
      
    }
 })

ps:proxytarget進行了代理,target就是obj對象,receive用於規定this到底指向哪一個對象,app

proxy.foo   //當對proxy進行取值操做時會觸發這個get函數

上面這種狀況並無改變this的,因此console.log(receive === proxy) //true
Reflect也有get方法:Reflect.get(target, prokey, receive)函數

Reflect.get(proxy, 'foo') //同上沒有this的指向
let newobj = {
    foo: 'this指向將改變'
}
Reflect.get(proxy, 'foo', newobj)  //foo = console.log(receive === proxy)  //true

因此對Reflect.get的第三個參數進行賦值將帶入帶proxy的get的第三個參數中學習

  • set

與get相似,這個是賦值時會觸發set方法
proxy: set(target, propKey, value, receiver)this

let obj = {}
  let newobj = {
    a: '123'
  }
  let proxy = new Proxy(obj, {
    set (target, proKey, value, receive) {
      return target[proKey] = `當對proxy進行賦值操做時會觸發這個set函數${value}`
      
    }
  })
  proxy.a = 666      //receive === proxy  true
  Reflect.set(proxy, 'a', 888)          //receive === proxy  true
  Reflect.set(proxy, 'a', 888, newobj)  //receive === newobj  true
  • apply

proxy的apply:apply(target, object, args)代理

let twice = {
    apply (target, ctx, args) {
      console.log(ctx)    //undefined
      return Reflect.apply(...arguments);
    }
  }
  function sum (left, right) {
    this.num = 888  /若是ctx沒有傳入或者傳入null,則會進行window.num = 888的賦值
    return left + right + this.nm
  }
  let obj = {
   nm: 666
  }
  var proxy = new Proxy(sum, twice);
  console.log(proxy(1, 2)) // 6
  console.log(proxy.apply(obj, [7, 8]))  //ctx則爲obj,並改變return

執行流程:proxy觸發函數調用,執行apply的方法,將參數自動帶入,target就是sum函數,ctx沒有傳入爲undefined,args1, 2,接下來將所有參數帶入執行Reflect.applycode

  • has

has比較簡單,是對對象進行in運算,判斷該屬性是否存在對象中,能夠是自身也能夠是原型鏈上,無論是否可遍歷對象

  • construct

在構造函數new時觸發,原型鏈

var p = new Proxy(function () {}, {
    construct: function(target, args, newTarget) {
      console.log('called: ' + args.join(', '));
      console.log(newTarget === p)
      return { value: args[0] * 10 };
    }
  });

  console.log((new p(1)).value)
  //等價於下面,Reflect.construct(target, args), args必須是數組
  console.log(Reflect.construct(p, [1]))
  • ownKeys

返回對象中自身的全部屬性,固然具體仍是取決於return 什麼內容;

觸發條件:
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
for...in循環
let target = {
  a: 1,
  b: 2,
  c: 3,
  [Symbol.for('secret')]: '4',
};

Object.defineProperty(target, 'key', {
  enumerable: false,
  configurable: true,
  writable: true,
  value: 'static'
});

let handler = {
  ownKeys(target) {
    return ['a', 'd', Symbol.for('secret'), 'key'];
  }
};

let proxy = new Proxy(target, handler);
console.log(Object.keys(proxy))    //自動過濾symbol,不存在的屬性,不可遍歷的屬性
console.log(Reflect.ownKeys(proxy)) //返回handler中return的值
相關文章
相關標籤/搜索