Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a JavaScript object property refer to another property of the same object? [duplicate]

I recently tried to create an object like this:

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

My intentions were to improve jQuery's selector performance by caching the results of $('#carousel1 .slider') in an object property, and to keep the code concise and relatively DRY.

However, this didn't work. When the code executed, it threw an exception when trying to parse the value of panes, complaining that carousel was undefined.

This makes sense, since I'd assume that carousel isn't fully declared until the assignment statement has been fully executed. However, I'd like to avoid resorting to this:

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

That's not too much worse, but the carousel object will have several more properties that rely on the values of other properties, so that could quickly become verbose.

I tried using this, but to no avail. I may well not have been using it correctly, or that may not be a valid approach anyway.

Is there a way for properties of an object to refer to other properties of the same object, while that object is still being declared?


Based on Matthew Flaschen and casablanca's answers (thanks, guys!), I think these are the versions of my actual code that I'd end up with, based on each approach:

// 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'); })(); 

and

// 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; 

Assuming those are both correct (I haven't tested them), it's kind of a tough call. I think I slightly prefer Matthew Flaschen's approach, since the code is contained to a structure that more closely resembles an object declaration. There's also ultimately only one variable created. However, there's a lot of this in there, which seems repetitive - although that may be just the price to pay.

like image 666
Bungle Avatar asked Jul 04 '10 03:07

Bungle


People also ask

How is an object property referenced in JavaScript?

Object properties are defined as a simple association between name and value. All properties have a name and value is one of the attributes linked with the property, which defines the access granted to the property. Properties refer to the collection of values which are associated with the JavaScript object.

How do you copy properties from one object to another in JavaScript?

The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.

Can we have two properties with the same name inside an object?

You cannot. Property keys are unique. Follow TravisJ 's advice. You might want to look up the term 'multimap', too.

Does JavaScript copy object by reference?

Objects in JavaScript are passed by reference. When more than one variable is set to store either an object , array or function , those variables will point to the same allocated space in the memory. Passed by reference.


2 Answers

Not with object literals (this has the same value during constructing of the literal that it did before-hand). But you can do

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

This uses an object created from an anonymous function constructor.

Note that $slider and panes are public, so can be accessed as carousel.$slider, etc.

like image 86
Matthew Flaschen Avatar answered Nov 05 '22 23:11

Matthew Flaschen


Unfortunately, no. The {} syntax initiates creation of a new object, but until the object is created, it is not assigned to the carousel variable. Also, the this value can only change as a result of a function call. If your "several more properties" are all going to depend only on slider, then you could get around with something like this:

var slider = $('.slider'); var carousel = {   panes: slider.children.length(),   something: slider.something_else,   // ... }; carousel.slider = slider; 
like image 36
casablanca Avatar answered Nov 06 '22 00:11

casablanca