是否可以在JavaScript中实现动态获取器设置器?

是否可以在JavaScript中实现动态获取器设置器?,第1张

是否可以在JavaScript中实现动态获取器/设置器?

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...};

但是再次,我无法想象您真的想这样做,因为它如何改变您使用对象的方式。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5509199.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-13
下一篇 2022-12-13

发表评论

登录后才能评论

评论列表(0条)

保存