概述
Reflect
是爲了操作對象而提供的 API
,它的設計目的有以下幾個。
- 將
Object
上一些屬於語言內部的方法 (比如Object.defineProperty
)放在Reflect
對象上。現階段,某些方法同時在Object
和Relfect
對象上部署,未來的新方法將只部署在Reflect
對象上。 - 修改某些
Object
方法的返回結果,讓其更加完善。比如,Object.defineProperty(obj,name,desc)
在無法定義屬性時,會拋出一個異常,而Reflect.defineProperty(obj,name,desc)
則會返回false
- 讓
Object
操作變成函數行爲。某些Object
操作是命令式的,比如name in obj
和delete obj[name]
,而Reflect.has(obj,name)
和Reflect.deleteProperty(obj,name)
讓他們變成了函數行爲。 Reflect
對象的方法與Proxy
對象的方法對應,只要是Proxy
對象的方法,就能在Reflect
對象上找到對應的方法。這就讓Proxy
對象可以方便的調用對應的方法,完成默認行爲。也就是說,不管Proxy
怎麼修改默認行爲,你總可以在Reflect
上獲取默認行爲。
靜態方法
Reflect
對象上一共有13個靜態方法,這些大部分與 Object
對象同名甚至作用都是相同的,而且它與 Proxy
對象的方法是對應的。
Reflect.get(target,name,receiver)
Reflect.get()
方法查找並返回 target
對象的 name
屬性,如果沒有該屬性,則返回 undefined
。如果 name
屬性部署了 getter
,那麼將 receiver
綁定到函數中的 this
。
let person = {
name:"jonas",
get age(){
return this.age
}
}
let jonas = {age:18}
let name = Reflect.get(person,"name")
let age = Reflect.get(person,"age",jonas)
console.log(name) //jonas
console.log(age) //18
另外,如果第一個參數不是對象,而是基本類型數據,則會報錯。
Reflect.set(target,name,value,receiver)
設置 target
對象的 name
屬性爲 value
,如果屬性設置了 setter
則將 receiver
綁定到函數中的 this
let person = {
name:"jonas",
get age(){
return this.age
},
set age(value){
return this.age = value
}
}
let jonas = {age:18}
Reflect.set(person,"age",20,jonas)
console.log(jonas.age) //20
同樣的,如果第一個參數不是對象,則會報錯。
Reflect.has(obj,name)
判斷 name
是否爲 obj
對象中的屬性,相當於 name in obj
。方法返回布爾值。
let person = {name:"jonas"}
let result = Reflect.has(person,"name")
console.log(result) //true
Reflect.deleteProperty(obj,name)
刪除對象中的屬性,相當於 delete obj[name]
,該方法返回布爾值,如果屬性不存在或刪除成功,則返回 true
let person = {name:"jonas"}
let result = Reflect.deleteProperty(person,"name")
console.log(result) //true
console.log(person) ///{}
Reflect.construct(target,args)
該方法等同於 new
運算符,提供了一種不使用 new
關鍵字實例化的方式。其中 target
是構造函數,args
則是函數的參數列表。
function Person(name,age){
this.name = name
this.age = age
}
let person = Reflect.construct(Person,["jonas",18])
console.log(person) //Person { name: 'jonas', age: 18 }
Reflect.getPrototypeOf(obj)
用於讀取對象的 __proto__
屬性,對應 Object.getPrototypeOf(obj)
Reflect.getPrototypeOf()
與 Object.getPrototypeOf()
的區別是後者如果第一個參數不是對象,則會轉換爲對象,而前者會報錯。
Reflect.setPrototypeOf(obj,proto)
該方法用於設置目標對象的原型,與 Object.setPrototypeOf()
對應,返回值是一個布爾值,表示是否設置成功。
提點:封閉對象,無法擴展對象,凍結對象不能設置原型。
如果第一個參數不是,這兩個方法都會報錯。
Reflect.apply(func,thisArg,args)
該方法等同於 Function.prototype.apply.call()
用於綁定 this
對象後執行函數。
一般情況下,如果需要綁定函數 this
,可以直接 fn.call()
,但是如果函數重寫了 apply()
方法,就只能通過 Function
的原型來實現了。然而,Reflect
就是簡化了這個操作。
Reflect.defineProperty(target,key,desc)
該方法等同於 Object.defineProperty
,用來爲對象定義屬性。注意:Object.defineProperty
將逐漸被淘汰,取而代之的是 Reflect.defineProperty
.
Reflect.getOwnPropertyDescriptor(target,prop)
該方法基本等同於 Object.getOwnPropertyDescriptor()
,用於得到指定屬性的屬性描述符,將來後者將會被廢除。
Reflect.isExtensible(target)
對應 Object.isExtensible()
,返回一個布爾值,表示當前對象是否可擴展。
Reflect.preventExtensions(target)
對應 Object.preventExtensions()
,用於讓一個對象變爲不可擴展,返回一個布爾值,表示是否操作成功。
Reflect.ownKeys(target)
該方法用於返回對象的所有屬性,等於 Object.getOwnPropertyNames
與 Object.getOwnPropertySymbols
兩者之和。