【问题标题】:Javascript Object Properties Calculated (on the fly) from Other Object Properties从其他对象属性计算(即时)的 Javascript 对象属性
【发布时间】:2015-04-22 04:06:29
【问题描述】:

我正在尝试创建一个 javascript 对象来计算其上设置的属性的各种值。我已经编译了这个我想要实现的简单示例:JSFIDDLE

var obj = {};
obj.a = 2;
obj.b = 5;
obj.avg = "(obj.a + obj.b)/2"; 
obj.rounded = "Math.floor(eval(obj.avg))";

console.log("rounded avg: " + eval(obj.rounded));
//simulate changing properties
obj.a = Math.floor(Math.random() * 10);
obj.b = Math.floor(Math.random() * 10);
console.log("rounded avg: " + eval(obj.rounded));

上面的代码目前实现了我想要的(使用标准设置值,如 'a' 和 'b' 来计算 'avg',然后在第二次计算中使用 'avg' 'rounded')。

有没有更好的方法来实现这一点(理想情况下,只要在另一个属性中引用计算的属性时,就不需要 eval() 调用)。

我希望计算的属性像函数一样工作(每当引用它们时计算它们的值),而不是最初计算它们的值并且不改变 - 我想避免必须使用 () 来调用函数(这样我就可以以相同的方式引用普通值和计算值 - 只是通过它们的属性名称)。

【问题讨论】:

    标签: javascript javascript-objects


    【解决方案1】:

    不要使用eval,而是使用如下函数:

    var obj = {};
    obj.a = 2;
    obj.b = 5;
    obj.avg = function() { return (this.a + this.b) / 2; };
    obj.rounded = function() { return Math.floor(this.avg()); };
    
    console.log("rounded avg: " + obj.rounded());
    obj.a = Math.floor(Math.random() * 10);
    obj.b = Math.floor(Math.random() * 10);
    console.log("rounded avg: " + obj.rounded());

    如果您不必支持旧浏览器,为了避免在调用函数时必须使用括号,您可以使用getters,如下所示:

    var obj = {
      a: 2,
      b: 5,
      get avg() { return (this.a + this.b) / 2; },
      get rounded() { return Math.floor(this.avg) }
    }
    
    console.log("rounded avg: " + obj.rounded);
    obj.a = Math.floor(Math.random() * 10);
    obj.b = Math.floor(Math.random() * 10);
    console.log("rounded avg: " + obj.rounded);

    【讨论】:

    • 当然,但是 OP 说“我想避免使用 () 来调用函数”。
    • @torazaburo 我“明白”了 :-)
    • @RobbyCornelissen Ha,现在我 get 它 — “得到”……
    • @RobbyCornelissen 感谢您提供非常完整的答案。我真的很想使用“getter”语法,但不幸的是我需要支持 IE8,所以看起来我被这些功能困住了。这是我更新的FIDDLE,显示了我从您的答案中一起工作的解决方案(基本上我使用'_val'来命名普通值并设置访问器函数,以便我可以使用通用的函数样式语法引用计算值中的属性)
    【解决方案2】:

    如果您不需要支持 Internet Explorer 8 或更低版本,请使用 Getters

    var obj = {
      a:2,
      b:5,
      get avg(){
        return (this.a + this.b)/2;
      }, 
      get rounded(){
        return Math.floor(this.avg);
      }
    }
    

    用法:

    obj.a; // returns 2
    obj.b; // returns 5
    obj.avg; // returns 3.5
    obj.rounded; // returns 3
    

    【讨论】:

    • 感谢您的回答。我真的希望我可以使用 getter 语法,但我需要支持 IE8。
    【解决方案3】:

    看来您是在追求所谓的计算属性。这是一个在请求时计算的变量。在 Javascript 中,您可以使用 Object Getter/Setter Syntax

    【讨论】:

    • 第一次阅读这个问题时,我想到了计算属性名称……obj=({[propname]:6}).
    • @Xufox 为什么要在对象周围加上括号?
    • @torazaburo 有时我会收到“SyntaxError: missing ; before 语句”在没有赋值的情况下将对象写入控制台时……为了安全起见……
    • 单独来说,是的,您需要括号,否则{ 将被解释为块的开头。在分配的右侧,块无法到达,不需要。随便。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    • 2015-09-20
    • 1970-01-01
    • 2015-02-12
    相关资源
    最近更新 更多