ES6之Reflect

Reflext對象和Proxy對象同樣,都是爲了操做對象而新增的,目的:bash

將Object對象一些明顯屬於語言內部的方法放到Reflect對象上,好比Object.defineProperty,將來新方法只部署在Reflect對象上。app

修改Object方法的返回結果,變的更合理,好比Object.defineProperty在沒法定義屬性時,會拋出一個錯誤,而Reflect.defineProperty則會返回false。函數

讓Object操做都變成函數行爲。某些Object操做是命令式,好比name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)讓它們變成了函數行爲。flex

Reflect對象的方法與Proxy對象的方法一一對應,只要是Proxy對象的方法,就能在Reflect對象上找到對應的方法。這就讓Proxy對象能夠方便地調用對應的Reflect方法。也就是說,無論Proxy怎麼修改默認行爲,你總能夠在Reflect上獲取默認行爲。ui

跟Proxy同樣,Reflect也有13個靜態方法:this

Reflect.apply(target, thisArg, args)

Reflect.construct(target, args)

Reflect.get(target, name, receiver)

Reflect.set(target, name, value, receiver)

Reflect.defineProperty(target, name, desc)

Reflect.deleteProperty(target, name)

Reflect.has(target, name)

Reflect.ownKeys(target)

Reflect.isExtensible(target)

Reflect.preventExtensions(target)

Reflect.getOwnPropertyDescriptor(target, name)

Reflect.getPrototypeOf(target)

Reflect.setPrototypeOf(target, prototype)
複製代碼

大部分和Object對象同名方法做用同樣,最重要的是與Proxy對象方法一一對應。spa

Reflect.get(target, name, receiver)prototype

查找並返回target對象的name屬性,若是沒有該屬性,則返回undefined。若是name屬性部署了讀取函數(getter),則讀取函數的this綁定receiver,若是第一個參數不是對象,Reflect.get方法會報錯。:code

var obj = {

    a: 1,

    b: 2,

    get c(){

        return this.a + this.b;

    }

}

var robj = {

    a: 4,

    b: 5

}

console.log(Reflect.get(obj, 'a'));//1

console.log(Reflect.get(obj, 'b'));//2

console.log(Reflect.get(obj, 'c', robj));//9
複製代碼

Reflect.set(target, name, value, receiver)cdn

設置target對象的name屬性等於value。若是name屬性設置了賦值函數,則賦值函數的this綁定receiver。若是第一個參數不是對象,Reflect.set會報錯。若是 Proxy對象和 Reflect對象聯合使用,前者攔截賦值操做,後者完成賦值的默認行爲,並且傳入了receiver,那麼Reflect.set會觸發Proxy.defineProperty攔截:

var obj = {

    a: 1,

    set b(value){

        return this.a = value;

    }

}

var robj = {

    a: 10

}

console.log(obj.a);//1

Reflect.set(obj, 'a', 10);

console.log(obj.a);//10

Reflect.set(obj, 'b', 20, robj);

console.log(obj.a);//10

console.log(robj.a);//20



Reflect.has(obj, name)
複製代碼

Reflect.has方法對應name in obj裏面的in運算符。若是Reflect.has()方法的第一個參數不是對象,會報錯。

var obj = {

    a: 1,

}

console.log('a' in obj);//true

console.log(Reflect.has(obj, 'a'));//true



Reflect.deleteProperty(obj, name)
複製代碼

Reflect.deleteProperty方法等同於delete obj[name],用於刪除對象的屬性。該方法返回一個布爾值。若是刪除成功,或者被刪除的屬性不存在,返回true;刪除失敗,被刪除的屬性依然存在,返回false。若是Reflect.deleteProperty()方法的第一個參數不是對象,會報錯:

var obj = {

    a: 1,

}

console.log(obj.a);//1

delete obj.a

console.log(obj.a);//undefined

var obj = {

    a: 1,

}

console.log(obj.a);//1

console.log(Reflect.deleteProperty(obj, 'a'));//true

console.log(obj.a);//undefined



Reflect.construct(target, args)
複製代碼

