2012-03-15 10 views
2

、私はオブジェクトがある場合:メソッドのいくつかのスコープ内のオブジェクトからプロパティにアクセスする適切な方法は何ですか?例えば

function Website(){ 
    this.images = []; 
} 

Website.prototype.getImages = function(){ 
    jQuery('img').each(function(key, val){ 
     this.images.push(val.src); 
    }) 
} 

をし、私はこのエラーを取得するwebsite.getImages()を呼び出そう:TypeError: Cannot call method 'push' of undefined

ので、この問題を解決するために、私はどうなる:

Website.prototype.getImages = function(){ 
    var images = this.images; 
    jQuery('img').each(function(key, val){ 
     images.push(val.src); 
    }) 
} 

しかし、私はいくつかの変数にアクセスしようとしているので、私はこのソリューションがきれいだとは思わない。

これを行うにはよりクリーンで良い方法がありますか?

+0

百万件の質問が重複しています –

+0

なぜ泣き叫ぶのではなく、なぜこれに関連する質問を投稿しますか?私は検索しようとしたが、おそらく私は間違った言葉を使用していたが、私は試してみましたが見つかりませんでした。 – davoclavo

答えて

2

あなたがこれを行うことができます:thisがどのように応じて設定されている一般的な意味で

Website.prototype.getImages = function(){ 
    var self = this; 
    jQuery('img').each(function(key, val){ 
     self.images.push(val.src); 
     // self.someOtherProperty 
     // self.someMethod() 
    }) 
} 

を関数が呼び出されると、内部関数のためにが正しく設定されていることを確認するために何かする必要があります。たとえば.call()または.apply() - または.bind()ですが、.bind()はI Eまでです。

コールバックをとるjQuery関数は、常にthisを論理的に設定します。ほとんどの場合、その時点で特定のDOM要素が処理されています。もちろん、それが他のものになりたいときには役に立ちません。

1

"クリーン"と呼ばれるものによって異なります。それは非常に読みやすいです。もう一つのアイデアは、あなたがまだあなたの最初のスニペットを使用できるように、this値を通過する.bindを使用している:

jQuery('img').each(function(key, val){ 
    this.images.push(val.src); 
}.bind(this)); // set the `this` inside `.each` to the one it is currently 
0

あなたは正しいことをしています。この動作の理由は、jQueryが.each()コールバックでをそれぞれ<img>に一致させるようにするためです。

+0

jQueryが意図的に各DOM要素に意図的に 'this 'を設定していなくても、ネストされた関数内では(デフォルトでは)' website'オブジェクトと同じではありません。 – nnnnnn

+0

ええ、私は知っています。どのような場合でも解決策は同じです( 'var that = this')。 – bfavaretto

0

いいえ、そうは思いません。ほぼすべてのjQueryコールバック関数でDOM要素に設定されていることがわかっているキーワードです。何かのように

jQuery('img').each(function(key, val){ 
    this.images.push(val.src); 
}.bind(this)); 

は、それが必然的であるよりも乱雑になります。参照解除変数 "self"または "that"はこれを行うための標準的な方法です。しかし、あなたは簡単にjQueryせずに行うことができます:

var imgs = document.getElementsByTagName("img"); 
for (var i=0, l=imgs.length; i<l; i++) 
    this.images.push(imgs[i].src); 

...ライン、短いjQueryのより速いし、同様にクロスブラウザの作業です。

0

もう1つの方法は、jQuery.proxyを使用することです。基本的に、他の人が触れているFunction.bind関数のラッパーです。それはすべてのブラウザで動作する点を除いて。

Website.prototype.getImages = function(){ 
    jQuery('img').each(
     jQuery.proxy(function(key, val){ 
      // 'this' now refers to the instance of Website 
      this.images.push(val.src); 
      this.other_property = 'awesome'; 
     }, this) 
    ); 
} 
関連する問題