2013年和2015年更新 (请参阅下面的2011年原始答案) :
从ES2015(又称“ ES6”)规范开始,此更改已更改:Javascript现在具有代理。代理使您可以创建真正的对象(作为其他对象的外观)。这是一个简单的示例,该示例将所有字符串形式的属性值转换为所有大写形式:
"use strict";if (typeof Proxy == "undefined") { throw new Error("This browser doesn't support Proxy");}let original = { "foo": "bar"};let proxy = new Proxy(original, { get(target, name, receiver) { let rv = Reflect.get(target, name, receiver); if (typeof rv === "string") { rv = rv.toUpperCase(); } return rv; }});console.log(`original.foo = ${original.foo}`); // "original.foo = bar"console.log(`proxy.foo = ${proxy.foo}`); // "proxy.foo = BAR"
您未覆盖的 *** 作具有其默认行为。在上面,我们要覆盖的全部是
get,但是有一个可以挂接的 *** 作的完整列表。
在
get处理程序函数的参数列表中:
target
是要代理的对象(original
在本例中为)。name
(当然)是要检索的属性的名称,通常是一个字符串,但也可以是一个符号。receiver``this
如果属性是访问器而不是数据属性,则是应该在getter函数中使用的对象。在正常情况下,这是代理或继承自代理的东西,但是 可以 是任何东西,因为陷阱可能由触发Reflect.get
。
这使您可以使用所需的全部获取和设置器功能创建对象:
"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.foo = ${obj.foo}`);obj.foo = "bar";console.log(`[after] obj.foo = ${obj.foo}`);
上面的输出是:
获取不存在的属性“ foo”[之前] obj.foo =未定义设置不存在的属性'foo',初始值:bar[之后] obj.foo = bar
请注意,当我们尝试检索
foo尚不存在的消息以及创建它时(而不是之后创建)时,如何获取“不存在”消息。
2011年的答案 (请参见上面的2013年和2015年更新) :
不,Javascript不具有全部属性功能。规范的第11.1.5节介绍了您使用的访问器语法,并且不提供任何通配符或类似的内容。
当然,您可以实现一个函数来执行此 *** 作,但是我猜您可能不想使用
f = obj.prop("foo");而不是
f =obj.foo;和(
obj.prop("foo", value);而不是)
obj.foo = value;(该函数必须使用该函数来处理未知属性)。
FWIW,getter函数(我不关心setter逻辑)看起来像这样:
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...};
但是再次,我无法想象您真的想这样做,因为它如何改变您使用对象的方式。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)