自ES2015(又名“ES6”)规范以来,情况发生了变化:JavaScript现在有代理。代理允许您创建对象,这些对象是其他对象(立面)的真正代理。下面是一个简单的示例,该示例在检索时将字符串中的任何属性值全部大写,并返回而不是返回不存在的属性:"missing"
undefined
"use strict";
if (typeof Proxy == "undefined") {
throw new Error("This browser doesn't support Proxy");
}
let original = {
example: "value",
};
let proxy = new Proxy(original, {
get(target, name, receiver) {
if (Reflect.has(target, name)) {
let rv = Reflect.get(target, name, receiver);
if (typeof rv === "string") {
rv = rv.toUpperCase();
}
return rv;
}
return "missing";
}
});
console.log(`original.example = ${original.example}`); // "original.example = value"
console.log(`proxy.example = ${proxy.example}`); // "proxy.example = VALUE"
console.log(`proxy.unknown = ${proxy.unknown}`); // "proxy.unknown = missing"
original.example = "updated";
console.log(`original.example = ${original.example}`); // "original.example = updated"
console.log(`proxy.example = ${proxy.example}`); // "proxy.example = UPDATED"
未覆盖的操作具有其默认行为。在上面,我们覆盖的只是 ,但是您可以挂接到一个完整的操作列表。get
在处理程序函数的参数列表中:get
-
target
是被代理的对象(在我们的例子中)。original
-
name
(当然)是要检索的属性的名称,它通常是一个字符串,但也可以是一个符号。
-
receiver
是应该在 getter 函数中使用的对象,如果该属性是访问器而不是数据属性。在正常情况下,这是代理或从它继承的东西,但它可以是任何东西,因为陷阱可能是由 触发的。this
Reflect.get
这使您可以使用所需的捕获所有 getter 和 setter 功能创建对象:
"use strict";
if (typeof Proxy == "undefined") {
throw new Error("This browser doesn't support Proxy");
}
let obj = new Proxy({}, {
get(target, name, receiver) {
if (!Reflect.has(target, name)) {
console.log("Getting non-existent property '" + name + "'");
return undefined;
}
return Reflect.get(target, name, receiver);
},
set(target, name, value, receiver) {
if (!Reflect.has(target, name)) {
console.log(`Setting non-existent property '${name}', initial value: ${value}`);
}
return Reflect.set(target, name, value, receiver);
}
});
console.log(`[before] obj.example = ${obj.example}`);
obj.example = "value";
console.log(`[after] obj.example = ${obj.example}`);
以上输出为:
Getting non-existent property 'example'
[before] obj.example = undefined
Setting non-existent property 'example', initial value: value
[after] obj.example = value
请注意,当我们尝试检索“不存在”消息时,以及当我们创建它时,我们如何再次获得“不存在”消息,但在此之后不会。example
2011年的答案(上述内容已过时,仍然与仅限于ES5功能(如Internet Explorer)的环境相关):
不,JavaScript 没有包罗万象的属性功能。您正在使用的访问器语法在规范的第 11.1.5 节中进行了介绍,并且不提供任何通配符或类似内容。
当然,你可以实现一个函数来做到这一点,但我猜你可能不想使用而不是(这对于函数处理未知属性是必要的)。f = obj.prop("example");
f = obj.example;
obj.prop("example", value);
obj.example = value;
FWIW,getter函数(我没有打扰设置器逻辑)看起来像这样:
MyObject.prototype.prop = function(propName) {
if (propName in this) {
// This object or its prototype already has this property,
// return the existing value.
return this[propName];
}
// ...Catch-all, deal with undefined property here...
};
但同样,我无法想象你真的想这样做,因为它改变了你使用对象的方式。