web-dev-qa-db-ja.com

JavaScriptオブジェクトプロパティは、同じオブジェクトの別のプロパティを参照できますか?

私は最近このようなオブジェクトを作成しようとしました:

_var carousel = {
      $slider: $('#carousel1 .slider'),
      panes: carousel.$slider.children().length
    };
_

私の意図は、オブジェクトプロパティに$('#carousel1 .slider')の結果をキャッシュすることでjQueryのセレクターのパフォーマンスを改善し、コードを簡潔で比較的ドライに保つことでした。

しかし、これは機能しませんでした。コードが実行されると、panesの値を解析しようとしたときに例外がスローされ、carouselが未定義であると訴えられました。

これは理にかなっています。なぜなら、carouselは、割り当てステートメントが完全に実行されるまで完全には宣言されないと仮定するからです。ただし、これに頼るのは避けたいと思います。

_var carousel = {};
carousel.$slider = $('#carousel1 .slider');
carousel.panes = carousel.$slider.children().length;
_

それほど悪くはありませんが、carouselオブジェクトには、他のプロパティの値に依存するプロパティがさらにいくつかあるため、すぐに冗長になります。

thisを使用してみましたが、役に立ちませんでした。私はそれを正しく使用していなかったかもしれません、またはそれはとにかく有効なアプローチではないかもしれません。

そのオブジェクトがまだ宣言されている間に、オブジェクトのプロパティが同じオブジェクトの他のプロパティを参照する方法はありますか?


Matthew Flaschenとcasablancaの回答(ありがとう!

_// Matthew Flaschen

var carousel = new (function() {
  this.$carousel = $('.carousel');
  this.$carousel_window = this.$carousel.find('.window');
  this.$carousel_slider = this.$carousel.find('.slider');
  this.$first_pane = this.$carousel.find('.slider').children(':first-child');
  this.panes = this.$carousel_slider.children().length;
  this.pane_gap = this.$first_pane.css('margin-right');
})();
_

そして

_// casablanca

var $carousel = $('.carousel'),
    $carousel_slider = $carousel.find('.slider'),
    $first_pane: $carousel.find('.slider').children(':first-child');

var properties = {
  $carousel_window: $carousel.find('.window'),
  panes: $carousel_slider.children().length,
  pane_gap: $first_pane.css('margin-right')
};

properties.$carousel = $carousel;
properties.$carousel_slider = $carousel_slider;
properties.$first_pane = $first_pane;
_

それらが両方とも正しいと仮定すると(私はそれらをテストしていない)、それは一種の難しい呼び出しです。コードはオブジェクト宣言により類似した構造に含まれているため、Matthew Flaschenのアプローチを少し好むと思います。また、最終的に作成される変数は1つだけです。ただし、そこには多くのthisがあり、繰り返しのように見えますが、それはただ支払う代償かもしれません。

62
Bungle

オブジェクトリテラルではありません(thisは、リテラルの構築中に、事前に行ったのと同じ値を持ちます)。しかし、あなたはできる

var carousel = new (function()
{
      this.$slider =  $('#carousel1 .slider');
      this.panes = this.$slider.children().length;
})();

これは、匿名関数コンストラクターから作成されたオブジェクトを使用します。

$sliderpanesはパブリックなので、carousel.$sliderなどとしてアクセスできることに注意してください。

50

残念だけど違う。 {}構文は、新しいオブジェクトの作成を開始しますが、オブジェクトが作成されるまで、carousel変数には割り当てられません。また、this値は関数呼び出しの結果としてのみ変更できます。 「複数のプロパティ」がすべてsliderのみに依存する場合は、次のような方法で回避できます。

var slider = $('.slider');
var carousel = {
  panes: slider.children.length(),
  something: slider.something_else,
  // ...
};
carousel.slider = slider;
19
casablanca