[解決済み] Javascript: 演算子のオーバーローディング
質問
JavaScriptを使い始めて数日経ちますが、定義したオブジェクトに対して演算子をオーバーロードしたいという状況になりました。
Googleで検索してみたところ、公式にはできないようですが、このアクションを実行するための長ったらしい方法を主張している人が何人かいるようです。
基本的にはVector2クラスを作り、以下のようなことができるようにしたいです。
var x = new Vector2(10,10);
var y = new Vector2(10,10);
x += y; //This does not result in x being a vector with 20,20 as its x & y values.
その代わり、こんなことをしなければならない。
var x = new Vector2(10,10);
var y = new Vector2(10,10);
x = x.add(y); //This results in x being a vector with 20,20 as its x & y values.
Vector2クラスで演算子をオーバーロードする方法はありますか?これは単に醜く見えるだけなので。
どのように解決するのですか?
お分かりのように、JavaScriptは演算子のオーバーロードをサポートしていません。最も近いのは
toString
(インスタンスを文字列に強制する必要があるときに呼び出されます) と
valueOf
(を使用する場合など、数値に変換するために呼び出されます。
+
を足し算に使う場合、あるいは多くの場合、連結に使う場合は
+
は連結の前に加算を行おうとします)、これはかなり限定的です。どちらも
Vector2
オブジェクトを生成します。同じように
Proxy
(ES2015 で追加) では、オブジェクトのさまざまな操作 (プロパティへのアクセスも含む) を傍受できますが、やはり
+=
で
Vector
インスタンスになります。
この質問に来る人の中で、結果として文字列や数値が欲しい人(代わりに
Vector2
の例です。
valueOf
と
toString
. これらの例
しない
は演算子のオーバーロードを示すもので、JavaScript に組み込まれたプリミティブへの変換処理を利用しているだけです。
valueOf
この例では、オブジェクトの
val
を経由してプリミティブに強制された場合、その応答として
+
:
function Thing(val) {
this.val = val;
}
Thing.prototype.valueOf = function() {
// Here I'm just doubling it; you'd actually do your longAdd thing
return this.val * 2;
};
var a = new Thing(1);
var b = new Thing(2);
console.log(a + b); // 6 (1 * 2 + 2 * 2)
あるいは、ES2015の
class
:
class Thing {
constructor(val) {
this.val = val;
}
valueOf() {
return this.val * 2;
}
}
const a = new Thing(1);
const b = new Thing(2);
console.log(a + b); // 6 (1 * 2 + 2 * 2)
あるいは、コンストラクターなしのオブジェクトだけで
var thingPrototype = {
valueOf: function() {
return this.val * 2;
}
};
var a = Object.create(thingPrototype);
a.val = 1;
var b = Object.create(thingPrototype);
b.val = 2;
console.log(a + b); // 6 (1 * 2 + 2 * 2)
toString
この例では、オブジェクトの
val
を経由してプリミティブに強制された場合などには、大文字に変換されます。
+
:
function Thing(val) {
this.val = val;
}
Thing.prototype.toString = function() {
return this.val.toUpperCase();
};
var a = new Thing("a");
var b = new Thing("b");
console.log(a + b); // AB
あるいは、ES2015の
class
:
class Thing {
constructor(val) {
this.val = val;
}
toString() {
return this.val.toUpperCase();
}
}
const a = new Thing("a");
const b = new Thing("b");
console.log(a + b); // AB
あるいは、コンストラクターなしのオブジェクトだけで
var thingPrototype = {
toString: function() {
return this.val.toUpperCase();
}
};
var a = Object.create(thingPrototype);
a.val = "a";
var b = Object.create(thingPrototype);
b.val = "b";
console.log(a + b); // AB
関連
-
[解決済み】SyntaxError: 'import' と 'export' は 'sourceType: module' とだけ表示されるかもしれない - Gulp
-
[解決済み】React.jsの配列の子要素のユニークキーを理解する
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] とは何ですか! (not not)演算子とは何ですか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
-
[解決済み】JavaScriptの比較では、どちらの等号演算子(== vs ===)を使うべきですか?
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】jquery $.ajaxオブジェクトのresponseJSONプロパティを取得する方法 [重複]。
-
[解決済み】XMLHttpRequestモジュールが定義されていない/見つからない
-
[解決済み】BootstrapのCollapseが折りたたまれない
-
[解決済み] [Solved] Uncaught TypeError: nullのプロパティ 'appendChild' を読み取ることができない。
-
[解決済み】SyntaxError: JSON の位置 1 に予期しないトークン o があります。
-
[解決済み】PhantomJS 2.1.1を使用してReactJSアプリケーションをレンダリングできない理由とは?
-
[解決済み】TypeError:res.jsonは関数ではありません。
-
[解決済み】Syntax error: JavaScriptの不正なreturnステートメント
-
[解決済み】Vueが定義されていない
-
[解決済み】中央値の計算 - javascript