1、Proxy
Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
1. 基本操作(11种)
注:这里只列举了几种 ,其余的可以去MDN查看 Proxy - JavaScript | MDN (mozilla.org)``
// 为什么说是对象的基本操作呢,我们使用js对对象取值、赋值等基本操作就是在调用一个个函数
const obj = {
a: 11
}
obj.a // [[GET]]
obj.b = 10 // [[SET]]
'a' in obj // [[HAS]]
delete obj a // [[DELETE]]
for(const key in obj){} // [[OWNKEYS]]
2. 拦截和自定义
当我们不使用 Proxy来代理对象的时候在操作对象时会默认调用原来的基本操作函数,当我们使用Proxy时他就不会走原来的函数了,会走我们proxy描述符中的陷阱函数(就像陷阱一样会拦截)
const obj = {
browsers: ["Internet Explorer", "Netscape"],
}
// obj:目标对象
// prop:操作的键
// value: 赋的值
// 代理对象 = new Proxy(要代理的对象, {
// get:(obj,prop){},
// set:(obj,prop,value){},
// })
// 以下`products`代理会计算传值并根据需要转换为数组。这个代理对象同时支持一个叫做 `latestBrowser`的
// 附加属性,这个属性可以同时作为 getter 和 setter。
let products = new Proxy(
obj,
{
get: function (obj, prop) {
// 附加一个属性
if (prop === "latestBrowser") {
return obj.browsers[obj.browsers.length - 1];
}
// 默认行为是返回属性值
return obj[prop];
},
set: function (obj, prop, value) {
// 附加属性
if (prop === "latestBrowser") {
obj.browsers.push(value);
return;
}
// 如果不是数组,则进行转换
if (typeof value === "string") {
value = [value];
}
// 默认行为是保存属性值
obj[prop] = value;
// 表示成功
return true;
},
},
);
console.log(products.browsers); // ['Internet Explorer', 'Netscape']
products.browsers = "Firefox"; // 如果不小心传入了一个字符串
console.log(products.browsers); // ['Firefox'] <- 也没问题,得到的依旧是一个数组
products.latestBrowser = "Chrome";
console.log(products.browsers); // ['Firefox', 'Chrome']
console.log(products.latestBrowser); // 'Chrome'