共计 2310 个字符,预计需要花费 6 分钟才能阅读完成。
点击在线浏览,体验更好 | 链接 |
---|---|
古代 JavaScript 高级小册 | 链接 |
深入浅出 Dart | 链接 |
古代 TypeScript 高级小册 | 链接 |
深刻了解 Proxy
在古代 JavaScript 中,Proxy 是一种十分有用的个性,它容许咱们在许多惯例操作中插入自定义行为。然而,因为其深度和复杂性,很多开发者可能会对如何应用它或它的工作原理感到困惑。在本篇文章中,咱们将具体探讨 JavaScript Proxy,并通过代码示例演示其应用。
Proxy 是什么?
在 JavaScript 中,Proxy 是一个非凡的“包装器”对象,它能够用于批改或扩大某些基本操作的行为,比方属性读取、函数调用等。这种批改或扩大的行为是通过所谓的 ”traps” 实现的,这些 ”traps” 定义了如何拦挡和扭转基本操作。
以下是一个简略的例子,显示了如何应用 Proxy 拦挡对象的属性读取操作:
let target = {name: "target"};
let proxy = new Proxy(target, {get: function(target, property) {return property in target ? target[property] : "Default";
}
});
console.log(proxy.name); // 输入 "target"
console.log(proxy.unknown); // 输入 "Default"
在下面的例子中,当咱们尝试从 proxy 读取不存在的属性时,咱们失去了 ”default”,而不是通常的 ”undefined”。这是因为咱们的 ”get” trap 拦挡了读取操作,并返回了默认值。
Proxy 的用处
Proxy 有许多用处,上面是一些常见的例子:
数据校验
Proxy 能够用于校验设置对象属性的值:
let validator = {set: function(target, property, value) {if (property === "age") {if (!Number.isInteger(value)) {throw new TypeError("The age is not an integer");
}
if (value < 0 || value > 200) {throw new RangeError("The age is invalid");
}
}
target[property] = value;
return true;
}
};
let person = new Proxy({}, validator);
person.age = 100; // 失常
console.log(person.age); // 输入 100
person.age = "young"; // 抛出 TypeError: The age is not an integer
person.age = 300; // 抛出 RangeError: The age is invalid
数据绑定和察看
Proxy 能够用于实现数据绑定和察看(数据变动的监听):
let handler = {set: function(target, property, value) {console.log(`${property} is set to ${value}`);
target[property] = value;
return true;
}
};
let proxy = new Proxy({}, handler);
proxy.name = "proxy"; // 输入 "name is set to proxy"
函数参数的默认值
Proxy 能够用于给函数参数设置默认值:
function defaultValues(target, defaults) {
return new Proxy(target, {apply: function(target, thisArg, args) {args = args.map((arg, index) => arg === undefined ? defaults[index] : arg);
return target.apply(thisArg, args);
}
});
}
let add = defaultValues(function(x, y) {return x + y;}, [0, 0]);
console.log(add(1, 1)); // 输入 2
console.log(add(undefined, 1)); // 输入 1
console.log(add(1)); // 输入 1
以上仅仅是 Proxy 能做的事件的一部分。在理论开发中,你能够依据须要灵便应用 Proxy。
Proxy vs Reflect
在 ES6 中引入了另一个新的全局对象 Reflect
,它提供了一组用于执行 JavaScript 基本操作的办法,例如Reflect.get()
,Reflect.set()
等。这些办法与 Proxy 的 traps 一一对应。这使得 Proxy 的 traps 能够应用对应的 Reflect 办法来执行被拦挡的操作:
let proxy = new Proxy(target, {get: function(target, property) {return Reflect.get(target, property);
}
});
Reflect 的办法有许多长处。首先,它们总是返回一个冀望的值,使得代码更易于了解和调试。其次,它们提供了一种正确处理 JavaScript 基本操作的办法。例如,应用 Reflect.set()
能够正确处理设置只读属性的状况。
论断
JavaScript Proxy 是一个十分弱小的工具,它为批改和扩大基本操作提供了可能性。尽管在某些状况下,应用 Proxy 可能会让代码变得更简单,但在解决某些简单问题时,如数据绑定和察看、操作拦挡和校验等,它的劣势就显现出来了。了解和把握 Proxy 能够让你的 JavaScript 代码更具备扩展性和灵活性。