在 Javascript 的新标准 ES6 中,出现了一个新的对象 Proxy,它允许你在对象和函数之间建立一个代理层,通过代理层,可以更好的控制函数和对象的行为。Proxy 对象可以助力前端开发中的数据操作、状态管理、接口封装以及调试等多个场景,在本文中我们将详细介绍 Proxy 对象的使用方法,希望能给各位开发者带来启迪和帮助。
Proxy 对象的概述
Proxy 对象让你能够在对象或者函数的访问上添加一个代理层,通过代理层,我们可以实现更加细粒度的控制。Proxy 对象有一个构造函数 Proxy,并且支持多个构造函数参数,最常用的参数为目标对象及处理程序对象。
let proxy = new Proxy(target, handler);
target 参数是要被代理的对象,而 handler 参数则是一个对象,里面定义了代理的处理程序,比如 get、set、apply、construct 等等。
实例:对象属性值的过滤和检验
许多情况下需要对对象的属性进行控制,比如只读属性等,这时候我们可以使用 Proxy 来实现更完美的控制。
我们以一个简单的需求场景为例,通过代理层控制一个对象属性的值必须为数字。
// www.javascriptcn.com code example
let person = { age: 31 };
let validateNumber = {
set(target, key, value, proxy) {
if (!Number.isInteger(value)) {
throw new TypeError('Value is not an integer');
}
return Reflect.set(target, key, value, proxy);
}
};
let proxyPerson = new Proxy(person, validateNumber);
proxyPerson.age = 'thirty-one';
console.log(proxyPerson.age);
// Expected: Maximum call stack size exceeded在上述代码中,我们声明了一个基础对象 person,然后定义了一个代理对象 validateNumber。validateNumber 实现了 set 处理程序,该程序可以用于设置对象属性,比如 person 对象中的 age 属性。在 set 处理程序中,如果传入的属性值不是一个数字,那么我们就抛出了一个类型错误异常。如果是合法的数字,我们就使用 Reflect 对象执行真正的操作。
实例:让数组支持负数索引
在 Javascript 中,数组是一个非常重要的数据结构。然而,在默认情况下,当我们访问一个数组的负数索引时,会返回 undefined,希望访问负数索引仍然返回相对应的数字,我们可以使用 Proxy 来实现这个功能。
// www.javascriptcn.com code example
let arr = [1,2,3,4,5];
let negativeArray = (arr, reverse) => {
return new Proxy(arr, {
get: (target, index) => {
index = +index;
if (index < 0) {
index = reverse ? target.length + index : -index;
}
return Reflect.get(target, index);
}
})
}
let proxyArr = negativeArray(arr, true);
console.log(proxyArr[-1]);
// Expected: 5在上述代码中,我们声明了一个数组 arr,然后定义了一个 negativeArray 函数,该函数返回一个代理对象,该对象通过 get 处理程序,将数组负数索引转换为相对应的正数索引,避免了使用负数索引可能带来的问题。
实例:在对象上捕捉用户的操作
在一些特定业务场景下,我们需要知道外部用户对一个对象的某些操作变化,比如对象属性的更改以及属性的赋值。这时候我们可以使用 Proxy 手段来实现属性操作的侦听器,对外暴露一个功能接口。通过监听该接口,我们能够捕捉到所有的属性更新和赋值操作,进而进行下一步的数据处理或者状态控制。
// www.javascriptcn.com code example
let obj = {
name: '',
age: '',
gender: '',
setAttrValue(key, value) {
this[key] = value;
console.log('key:'+key+'value:'+value);
}
};
let p = new Proxy(obj, {
set: (target, prop, value) => {
target[prop] = value;
target.setAttrValue(prop, value);
return true;
}
});
p.name = 'test';
p.age = 35;
## p.gender = 'male';
// Expected: key:name value:test
// key:age value:35
// key:gender value:male在上述代码中,我们声明了一个基础对象 obj,然后使用 Proxy 对象对 obj 进行代理,使用 set 处理程序拦截了对象属性更新行为,进而实现了对用户更新的属性进行输入捕捉。
小结
在本文中,我们详细介绍了 ES6 中的 Proxy 对象的使用方法,本文提供了针对于对象属性值的过滤和检验、支持数组的负数索引以及对象属性操作捕捉等多个实例,希望能够帮助更多的前端开发者更好地理解 Proxy 对象的特性以及使用场景。更多 Proxy 的实战运用,就需要开发者根据具体业务场景进行思考和实践,相信在不断的思考与实践过程中,Proxy 对象将会发挥出更加强大的作用。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/67c0171e314edc268462e53c