JavaScript对象:属性名的反向引用

5
我正在尝试简化javascript对象内容的创建,以便值取决于成员名称,类似于以下示例:
var obj = {
    1: "you selected 1",
    2: "wow, you selected 2",
    3: "this time, you selected " + myName(), //myName() gets resolved to 3
    137: "I think you've chosen " + myName() + " this time.", //myName() gets resolved to 137
    513: myName() + " is the answer!" //myName() gets resolved to 513
};

是否可能在值的定义中引用成员名称,使用类似于所谓函数 myName()的东西来进行反向引用?

如果没有本地方法存在,那么推荐实现此功能的方法是什么?

你可能会问"这家伙为什么需要这种奇怪的对象生成方式?",答案是:在我的代码中,成员/字段名可能会更改,将使用默认值进行复制,唯一不同之处就是对成员名称的引用,我不想在每个键值对中两次定义数字值,因此我正在寻找一种在值的定义中进行反向引用的方法来引用名称。


1
所以基本上你想要在值中获取对象的键对吧? 就像 obj ={ "dave" : "my name is "+key} 这里的 key 将会被解析为 dave。 - Dave Ranjan
是的,我希望该值能够获取键。'键'将是相同的关键字,但对于具有不同键的值,将返回不同的数字。 - Eduardo Poço
我一直在考虑使用特殊字符串,比如“@key@”,然后再替换它,但是有可能会有人想在值中使用字符串“@key@”,最终导致代码注入的风险。 - Eduardo Poço
听起来不错,但我不想让我们的密钥硬编码。我们如何在不硬编码的情况下将其发送到函数中呢? - Dave Ranjan
如果您事先知道键,那么您可以这样做:obj[key] = 'blabla' + key吗? - yBrodsky
嗯,是的,但是...抱歉,我没能解释清楚key不一定出现在value的末尾。我会编辑问题来解决这个问题。 - Eduardo Poço
2个回答

2
你正在寻找一个ES6的特性,Proxy

Proxy对象用于定义基本操作(例如属性查找、赋值、枚举、函数调用等)的自定义行为。

然后使用实际键值来取代占位符{key},获取prop中的实际键值。

var obj = {
        1: "you selected {key}",
        2: "wow, you selected {key}",
        3: "this time, you selected {key}",
        137: "I think you've chosen {key} this time.",
        513: "{key} is the answer!"
    },
    p = new Proxy(obj, {
        get: function(target, prop) {
            return target[prop] && target[prop].replace("{key}", prop);
        }
    });

console.log(p[3]);          // this time, you selected 3
console.log(p[137]);        // I think you've chosen 137 this time.
console.log(p[513]);        // 513 is the answer!
obj.foo = 'This is {key}!'; // create new property foo
console.log(p.foo);         // This is foo!
obj.bar = obj.foo;          // assign foo to bar
delete obj.foo;             // delete foo
console.log(p.foo);         // undefined
console.log(p.bar);         // This is bar!


1
我无法理解代理的好处。似乎只需使用替换即可完成工作。该解决方案保留了“{key}”子字符串。如果没有解决方案能够逃逸到代码而不是保留字符串,我将接受您的解决方案。 - Eduardo Poço
@EduardoPoço,代理有权访问被调用属性的名称。 - Nina Scholz
哦,现在我明白了,替换是在请求值时进行的。原始对象保留了子字符串“{key}”,因此只有通过代理访问对象的外部代码才能看到替换,对吧?所以这就是为什么它被称为代理的原因! - Eduardo Poço
@EduardoPoço,没错。代理的get方法被调用,并且实际的键值被替换。 - Nina Scholz

0

毕竟,我找到了一种实现我的愿望的方法,如果还有人感兴趣的话。

我使用了值中的函数而不是字符串。这些函数进行计算并返回值,根据函数在需要的键处使用它们。所以它变成了:

var obj = {
    1: function(key){return "you selected 1";},
    2: function(key){return "wow, you selected 2";},
    3: function(key){return "this time, you selected " + key;},
    137: function(key){return "I think you've chosen " + key + " this time.";},
    513: function(key){return key + " is the answer!";}
};

function getValue(key) {
    return obj[key](key);
}

要调用该值,请使用:

var value = getValue(137);

没有任何字符串被保留作替换,因为操作者(也就是我自己)对此非常谨慎。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接