对对象执行赋值操作

时间:2013-10-22 23:34:50

标签: javascript

示例JSFiddle,以便您可以更好地了解http://jsfiddle.net/brsXL/3/的内容(打开控制台并查看记录的vars对象)。

我正在为JavaScript中的特定数学子集构建解析器和计算机,它将表达式作为用户的字符串,并允许它们使用变量。为了保持我的计算逻辑简单但允许使用变量,我创建了一个对象,其行为类似于数字但具有通过引用传递的奖励。

var Variable = function(value) {
    this.value = value || null;
}
Variable.prototype.valueOf = function() {
    return this.value;
}

这样可以:

var a = new Variable(10);
console.log(a + 2); // = 12
console.log(a / 2); // = 5

但是,只要我希望执行任何形式的赋值操作(例如+=),对象就会丢失,并被对象的value属性的操作结果替换。 e.g。

var a = new Variable(10);
console.log(a += 2); // = 12
console.log(a); // = 12

我需要它像这样工作的原因是因为我想使用相同的函数来处理数字和变量。我可以为每个赋值操作添加代码,但这对我来说感觉不太理想,例如

var ops = {
   "+=" : function(a, b) {
      if (a instanceof Variable) {
         a.value += b;
      } else {
         a += b;
      }
      return a;
   },
   ...
}

但我更愿意写:

var ops = {
   "+=" : function(a, b) {
      return a += b;
   },
   ...
}

可以这样做吗?

1 个答案:

答案 0 :(得分:4)

  

我更愿意写:

function(a, b) {
    return a += b;
}
     

可以这样做吗?

没有。将Reference值作为单个变量传递是不可能的。您始终需要使用对象属性。 a在您的函数中始终是本地范围的,因此更改它不会影响外部世界。而且我不鼓励你试图让你的运算符函数在更高范围的变量上运行......

我认为在你的情况下,对变量使用显式测试是很好的,因为赋值运算符来实际执行。您不能仅将文字或其他值分配给变量。它甚至可能是

var ops = {
   "=" : function(a, b) {
      if (a instanceof Variable) {
         a.value = +b; // cast b to a number (from whatever it is)
         return a;
      } else {
         throw new Error("Invalid assignment to non-variable "+a);
      }
   },
   ...
}

另外,为避免代码重复,您可能无法写出所有复合赋值运算符。以通用方式定义它们:

["+", "-", "*", "/"].forEach(function(op) {
    ops[op+"="] = function(a, b) {
        return ops["="].call(this, a, ops[op].call(this, a, b));
    };
});

Updated jsfiddle demo