ES6中Proxy常用的攔截操作全面講解
一、什么是 Proxy
Proxy 是 ES6 引入的一個(gè)強(qiáng)大功能,意思是“代理”。它可以用來攔截對(duì)象的操作,并在操作時(shí)進(jìn)行自定義的邏輯處理。
你可以把 Proxy 理解成:
?? 在 對(duì)象 和 外部訪問者 之間加了一層“代理層”,所有對(duì)對(duì)象的操作都會(huì)先經(jīng)過 Proxy,從而讓我們有機(jī)會(huì)“改寫”這些操作。
語法如下:
let proxy = new Proxy(target, handler);
target:要代理的對(duì)象(可以是對(duì)象、數(shù)組、函數(shù)等)handler:包含攔截方法的對(duì)象,不同的方法對(duì)應(yīng)不同的攔截操作
二、常用的攔截操作(handler traps)
1.get—— 攔截對(duì)象屬性的讀取
const user = {
name: "Tom",
age: 18
};
const proxy = new Proxy(user, {
get(target, prop) {
if (prop === "age") {
return target[prop] + " 歲";
}
return target[prop];
}
});
console.log(proxy.name); // Tom
console.log(proxy.age); // 18 歲
?? 在讀取 age 時(shí)被攔截,返回了一個(gè)自定義的字符串。
2.set—— 攔截對(duì)象屬性的賦值
const user = {};
const proxy = new Proxy(user, {
set(target, prop, value) {
if (prop === "age") {
if (typeof value !== "number") {
throw new TypeError("年齡必須是數(shù)字!");
}
}
target[prop] = value;
return true; // 必須返回 true 表示賦值成功
}
});
proxy.age = 20;
console.log(proxy.age); // 20
proxy.age = "abc"; // 報(bào)錯(cuò):年齡必須是數(shù)字!
?? 可以在設(shè)置屬性時(shí)做數(shù)據(jù)校驗(yàn),非常適合做表單驗(yàn)證。
3.has—— 攔截in操作符
const user = { name: "Tom", password: "123456" };
const proxy = new Proxy(user, {
has(target, prop) {
if (prop === "password") {
return false; // 隱藏 password 屬性
}
return prop in target;
}
});
console.log("name" in proxy); // true
console.log("password" in proxy); // false
?? 可以用來隱藏敏感信息。
4.deleteProperty—— 攔截delete操作
const user = { name: "Tom" };
const proxy = new Proxy(user, {
deleteProperty(target, prop) {
if (prop === "name") {
console.log("name 屬性不能被刪除!");
return false;
}
return true;
}
});
delete proxy.name; // name 屬性不能被刪除!
console.log(proxy.name); // Tom
5.apply—— 攔截函數(shù)調(diào)用
function sum(a, b) {
return a + b;
}
const proxy = new Proxy(sum, {
apply(target, thisArg, args) {
console.log("攔截函數(shù)調(diào)用,參數(shù)是:", args);
return target(...args) * 2; // 返回值改為原函數(shù)結(jié)果的兩倍
}
});
console.log(proxy(1, 2)); // 6
6.construct—— 攔截new操作
class Person {
constructor(name) {
this.name = name;
}
}
const ProxyPerson = new Proxy(Person, {
construct(target, args) {
console.log("正在創(chuàng)建實(shí)例,參數(shù):", args);
return new target(...args);
}
});
const p = new ProxyPerson("Tom");
// 正在創(chuàng)建實(shí)例,參數(shù): [ 'Tom' ]
三、Proxy 的應(yīng)用場(chǎng)景
數(shù)據(jù)驗(yàn)證(如 set 中校驗(yàn)數(shù)據(jù)類型)
隱藏屬性(如 has、get 中屏蔽敏感數(shù)據(jù))
調(diào)試/日志記錄(在 get/set 時(shí)記錄日志)
自動(dòng)填充默認(rèn)值(屬性不存在時(shí)返回默認(rèn)值)
函數(shù)增強(qiáng)(apply 中擴(kuò)展函數(shù)功能)
Vue3 響應(yīng)式實(shí)現(xiàn)(Vue3 底層用 Proxy 實(shí)現(xiàn)數(shù)據(jù)劫持)
四、Proxy 與 Object.defineProperty 的區(qū)別
在 Vue2 中,響應(yīng)式是通過 Object.defineProperty 實(shí)現(xiàn)的,而 Vue3 改用了 Proxy。
Object.defineProperty只能監(jiān)聽對(duì)象的屬性,不能監(jiān)聽對(duì)象本身Proxy 能直接代理整個(gè)對(duì)象,不需要對(duì)每個(gè)屬性單獨(dú)處理
Proxy 能監(jiān)聽更多操作(如
in、delete、函數(shù)調(diào)用等)
因此,Proxy 更加靈活、強(qiáng)大,也逐漸成為未來的主流。
總結(jié)
到此這篇關(guān)于ES6中Proxy常用攔截操作的文章就介紹到這了,更多相關(guān)ES6 Proxy全面講解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS與jQuery實(shí)現(xiàn)ListBox上移,下移,左移,右移操作功能示例
這篇文章主要介紹了JS與jQuery實(shí)現(xiàn)ListBox上移,下移,左移,右移操作功能,涉及javascript與jQuery的事件響應(yīng)、頁面元素動(dòng)態(tài)操作等相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-05-05

