8

http://jsfiddle.net/brsXL/3/で何が起こっているかをよりよく理解できるように、JSFiddle の例を示します (コンソールを開き、ログに記録された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

+=ただし、オブジェクトが失われ、オブジェクトの値プロパティに対する操作の結果に置き換えられるなど、何らかの形式の代入操作を実行したい場合はすぐに。例えば

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

これはできますか?

4

1 に答える 1

4

私はむしろ書きたい:

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

これはできますか?

いいえ。参照値を単一の変数として渡すことはできません。常にオブジェクト プロパティを使用する必要があります。a関数では常にローカルスコープであるため、変更しても外部の世界には影響しません。そして、より高いスコープの変数を操作する演算子関数を作成しようとしないことをお勧めします…</p>

あなたの場合、代入演算子実際にそれを行う必要があるため、変数に明示的なテストを使用しても問題ないと思います。リテラルやその他の値に代入することはできません。変数にのみ代入できます。そうかもしれない

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

( jsfiddle デモを更新)

于 2013-10-23T11:44:52.657 に答える