Подтвердить что ты не робот

Может ли свойство объекта JavaScript ссылаться на другое свойство одного и того же объекта?

Недавно я попытался создать такой объект:

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

Мои намерения заключались в улучшении производительности селектора jQuery путем кэширования результатов $('#carousel1 .slider') в свойстве объекта и для обеспечения краткости кода и относительно СУХОЙ.

Однако это не сработало. Когда код выполнялся, он генерировал исключение при попытке проанализировать значение panes, жалуясь, что carousel был undefined.

Это имеет смысл, так как я предполагаю, что 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;

Предполагая, что они оба правильны (я их не тестировал), это непростой вызов. Я думаю, что я немного предпочитаю подход Мэтью Флашена, поскольку код содержится в структуре, более близкой к объявлению объекта. Там также создается только одна переменная. Однако там много this, которое кажется повторяющимся - хотя это может быть только цена, которую нужно заплатить.

4b9b3361

Ответ 1

Не с объектными литералами (this имеет такое же значение при построении литерала, что и раньше). Но вы можете сделать

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

В этом случае используется объект, созданный из конструктора анонимной функции.

Обратите внимание, что $slider и panes являются общедоступными, поэтому их можно получить как carousel.$slider и т.д.

Ответ 2

К сожалению, нет. Синтаксис {} инициирует создание нового объекта, но до создания объекта он не присваивается переменной carousel. Кроме того, значение this может меняться только в результате вызова функции. Если ваши "несколько свойств" будут зависеть только от slider, тогда вы можете обойти что-то вроде этого:

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