Reflect.construct方法等同於new target(...args),這提供了一種不使用new,來調用構造函數的方法。若是Reflect.construct()方法的第一個參數不是函數,會報錯:

function User(name) {



}

var user = new User('wade');

var user = Reflect.construct(User, ['wade']);



Reflect.getPrototypeOf(obj)

Reflect.getPrototypeOf方法用於讀取對象的__proto__屬性,對應Object.getPrototypeOf(obj)。區別是,若是參數不是對象,Object.getPrototypeOf會將這個參數轉爲對象,而後再運行,而Reflect.getPrototypeOf會報錯:

function User() {};

var user = new User();

console.log(Object.getPrototypeOf(user) === User.prototype);//true

console.log(Reflect.getPrototypeOf(user) === User.prototype);//true



Reflect.setPrototypeOf(obj, newProto)
複製代碼

Reflect.setPrototypeOf方法用於設置目標對象的原型(prototype),對應Object.setPrototypeOf(obj, newProto)方法。它返回一個布爾值,表示是否設置成功。若是沒法設置目標對象的原型(目標對象禁止擴展),Reflect.setPrototypeOf方法返回false。

若是第一個參數不是對象,Object.setPrototypeOf會返回第一個參數自己,而Reflect.setPrototypeOf會報錯。若是第一個參數是undefined或null,Object.setPrototypeOf和Reflect.setPrototypeOf都會報錯:

function User() {};

User.prototype.a = 1;

var user = new User();

function Son() {};

Son.prototype.a = 2;

var user = new User();

Reflect.setPrototypeOf(user, Son.prototype);

console.log(user.a);//2



Reflect.apply(func, thisArg, args)
複製代碼

Reflect.apply方法等同於Function.prototype.apply.call(func, thisArg, args),用於綁定this對象後執行給定函數。綁定一個函數的this對象,能夠這樣寫fn.apply(obj, args),可是若是函數定義了本身的apply方法,就只能寫成Function.prototype.apply.call(fn, obj, args),採用Reflect對象能夠簡化這種操做。

Reflect.defineProperty(target, propertyKey, attributes)

Reflect.defineProperty方法基本等同於Object.defineProperty,用來爲對象定義屬性。將來,後者會被逐漸廢除,從如今開始就使用Reflect.defineProperty代替它,若是Reflect.defineProperty的第一個參數不是對象,就會拋出錯誤:

var obj = {};

Reflect.defineProperty(obj, 'a', {

    value: 1

});

console.log(obj.a);//1



Reflect.getOwnPropertyDescriptor(target, propertyKey) 
複製代碼

Reflect.getOwnPropertyDescriptor基本等同於Object.getOwnPropertyDescriptor,用於獲得指定屬性的描述對象,未來會替代掉後者。區別是,若是第一個參數不是對象,Object.getOwnPropertyDescriptor(1, 'foo')不報錯,返回undefined,而Reflect.getOwnPropertyDescriptor(1, 'foo')會拋出錯誤,表示參數非法:

var obj = {};

Reflect.defineProperty(obj, 'a', {

    value: 1,

});

console.log(Reflect.getOwnPropertyDescriptor(obj, 'a'));

configurable: false

enumerable: false

value: 1

writable: false



Reflect.isExtensible (target)
複製代碼

Reflect.isExtensible方法對應Object.isExtensible,返回一個布爾值,表示當前對象是否可擴展。若是參數不是對象,Object.isExtensible會返回false,由於非對象原本就是不可擴展的,而Reflect.isExtensible會報錯。

Reflect.preventExtensions(target)

Reflect.preventExtensions對應Object.preventExtensions方法,用於讓一個對象變爲不可擴展。它返回一個布爾值,表示是否操做成功。若是參數不是對象,Object.preventExtensions在 ES5 環境報錯,在 ES6 環境返回傳入的參數,而Reflect.preventExtensions會報錯。

Reflect.ownKeys (target)

Reflect.ownKeys方法用於返回對象的全部屬性,基本等同於Object.getOwnPropertyNames與Object.getOwnPropertySymbols之和。若是Reflect.ownKeys()方法的第一個參數不是對象,會報錯。

相關文章
相關標籤/搜索