反射機制的定義
反射通常指在程式在運行時能夠獲取自身的資訊,
靜態語言反射
在java中使用反射的一個例子
Class<?> clazz = Class.forName("com.netease.main.Person"):
Method[] methods = clazz.getMethods():
JavaScript 反射
假設有一個物件obj,我們不知道他的內部結構和Api,這個時候我們通過某種機制獲取一個物件的內部結構,這種機制就叫做反射,
我們可以看下javaScript中的幾個例子
for(let p in window) {
console.log(p)
}
// 了解了window內部結構后,我們可以使用window內部的屬性,我們嘗試呼叫它的方法
window['open']('http://www.baidu.com')
// 使用Object.keys方法獲取物件的內部結構:
let obj = {
id: 1,
name: 'xxx',
test: function test() {
console.log('test')
}
}
// 輸出結果:
console.log(Object.keys(obj))
以上我們通過幾個例子基本了解了什么是反射,
Reflect
Reflect是一個內置物件,它提供攔截JavaScript操作的方法,Reflect沒有建構式,不能使用‘new’運算子去新建,也不能將其作為一個函式去呼叫,Reflect的所有屬性和方法都是靜態的(類似Math物件),
為什么需要Reflect物件?
- 把實作反射機制的方法重新歸結在一起并且簡化操作,保持JS語意清晰和語法簡單,
let key1 = 'id', key2 = Symbol.for('name'),
obj = { [key1]: 1, [key2]: 'xxx' };
let keys = Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj))
// 使用Reflect 獲取所有keys
let reflectKeys = Reflect.ownKeys(obj)
- 補充了一些Object物件沒有的方法,比如Reflect.apply,
function fn(...rest) {
console.log(rest);
console.log('test:' + this.name)
}
fn.apply = null;
fn.apply(1,2,3); // TypeError: fn.apply is not a function
Function.prototype.apply.call(fn, {name: 'xxx'}) // [] test: name
Reflect.apply(fn, {name: 'xxx'},[1,2,3]);
- 讓Object操作都變成函式行為,比如使用Reflect.has(obj,name)替換name in obj,
let obj1 = { name: 'xxx'};
if ('name' in obj1) {
console.log('test ok')
}
let obj2 = { name: 'xxx'};
if(Reflect.has(obj2, 'id')) {
console.log('test ok')
}

Reflect.apply()
對于一個函式進行呼叫操作,同時可以傳入一個陣列作為呼叫引數,
Reflect.apply(target,thisArgument,argumentsList)
Reflect.construct()
對建構式進行new 操作,相當于執行new target(...args),
Reflect.construct(target,argumentsList[,newTarget])
Reflect.defineProperty()
定義物件的一個屬性,attributes為屬性描述
Reflect.defineProperty(target,property,attributes)
Reflect.deleteProperty()
洗掉物件的一個屬性,
Reflect.deleteProperty(target,property)
Reflect.get()
查找并回傳物件的屬性值,
Reflect.get(target, property[, receiver])
可以看個例子
// 預設receiver
let obj = {
a: 1,
b: 2,
get c() {
return this.a + this.b
}
}
console.log(Reflect.get(obj, 'a')) // 1
console.log(Reflect.get(obj, 'b')) // 2
console.log(Reflect.get(obj, 'c')) // 3
// 加上receiver
let obj1 = {
a: 1,
b: 2,
get c() {
return this.a + this.b
}
}
let receiver = {
a: 4,
b: 4,
}
console.log(Reflect.get(obj1, 'a',receiver)) // 1
console.log(Reflect.get(obj1, 'b',receiver)) // 2
console.log(Reflect.get(obj1, 'c',receiver)) // 8
Reflect.set()
設定物件的屬性值
Reflect.set(target, property, value[, receiver])
// 預設receiver
let obj = {
name: 'test',
}
console.log(obj.name); // test
Reflect.set(obj, 'name', 'xxx')
console.log(obj.name) // xxx
// 加上reveiver
let obj = {
name: 'test',
set nickname(value) {
return this.name = value
}
}
let receiver = {
name: 'test'
}
console.log(obj.name); // test
console.log(receiver.name); // test
Reflect.set(obj, 'nickname', 'xxx', receiver);
console.log(obj.name); // test
console.log(receiver.name); // xxx
Reflect.getOwnPropertyDescriptor()
查找并回傳物件的屬性描述符,
Reflect.getOwnPropertyDescriptor(target, propertyKey)

Reflect.getPrototypeOf()
回傳指定物件的原型,讀取物件的__proto__屬性,
Reflect.getPrototypeOf(target)

Reflect.setPrototypeOf()
設定指定物件的原型,
Reflect.setPrototypeOf(target,prototype)

Reflect.has()
判斷obj是否有某個屬性,
Reflect.has(target,prototype)
Reflect.isExtensible()
判斷一個物件是否可擴展
Reflect.isExtensible(target)
Reflect.preventExtensions()
讓物件變為不可擴展,
Reflect.preventExtensions(target)

Reflect.ownKeys()
返回要給包含所有自身屬性(不包含繼承屬性)的陣列,
Reflect.ownKeys(target)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/399525.html
標籤:其他
