JavaScript Proxy代理
ES6标准中包含的高级功能之一是JavaScript代理。代理(Proxy)是一个JavaScript对象,它将包装一个对象或函数,并确定基本操作的特定行为。代理(Proxy)可以通过充当另一个对象的代理来重新定义一个对象的基本操作。
可以重新定义的一些基本操作包括读写、枚举、属性查找、函数调用等。代理和元编程语言类似,它不依赖于被包装的对象或函数。
JavaScript代理是一个封装了另一个对象(目标对象)并窃听目标对象核心动作的对象。
语法
下面的语法显示了一个带有处理器(handler)和目标(target)变量的JavaScript代理。
let target_variable = new Proxy(target, handler);
参数:
代理所提供的两个参数是目标和handler()。
- target:将被代理的对象或函数,可以是类、函数或另一个代理。关键字”target”用于跟踪包装对象或方法的代理。
- handler:一个包含控制代理完成活动时,如何行为的方法的对象。
- 陷阱:尽管此参数在proxy()的语法中不可见,但我们仍然会使用它。这些是在处理目标时使用的方法。
解释:
- 我们可以使用JavaScript的Proxy类,其中参数”target”和”handler”将是包装对象。
- 在目标上使用的函数和陷阱将用于对目标执行操作。
- 如果处理程序有一个陷阱,它将执行并为代理提供处理它的机会;否则,这些活动将使用目标。
JavaScript的proxy()操作是什么
- 在这个过程中,关键的三个术语”target”、”handler”和”traps”将非常有用,因为Proxy对象是目标对象的包装器,可以更新变量。
const student = {
studentName: 'Radha',
studentNumber: '9022110011',
email: 'radg211@example.com',
}
- 代理拦截目标对象上执行的所有操作,并将它们转向处理器对象。
const handler_variable = {
get(target, property_data) {
console.log(`the value ${property_data} will be read.`);
return target[property_data];
}
}
或者
const handler_variable = {};
- 接下来,使用新的Proxy()和参数”目标对象”和”处理器对象”,构建一个代理。
const proxyVar = new Proxy(student, handler_variable);
- 代理是一种奇怪的东西,没有自己的特征。如果“处理对象”为空,则操作将路由到“目标”。
console.log(proxyVar.studentName);
- 为了对在实际编码中如何使用proxy()并将数据显示为输出有一个良好的概念。
示例
这些示例描述了JavaScript代理的功能和操作。
示例1:
该示例展示了使用输入参数和基本空处理程序的JavaScript代理方法。我们可以使用变量中的三个属性,并使用处理程序变量来显示它们。
<!DOCTYPE html>
<html>
<head>
<title> JavaScript Proxy </title>
</head>
<body>
<h3> JavaScript Proxy() </h3>
<p> Javascript proxy() shows student data with the handler using function. </p>
<script>
const student = {
studentName: 'Radha',
studentNumber: '9022110011',
email: 'radg211@example.com',
}
const handler_variable = {};
const proxyVar = new Proxy(student, handler_variable);
document.write("Name of the Student: " + proxyVar.studentName + "<br/>");
document.write("Phone number of the Student: " + proxyVar.studentNumber + "<br/>");
document.write("Email of the Student: " + proxyVar.email);
</script>
</body>
</html>
结果
以下输出显示了使用代理目标和处理程序的学生数据。
示例2:
该示例展示了使用数组数据、目标和处理程序属性的JavaScript代理方法。处理程序使用输入变量的空参数。
<!DOCTYPE html>
<html>
<head>
<title> JavaScript Proxy </title>
</head>
<body>
<h3> JavaScript Proxy() </h3>
<p> Javascript proxy() shows input data with the handler using function. </p>
<script>
let target_variable = {};
let proxy_variable = new Proxy(target_variable, {});
proxy_variable.number = 50;
document.write("Using target: " + target_variable.number + "<br/>");
document.write("using proxy: " + proxy_variable.number + "<br/>");
for(let a in proxy_variable) document.write("Looping: " + a + "<br/>");
</script>
</body>
</html>
输出
以下输出展示了使用代理事件和循环的学生数据。
示例3:
这个示例展示了使用输入的目标和处理器属性的JavaScript代理方法。处理器使用输入变量的属性。
<!DOCTYPE html>
<html>
<head>
<title> JavaScript Proxy </title>
</head>
<body>
<h3> JavaScript Proxy() </h3>
<p> Javascript proxy() shows student data with the handler using function. </p>
<script>
const student = {
studentName: 'JavaTpoint',
studentNumber: '9180617143',
email: 'jtp1981@email.com',
}
const handler_variable = {
get(target, property_data) {
document.write(`The Propery ${property_data} is displayed: `);
return target[property_data];
}
}
const proxyVar = new Proxy(student, handler_variable);
document.write(proxyVar.studentName + "<br/>");
document.write(proxyVar.studentNumber + "<br/>");
document.write(proxyVar.email);
</script>
</body>
</html>
输出
以下输出显示使用代理目标和处理程序的学生数据。
使用代理的优点和缺点
优点
如上所述,Javascript代理在各种情况下都很有用。以下是这些情况的列表:
- 对可以与项目交互的操作具有更大的控制。代理在处理基本对象操作的执行时,给用户提供了额外的控制和灵活性。
- 检查和验证数据:这可能涉及类型检查或将值限制在给定阈值内。
- 安全性:它们允许只读访问对象和数组中保存的数据,防止数据被非法修改。
- DOM修改:DOM操作过程中积极使用它们。
- 默认行为:使用代理时,可以重新定义get方法,在请求的属性或数据不存在时返回默认值。
缺点
- 它也具有显著的缺点,在特定情况下可能不受欢迎。我们在本部分讨论Javascript代理的缺点。
- 性能:代理充当用户和原始项目之间的联络人。这增加了处理的复杂性水平,对性能有负面影响。
- 当性能是关键因素时,代理可能不是一个好的选择。
使用Javascript代理
- 当用户希望控制数据时,这些代理对象”target”、”handler”和”trap”将非常有用。
- 用户能够观察项目并确保它们执行其预期职责。
- 用于监视异步操作、验证数据和使用REST API。
- 还用于类型检查和可撤销引用。
- 在JavaScript的DOM文档对象模型的实现中使用。
Proxy()陷阱
有三个Proxy()陷阱可以用于运行数组、枚举或其他多个数据:
- get()陷阱
- set()陷阱
- apply()陷阱
- delete()陷阱
“get()”陷阱
当使用代理对象访问目标对象的属性时,将触发get()陷阱。
当proxyUser对象访问一个用户对象的属性时,将显示一条消息作为输出。
在大多数情况下,当访问属性时,您可以创建自己的自定义逻辑并将其放入get()陷阱中。
示例:
该示例展示了使用代理函数的get陷阱来获取数据。
<!DOCTYPE html>
<html>
<head>
<title> JavaScript Proxy </title>
</head>
<body>
<h3> JavaScript Proxy() </h3>
<p> Javascript proxy() shows data with the handler using function. </p>
<script>
const studentInfo = {
goodName: 'JavaTpoint',
mode: 'WebSite'
}
const handler_variable = {
get(target_variable, property_variable) {
return property_variable === 'fullData' ?
`{target_variable.goodName}{target_variable.mode}` :
target_variable[property_variable];
}
};
const proxy_variable = new Proxy(studentInfo, handler_variable);
document.write(proxy_variable.fullData);
</script>
</body>
</html>
输出
该图像使用代理获取陷阱显示数据。
set()陷阱
当设置对象的属性时,set()陷阱调节对象的行为。
示例
set()陷阱用于设置值和条件。该值使用set()方法和条件来显示。
<!DOCTYPE html>
<html>
<head>
<title> JavaScript Proxy </title>
</head>
<body>
<h3> JavaScript Proxy()with set traps </h3>
<p> Javascript proxy() shows student data with the handler using function. </p>
<script>
const studentInfo = {
goodName: 'JavaTpoint',
mode: 'WebSite',
language: 'Javascript',
User: 'Student',
students: 6
}
const handler_variable = {
set(obj, prop, value) {
if ((prop === 'students') && ((value % 2) !== 0)) {
document.write('students must have an even number for pair like : ');
} else {
return Reflect.set(...arguments);
}
}
};
const proxy_variable = new Proxy(studentInfo, handler_variable);
proxy_variable.students = 1;
document.write(proxy_variable.students);
document.write("<br>");
proxy_variable.students = 8;
document.write(proxy_variable.students);
</script>
</body>
</html>
输出
图像使用代理设置陷阱展示数据。
apply()陷阱
handler.apply()功能是一个诡计,通过它让你调用一个函数。
示例
apply()陷阱用来设置值和条件。使用javascript中的apply()方法以大写和小写格式显示数据。
<!DOCTYPE html>
<html>
<head>
<title> JavaScript Proxy </title>
</head>
<body>
<h3> JavaScript Proxy()with apply traps </h3>
<p> Javascript proxy() shows student data with the handler using function. </p>
<script>
const employee = {
subject: 'Javascript',
website: 'Javatpoint'
}
const getemployeeName = function (employee) {
return `{employee.subject}{employee.website}`;
}
const Proxy1 = new Proxy(getemployeeName, {
apply(target, thisArg, args) {
return target(...args).toUpperCase();
}
});
const Proxy2 = new Proxy(getemployeeName, {
apply(target, thisArg, args) {
return target(...args).toLowerCase();
}
});
document.write(Proxy1(employee)+ "<br>");
document.write(Proxy2(employee));
</script>
</body>
</html>
输出
此图显示使用代理设置陷阱的数据。
delete()的陷阱
当删除属性时,等等,你们可以深入探讨这些陷阱。使用Handler.delete()方法可以捕获删除操作符的陷阱。始终返回一个布尔值。这显示了是否实际删除了打算删除的项。
示例
使用javascript删除代理属性的delete()陷阱。
<!DOCTYPE html>
<html>
<head>
<title> JavaScript Proxy </title>
</head>
<body>
<h3> JavaScript Proxy() with delete traps </h3>
<p> Javascript proxy() shows student data with the handler using function. </p>
<script>
const proxy_variable = new Proxy({}, {
deleteProperty: function(target_var, prop_var) {
if (prop_var in target_var){
delete target_var[prop_var]
document.write('<br> Property is deleted: ' + prop_var+ "<br>")
return true
}
else {
document.write('<br> Poperty does not exist after deleting: ' + prop_var)
return false
}
}
})
let first_var
proxy_variable.subject = "JavaScript"
document.write('subject' in proxy_variable)
first_var = delete proxy_variable.subject
console.log(first_var)
document.write('subject' in proxy_variable)
first_var = delete proxy_variable.subject
console.log(first_var)
</script>
</body>
</html>
输出
图像显示了代理函数的已删除属性。
其他JavaScript陷阱
其他陷阱包括以下内容:
- construct – 用于new操作符的陷阱。针对new操作符的函数Handler.construct()使程序员能够创建对象的实例。
- getPrototypeOf – 用于拦截对”[[GetPrototypeOf]]”的内部调用。
- setPrototypeOf – 用于调用”Object.setPrototypeOf”。
- isExtensible – 该陷阱用于调用”Object.isExtensible”。
- preventExtensions – 这些陷阱用于调用”Object.preventExtensions”。
- getOwnPropertyDescriptor – 该陷阱用于调用”Object.getOwnPropertyDescriptor”。
带键的JavaScript代理(proxy)函数
“for”循环使用JavaScript代理函数和其数据显示代理数据的属性。我们可以在循环中使用代理变量和临时变量。它显示无值的目标属性。
示例
该示例显示了代理目标的可用属性。
<!DOCTYPE html>
<html>
<head>
<title> JavaScript Proxy </title>
</head>
<body>
<h3> JavaScript Proxy() with Key and Value </h3>
<p> Javascript proxy() shows required data with the handler using function. </p>
<script>
const studentInfo = {
Website: 'JavaTpoint',
mode: 'online',
subject: 'javascript'
}
const handler_variable = {
};
const proxy_variable = new Proxy(studentInfo, handler_variable);
for (var lang in proxy_variable){
document.write(lang+" : "+ proxy_variable [lang]+"<br>");
}
</script>
</body>
</html>
输出
图像显示了代理函数的关键属性。
JavaScript中的数组代理重载
“has”陷阱停止使用“in”函数来查看对象中是否存在属性的方法。
示例
该示例使用代理重载函数显示可用的属性及其值。
<!DOCTYPE html>
<html>
<head>
<title> JavaScript Proxy </title>
</head>
<body>
<h3> JavaScript Proxy() with overloading </h3>
<p> Javascript proxy() shows required data with the handler using function. </p>
<script>
function makeArray(arr_var) {
return new Proxy(arr_var, {
has: function (target_var, prop_var) {
return target_var.includes(prop_var);
}
});
};
const myMakeArray = makeArray(['hot', 'spicy', 'sweet', 'bitter']);
document.write('sweet' in myMakeArray);
document.write("<br>");
document.write('cool' in myMakeArray);
document.write("<br>");
document.write('hot' in myMakeArray);
</script>
</body>
</html>
输出
图片显示了代理函数的过载属性。
JavaScript 代理枚举
我们可以使用enumerate拦截for…in自ES6开始的标准版本; 但是我们不能执行这个任务。enumerate方法的返回值必须是一个对象。
示例
示例展示了可用属性及其值,使用代理枚举函数。
<!DOCTYPE html>
<html>
<head>
<title> JavaScript Proxy </title>
</head>
<body>
<h3> JavaScript Proxy() with enumeration </h3>
<p> Javascript proxy() shows student data with the enumerate function. </p>
<script>
const studentInfo = {
Website: 'JavaTpoint',
mode: 'online',
subject: 'javascript',
user : 'developers'
}
const handler_variable = {
enumerate: function (target_data) {
document.write(target_data, 'enumerating');
return Object.keys(target_data).filter(key=> !/\d|[A-Z]/.test(key)).sort()[Symbol.iterator]();
}
};
const proxy_variable = new Proxy(studentInfo, handler_variable);
for (var lang in proxy_variable){
document.write(lang+" : "+ proxy_variable [lang]+"<br>");
}
</script>
</body>
</html>
输出
该图显示了代理函数的枚举属性。
结论
JavaScript代理(proxy)有助于根据需求获取数组数据及其键值。使用JavaScript代理函数是处理哈希和数组值的简便方式。