=========================反射=======================
Reflect: 反射
1. Reflect是什麼:
Reflect是一個內置的JS對象,它提供了一系列方法,可以讓開發者通過調用這些方法,訪問JS底層功能
由於它類似於其他語言的反射,因此取名爲Reflect
2. 它可以做什麼?
使用Reflect可以實現屬性的取值,賦值,調用普通函數,調用構造函數,判斷屬性是否存在與對象中等
3.這些功能存在,爲啥還有重複實現一次?
ES5中提出一個概念: 減少魔法,讓代碼更加純粹
這種理念很大程度上是受到了函數式編程的影響: plus(add(3)(2))(6)
ES6進一步貫徹這種理念,它任務,對屬性內存的控制,原型鏈的修改,函數的調用等,
這些都屬於底層實現,屬於一種魔法,因此,需要將他們提取出來,形成一個正常的API,
並高度聚合到某個對象中,於是就造就了Reflect對像
4. 它到底提供了哪些API呢?
Reflect.set(target,propertyKey, value): 設置對象target的屬性propertyKey裏面的value,
相當於對象.屬性 = 賦值;
例如:
const obj = {
a: 1,
}
// 賦值
obj.a = 10;
// 等效於
Reflect.set(obj, 'a', 10)
Reflect.get(target, key) : 讀取對象target對象的屬性propertyKey,等同於獲取對象的屬性值
例如:
const obj = {
a: 1,
}
// 賦值
console.log(obj.a)
// 等效於
console.log(Reflect.get(obj, 'a'))
Reflect.apply(target, thisArgument, argumentsList): 調用一個指定的函數,等效於綁定this和參數裂掉。等效於函數調用
例如:
function methonds(a){
console.log("打印",a)
}
methonds(3);
Reflect.apply(methonds, null, [3])
Reflect.deleteProperty(obj, propertyKey): 刪除一個對象裏面的key和value, 相等於 delete
Reflect.defineProperty(target, propertyKey, attribute): 類似於Object.defineProperty,
不同的式如果配置出現問題,返回false而不是報錯
Reflect.construct(target, arguementList) : 用構造函數創建一個對象
Reflect.has(target, key): 判斷一個屬性是否包含某個對象,相當於 in
======================代理===========================
代理: 修改了底層實現的方式
使用方法:
// 代理一個目標對象
new Proxy(target, handler)
兩個參數:
target: 目標對象
handler: 是一個普通對象,其中可以重寫底層實現
返回一個代理對象
例如:
const obj2 = {
a: 1,
b: 2
}
const proxy = new Proxy(obj, {
set(target, propertyKey, value) {
// target[propertyKey] = value;
Reflect.set(target, propertyKey, value)
},
get(target, propertyKey){
if(Reflect.has(target, propertyKey)){
retrun Reflect.get(target, propertyKey);
}else{
retrun -1;
}
}
})
console.log(proxy)
用代理和反射實現一些例子,常用的功能
// 觀察者模式
// 有一個對象,是觀察者,它用於觀察另外一個對象的屬性值變化,當屬性值變化後會受到通知,可能會做一些事情
function observer(target) {
render();
const proxy = new Proxy(target, {
set(target, propertyKey, value) {
Reflect.set(target, propertyKey, value);
render();
},
get(target, propertyKey) {
Reflect.get(target, propertyKey);
}
})
function render() {
let htmlStr = "";
for (const item of Object.keys(target)) {
htmlStr += `<span>${item}:</span><span>${target[item]}</span></br>`
}
document.body.innerHTML = htmlStr;
}
return proxy;
}
const obj = {
a: 1,
b: 2,
}
const result = observer(obj);
console.log(result);
// 手寫一個給構造函數賦值的方法
function proxyConstructor(className, ...agrs) {
return new Proxy(className, {
construct(className, agrsList) {
const constructObj = Reflect.construct(className, agrs);
for (const item in agrs) {
Reflect.set(constructObj, agrs[item], agrsList[item]);
}
return constructObj;
}
})
}
class User {
}
const userProxy = proxyConstructor(User, "name", "age", "sex");
const user = new userProxy("twinkle", 18, '男');
console.log(user)
// 實現一個函數驗證器
function proxyValication(funcName, ...agrs) {
return new Proxy(funcName, {
apply(funcName, thisArgument, argumentsList) {
// 驗證參數類型是否符合要求
argumentsList.forEach((item, index) => {
if (typeof item !== agrs[index]) {
throw new TypeError(`第${index + 1}參數${argumentsList[index]}不是${agrs[index]}類型`)
}
})
return Reflect.apply(funcName, thisArgument, argumentsList);
}
})
}
function sum(a, b) {
return a + b;
}
const sumProxy = proxyValication(sum, "number", "number");
const resultSum = sumProxy(1, 5898);
console.log(resultSum);
``
> ![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20200623194241732.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxNDk5Nzgy,size_16,color_FFFFFF,t_70)
es6 代理(Reflect)和反射(Proxy)的學習總結
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.