WebKit HTML 5 SQL Storage Notes Demo のソースには次のようなものがあります:
function Note() {
var self = this;
var note = document.createElement('div');
note.className = 'note';
note.addEventListener('mousedown', function(e) { return self.onMouseDown(e) }, false);
note.addEventListener('click', function() { return self.onNoteClick() }, false);
this.note = note;
// ...
}
著者はselfをいくつかの場所(関数本体)で使用し、this他の場所(メソッドの引数リストで定義された関数の本体)。どうしたの?一度気づいたので、どこでも見られるようになりますか?
こちらをご覧ください alistapart.comの記事
self
は、コンテキストが変更されている場合でも、元のthis
への参照を維持するために使用されています。これは、イベントハンドラー(特にクロージャー)でよく使用される手法です。
現代のブラウザは、通常のウィンドウまたはWebWorkerのグローバルオブジェクトを指す グローバル変数self
を提供するため、変数名「self」はこの方法で使用しないでください。
混乱と潜在的な競合を避けるために、代わりにvar thiz = this
またはvar that = this
を記述できます。
はい、どこでも見ることができます。多くの場合、that = this;
です。
イベントによって呼び出される関数内でself
がどのように使用されるかを確認しますか?これらには独自のコンテキストがあるため、self
を使用して、Note()
に入ったthis
を保持します。
Note()
関数の実行が終了した後にのみ実行できる場合でも、self
が関数で引き続き使用できる理由は、内部関数がにより外部関数のコンテキストを取得するためですclosure.
var self = this
イディオムが嫌いな場合は、コールバックで元のthis
への参照を維持するための代替プロキシパターンがあることにも注意してください。
function.apply
またはfunction.call
を使用して関数を特定のコンテキストで呼び出すことができるため、特定のコンテキストを使用してapply
またはcall
で関数を呼び出す関数を返すラッパーを作成できます。このパターンの実装については、jQueryのproxy
関数を参照してください。以下に使用例を示します。
var wrappedFunc = $.proxy(this.myFunc, this);
その後、wrappedFunc
を呼び出して、コンテキストとしてthis
のバージョンを使用できます。
JavaScriptの癖です。関数がより適切にメソッドと呼ばれるオブジェクトのプロパティである場合、thisはオブジェクトを参照します。イベントハンドラの例では、包含オブジェクトはイベントをトリガーした要素です。標準関数が呼び出されると、thisはグローバルオブジェクトを参照します。例のように関数をネストしている場合、thisは外部関数のコンテキストにまったく関係しません。内部関数は包含関数とスコープを共有するため、開発者はvar that = this
のバリエーションを使用して、内部関数で必要なthisを保持します。
変数は、メソッドで定義されたインライン関数によってキャプチャされます。関数内のthis
は、別のオブジェクトを参照します。このようにして、外部スコープのthis
への参照を関数に保持させることができます。
他の人が説明したように、var self = this;
は、 closure のコードが親スコープを参照することを許可します。
ただし、現在は2018年であり、ES6はすべての主要なWebブラウザーで広くサポートされています。 var self = this;
イディオムは、以前ほど重要ではありません。
arrow functions を使用することで、var self = this;
を回避できるようになりました。
var self = this
を使用した場合:
function test() {
var self = this;
this.hello = "world";
document.getElementById("test_btn").addEventListener("click", function() {
console.log(self.hello); // logs "world"
});
};
var self = this
なしで矢印関数を使用できるようになりました。
function test() {
this.hello = "world";
document.getElementById("test_btn").addEventListener("click", () => {
console.log(this.hello); // logs "world"
});
};
矢印関数には、独自のthis
がなく、単に囲みスコープを想定します。
実際、selfはウィンドウ(window.self
)への参照です。したがって、var self = 'something'
と言うと、selfがウィンドウオブジェクトに存在するため、それ自体へのウィンドウ参照をオーバーライドします。
これが、ほとんどの開発者がvar that = this
よりもvar self = this;
を好む理由です。
とにかく; var that = this;
はグッドプラクティスに沿っていません...あなたのコードが他の開発者によって後で修正/修正されることを前提として、開発者コミュニティに関して最も一般的なプログラミング標準を使用する必要があります
したがって、var oldThis
/var oThis
/などのようなものを使用する必要があります-スコープ内で明確にするために// ..はそれほどではありませんが、数秒と少数の脳サイクルを節約します
上記で何度か言及したように、「自己」は、関数に入る前に「これ」への参照を維持するために単に使用されています。関数の中にある「this」は何か他のものを指します。