Search code examples
javascriptobjectscopeinstantiationencapsulation

Javascript Objects. Instantiation of an object as the property value of an object


I'm having some issues wrapping my head around object instantiation and scope in JavaScript...

Looking at this sample code:

someOtherObj = {
  aMethod: function() {
    $('body').append('aMethod successfully called!<br>');
    return 'd';
  }
}

// THIS WORKS!!
$('body').append(someOtherObj.aMethod() + '<br>');

someObj = {
  aValue: 'a',
  bValue: 'b',
  cValue: this.aValue,              // THIS DOESN'T WORK!!
  dValue: new someOtherObj(),       // THIS DOESN'T WORK!!
  eValue: {
    fValue: aValue,                 // THIS DOESN'T WORK!!
    gValue: this.aValue,            // THIS DOESN'T WORK!!
    hValue: someObj.aValue,         // THIS DOESN'T WORK!!
  },
};

// JavaScript crashes out before this, but...
// This should result in:  'a'
$('body').append(someObj.cValue + '<br>');

// This should result in:  'd'
$('body').append(someObj.dValue.aMethod() + '<br>');

// These should result in: 'a'
$('body').append(someObj.eValue.fValue + '<br>');
$('body').append(someObj.eValue.gValue + '<br>');
$('body').append(someObj.eValue.hValue + '<br>');

I think the comments are pretty self explanatory... But that being said:

  1. How can I make cValue reference (===) aValue, and/or have the same value (==) as aValue?
  2. How can I instantiate a new object as the property of another object?
  3. How can I access the property of a containing object?

Solution

  • How can I make cValue reference (===) aValue, and/or have the same value (==) as aValue?

    You can't (other than just using the same value to initialize it, e.g. cValue: 'a'); more here: Self references in object literal declarations.

    Alternately, you could make cValue a getter that returns aValue, though there's little point in this case:

    var obj = {
        aValue: 42,
        get cValue() {
            return this.aValue;
        }
    };
    console.log(obj.cValue); // 42
    obj.aValue = 67;
    console.log(obj.cValue); // 67

    How can I instantiate a new object as the property of another object?

    The way you're doing it. The problem with what you're doing (new someOtherObj()) is that someOtherObj is an object, not a constructor function. (Constructor functions are objects, but most objects aren't constructor functions.)

    This is a constructor function:

    function Example() {
        this.someProperty = "some value"; // This bit is optional; it's here to
                                          // emphasize that constructors initialize
                                          // the contents of the new object
    }
    

    so is this, via ES2015 class syntax:

    class Example {
        constructor() {
            this.someProperty = "some value"; // Again, this bit is optional
        }
    }
    

    In both cases, this works:

    var obj {
        example: new Example()
    };
    console.log(example.someProperty); // "some value"
    

    How can I access the property of a containing object?

    Via this, if the code that's running is called in a way that sets this to the object. For instance:

    var obj = {
        answer: 42,
        doSomething: function() {
            console.log(this.answer);
        }
    };
    obj.doSomething(); // 42
    

    See these questions and their answers:

    Or in the case of one-off objects like that, by using the name of the variable they're assigned to:

    var obj = {
        answer: 42,
        doSomething: function() {
            console.log(obj.answer); // <== Only change is here
        }
    };
    obj.doSomething(); // 42