Reflect Reflect 對象和Proxy對象一樣, 為操作對象提供了新的API。 為什麼使用 Reflect的方式來操作對象? 將 Object 對象上一些明顯屬於內部的方法放到 Reflect對象上。比如 也可以使用 修改某些 Object 方法的返回結果 讓 Object 操作都變成函數 ...
Reflect
Reflect 對象和Proxy對象一樣, 為操作對象提供了新的API。
為什麼使用 Reflect的方式來操作對象?
將 Object 對象上一些明顯屬於內部的方法放到 Reflect對象上。比如
Object.defindProperty
也可以使用Reflect.defindProperty
修改某些 Object 方法的返回結果
讓 Object 操作都變成函數行為。
Reflect 對象的操作方法和 Proxy的方法一一對應, 很方便 Proxy對象來調用 Reflect 方法
例子:
const sum = function (num1, num2) {
return num1 + num2
}
const proxy = new Proxy(sum, {
apply(target, context, args) {
return Reflect.apply(...arguments) * 2
}
})
proxy(1,2) // 6
以上代碼 proxy 的配置方法 apply和 Reflect的apply方法是對應關係,直接通過 Reflect.apply
來調用攔截函數 sum
。並將函數執行後的結果 * 2。最終的結果是 6。
#### Reflect 對象和 Proxy的靜態方法一樣,同樣是13個。
- Reflect.apply(target, context, args)
- Reflect.get(target, key, context)
- Reflect.set(target, key, value, context)
- Reflect.construct(target, args)
- Reflect.defindProperty(target, key, desc)
- Reflect.has(target, key)
- Reflect.deleteProperty(target, key)
- Reflect.setProperty(target, proto)
- Reflect.getProperty(target)
- Reflect.ownKeys(target)
- Reflect.isExtensible(target)
- Reflect.preventExtensions(target)
- Reflect.getOwnPropertyDescriptor(target, key)
Reflect.get(target, key, context)
target
: 查找的對象
key
: 查找的屬性
context
: 讀取getter函數的上下文對象
const obj = {
name: 'qiqingfu',
get sayName() {
console.log(this.name)
}
}
const obj1 = {
name: 'zhangfei'
}
Reflect.get(obj, 'name') // qiqingfu
Reflect.get(obj, 'sayName', obj1) // zhangfei
如果第一個參數不是對象, Reflect.get
方法會報錯。
Reflect.set(target, key, value, context)
target
: 要給哪個對象設置
key
: 要設置的屬性
value
: 設置的值
返回值
: boolean
const obj = {
value: 1,
set fn(newValue) {
return this.value = newValue
}
}
console.log(Reflect.set(obj, 'name', 'qiqingfu')) // true
console.log(Reflect.set(obj, 'fn', 2))
console.log(obj)
以上代碼,給obj對象設置了一個name
屬性,其值為qiqingfu
, 並且設置fn
的時候被get
函數攔截到了。
Reflect.has(target, key) 方法檢測 target對象上有麽有 key這個屬性
返回值
: boolean
const obj = {
name: 'qiqingfu',
a: 2
}
console.log(Reflect.has(obj, 'name')) // true
console.log(Reflect.has(obj, 'a')) // true
console.log(Reflect.has(obj, 'b')) // false
其實 Reflect.has
和 in
操作符類似。
Reflect.construct(target, args) 方法用於類似於 new 操作符
target
: 目標函數
args
: 實例化對象需要傳遞的參數 Array
返回值
: 實例對象
function Prosen (name, age) {
this.name = name;
this.age = age
}
const prosen = Reflect.construct(Prosen, ['qiqingfu', 22])
// {name: 'qiqingfu', age: 22}
以上代碼使用 Reflect.construct
方法實例話一個對象,接受的參數為數組類型
Reflect.defineProperty(target, key, decs) 和 Object.defineProperty(target, key, decs) 一樣
更推崇使用前者。
方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 並返回這個對象。
const obj = {
}
Reflect.defineProperty(obj, 'a', {
value: 1,
configurable: true, // 可配置
writable: true // 可寫
})
// {a: 1}
以上代碼給 obj 對象添加了一個 a屬性, 其值為1並且是可配置和可修改的
Reflect.deleteProperty(target, key) 方法刪除 target對象的key屬性
const obj = {
a: 1
}
Reflect.defindProperty(obj, 'a')
console.log(obj) // {}
Reflect.getPropertyOf(target) 方法獲取一個對象的原型對象
function Prosen() {
}
Prosen.prototype.age = 21
const prosen = Reflect.construct(Prosen, [])
// 獲取原型對象的屬性
const proto = Reflect.getPrototypeOf(prosen)
console.log(proto)
// {age: 21, constructor: ƒ}
以上代碼 給 Prosen 構造函數的原型對象上添加了一個 age屬性。並且通過 Reflect.construct
方法實例化一個對象。那麼就可以通過 Reflect.getPrototypeOf
方法獲取一個對象的原型對象。
Reflect.setPrototypeOf(target, proto) 方法將 proto設置為 target對象的原型對象
function Prosen() {
}
Prosen.prototype.age = 21
const prosen = Reflect.construct(Prosen, [])
// 設置prosen 的原型對象
Reflect.setPrototypeOf(prosen, {b: 2})
此時, prosen的原型對象為 {b:2}, 而 construct
指針會被覆蓋
Reflect.ownKeys(target) 獲取對象的key值,返回值為數組
和 Object.ownKeys
相同。
const obj = {
a: 1,
[Symbol('c')]: 3,
}
Reflect.defineProperty(obj, 'b', {
value: 2,
configurable: true,
enumerable: true
})
console.log(Reflect.ownKeys(obj))
// ["a", "b", Symbol(c)]
返回值是一個數組, 存放著對象的 key值的集合。
Reflect.getOwnPropertyDescriptor(target, key) 方法獲取一個對象key值的描述對象
返回值
: Object
const obj = {
a: 1,
[Symbol('c')]: 3,
}
Reflect.defineProperty(obj, 'b', {
value: 2,
configurable: true,
enumerable: true
})
const decs = Reflect.getOwnPropertyDescriptor(obj, 'b')
console.log(decs)
/*
{value: 2, writable: false, enumerable: true, configurable: true}
*/
以上代碼通過 Reflect.getOwnPropertyDescriptor
方法獲取一個對象屬性的描述對象, 如果第一個參數不是對象會報錯。而在 Object.getOwnPropertyDescriptor
不會報錯,只不過返回 undefind