2012-05-01 9 views
1

機能します。JavaScriptとjQueryのは、 "これは" anonymosの内側に、私はこのコードを持って

問題はconsole.log(this.url)undefinedを印刷したということでしたので、私はこのように見えるコードを作り直し:私は問題はインスタンスの値としてthisを取っていない閉鎖していたことを知っている

PageList.prototype.toHTML = function(){ 
    var div = $('<div class="container"></div>'); 
    var p = $('<p></p>'); 
    var link = $('<a></a>'); 
    var instance = this; 
    $.each(this.elements, function(index, array_value){ 
       console.log(instance.url); 
     } 
} 

が、限り、私はそれにバインドされたインスタンスではなくundefinedの、windowオブジェクトを参照する必要があります持っていない関数の内部thisへの参照を知っているように、少なくともそれはそこにブラウザの多くのケースです。

私のコードではどういうことが起こっているのですか?

注:私はjQueryのを使用していますし、this.elementsがすでに定義されています。

編集:今$.eachはので、私のコールバックは$.eachから呼び出されている、非インスタンス関数であることを考え出すイムそれはまだそれについて考えthisへの参照、windowでなければなりません。

+4

JavaScriptのスコープの世界へようこそ。 – epascarello

答えて

3

コールバック関数をhigher-order function(この場合は$.each)に設定すると、コールバックが実行されるときに上位の関数がthisの値を決定できます。この動作を制御する方法はありません。thisを使用しないでください(例:instanceのような参照を使用するか、クロージャを使用)。

$.eachのような高階関数は、コールバックのthisコンテキストを設定する方法を理解するために、状況設定機能Function.callFunction.applyをチェックしてください。それらのMDNページを読んだら、いくつかのことをクリアするかもしれません。

Array.prototype.forEachWithContext(callback, this_in_callback) { 
    for(var i = 0; i < this.length; ++i) { 
     callback.call(this_in_callback, i, this[i]); 
    } 
} 

そして、それを使用する::Array.forEachWithContextArray.forEachに似て

PageList.prototype.toHTML = function(){ 
    //... 
    this.elements.forEachWithCallback(function(index, array_value){ ... }, this); 
} 

私の例

は、ここでは簡単な例です。ただし、これらのコールバックの実行中にthisの値として使用されるコールバックの第2引数が必要です。

+0

私はcallとapplyの使い方を知っています。ちょうどこれを次のようにコーディングするのは難しいでしょう:$ .each.apply(this、...);私はjqueryとjsをこのような同じコマンドに混ぜるのは好きではありません。 – loki

+0

私のコードを使う必要はありません。jQueryがコールバックを使ってコールバックのコンテキストを変更する方法を説明しました。この場合、 '$ .each'は完全に処理可能です。既に持っている 'instance'でコードを使用してください。 'call' /' apply'を知っているので、私の答えの主な値はjQueryドキュメントの最初の引用です:** '$ .each'コールバックの中で、' this'は現在の配列要素**に設定されています。それはあなたが望んでいた説明です、と私は思います。 – apsillers

+0

あなたは正しいです、私はコンソール上の "オブジェクト"を見て、それがウィンドウオブジェクトを参照していると仮定しました。 – loki

1

$.proxythisが、私は問題は上にあったことを知っているあなたのPageList ...

+0

プロキシ機能に投票しても、そのような振る舞いを引き起こしている原因はまだ分かりません。 – loki

1

を参照することが保証されます

$.each(this.elements, $.proxy(function(index, array_value){ 
    console.log(this.url); 
},this)); 

...このような$.proxyであなたの$.each機能をラップしてみクロージャは、インスタンスの値としてこれを取っていませんが、限り、私はこの内部の参照は、それにバインドされていない関数を参照する必要がありますウィンドウオブジェクトを参照する必要があります、定義されていない、そこの多くのブラウザではそうです。

thiswindowです。定義されていないwindow.urlを印刷しています。試してconsole.log(this)、それはwindowをもたらすはずです。 [現在の要素の]

thisキーワードを介してアクセスすることができます... JavaScriptで

、ときに手:$.eachためjQuery docsによると

+0

これまでに気付かなかったのはかなり皮肉です。 – loki

+0

お待ちください、これは正しいですか?私の直感(とテスト)は 'thisList'インスタンスが' PageList.toHTML'の中にあるときに 'this'が' $ .each'へのコールバックの中で現在のリスト要素に等しいということを示しています。あなたはいつこのコードで 'window'と同じであることを観察しますか?PageListの外側を除いて? – apsillers

+0

私はちょうど@apsillersの答えを読んで、彼は正しいかもしれません。しかし、あなたのコード上で 'this.elements'とは何ですか? – bfavaretto

関連する問題