ウェブサイト検索

ecmascript 6 - クラス内での 'this' キーワードの使用をすべて排除する


私はTraceurを使って、今すぐ将来のJavaScriptを書けるようにしており、これは私がいくつかのクラスに持っている関数です

create() {
    this.game.physics.startSystem(Phaser.Physics.ARCADE);

    this.segmentcache = new SegmentCache(this.game);
    this.segments = new Segments(this.game);
    this.segments.cache = this.segmentcache;
    this.segments.seek(3);

    this.guy = new Guy(this.game, 140 + 8, 80);
    this.guy.anchor.set(0.5, 1.0);
    this.game.add.existing(this.guy);

    this.game.camera.x = 100;
    this.ticks = 0;
    this.cross = 0;
}

もちろん、従来のJavaScriptコードと同様に、至る所で this キーワードが使われています。Java などから来た私にとって、クラス内のフィールドを参照するときに this を指定しなければならないのは、とても不自然です。

Traceur に Java と同じ方法でクラスを解釈させる方法はありますか?(例:指定しない場合に自動的に this を挿入するなど)

回答 #1

私の知る限りでは、いいえ。

Java、C#、C++などでは、これは実行時のものではなくコンパイラの機能です。つまり、これは暗黙的に行われ、コンパイラが行うのは正しいアドレスをthisに入れ、変数を正しい方法で参照することです。ほとんどのコンパイラには、もし同じ名前のローカル変数(ローカルスコープ内)を持っている場合、それがメンバー変数より優先されるというルールがあります。

JavaScriptでは、call、apply、bindを使ってthisを簡単に置き換え、関数が作者が意図していないオブジェクトに対して呼び出されるようにすることができます(つまり、thisは異なる構造を持つオブジェクトである可能性があります)。そして、これが言語の構文が、スコープかthisを参照しているかを常に明示的に指定することを要求する理由だと思います。

JavaScriptの関数本体では実際にはグローバルスコープを読むことができるので、window.member(ブラウザの場合)を定義すると、明示的にthisを使用しない場合、関数の動作が変わる可能性があります

回答 #2

私の知る限り、ES6にはそのような機能はありません。

このタイプの機能は、Javascriptが親スコープの変数を参照できることによって複雑になります。したがって、次のようなコード行がある場合、それをどう識別するかを何らかの方法で判断しなければなりません:

ticks = 0;

手段

this.ticks = 0;

または、それが現在のスコープまたは親スコープの変数を ticks という名前で参照することを意味するのかどうか。

オブジェクトにプロパティを追加するだけで、以前は問題なく動作していたコードが、同じ名前のプロパティ参照とローカル変数または親スコープの変数との間に競合が生じることで混乱する可能性があります。それはおそらく大混乱になるでしょう。今では、プロパティ名との競合を避けるために、ローカル変数に名前空間を付ける必要があります。そして、ローカル変数にスコープを付ける必要がある場合、あなたが取り除こうとしていた余分な構文を再び導入していることになります。

Java はこれを許容できます。なぜなら、コンパイラは事前にすべてのプロパティ名を知っているため、衝突があればエラーを報告できるからです。JavaScript は動的に追加されるプロパティ(いつでも追加可能)を許容するため、パーサは解析時に特定のオブジェクトにどのプロパティ名があるかを実際には把握できず、衝突について警告することができません。これは単に言語のパース/コンパイルや動作方法の本質的な違いであり、そのためコードの表現においていくつか異なる機能や要件が生じます。

with構造を使用してタイプ入力を避けることは可能ですが、withはここに詳しく説明されている理由でJavascriptから削除されつつあり(strictモードでは許可されていません)、改善されたわけではないため、推奨される方法ではありません。