Search code examples
javascriptarraysobjectsquare-bracket

Understanding what is going on obj and two brack values equaling {some object data}


Sometimes what is most likely basic for all just doesn't sink in. I came across some javascript code I need to understand. I added a debugger so I could step through and hopefully understand it better but still not clear on what is going on.

var obj = {};
var myID = 999;

var productID = 1;

var myModelID = 100;
var myCatID = 200;
    var addMe = 1; 

if (typeof obj[myCatID] == 'undefined') {
    obj[myCatID] = {};
}

var locationObj = {
    state: 'roch',
    city: '3',
    street: '2nd',
    houseNum: '101'
};

var qty = 1;

obj[myCatID][myModelID]={
    'location': locationObj,
    'quantity': qty,
    'prodID': productID,
    'id': myID
};

What is going on here? obj[myCatID][myModelID] = . Something with respect to two properties in bracket notation for obj? Then assign an object to it? Just not clear on what I'm looking at.

The output via my alert and debugger. !https://i.sstatic.net/Sn2K5.jpg

!https://i.sstatic.net/VBRHh.jpg

Finally, what if I added an additional bracket value to change obj[myCatID][myModelID] to obj[myCatID][myModelID][addMe]? Why do I get a debug error, uncaught TypeError: Cannot set property '1' of undefined when run? I don't see how it's different that [myModelID] and how it's declared. I appreciate you helping me get past this road block.


Solution

  • You can access and manipulate JavaScript objects with bracket accessors.

    var obj = {};  // create an empty object
    obj['test'] = 'Hello World';  // add an object property 'test' with content 'Hello World'
    console.info(object['test']);  // Hello World
    console.info(object.test);  // Hello World
    

    As you can see, the object property access can be denoted as obj['propertyName'] or obj.propertyName. The same applies if you want to add a new property to your object: obj['newProperty'] = 42 is the same as obj.newProperty = 42.

    Now, if you want to have nested inner objects inside of an outer object, you can do this with multiple bracket accessors or dots: obj['prop1']['prop2']['prop3'] = 42 or obj.prop1.prop2.prop3 = 42.

    But: You have to initialize each inner object seperately before you can access it! Otherwise JavaScript will say "Cannot set property of undefined" because the actual object you try to access has never been initialized before.

    var obj = {};
    obj['prop1'] = {};  // creates an inner object 'prop1'
    obj['prop1']['prop2']['prop3'] = 42;  // does not work because 'prop2' has never been created as an inner object
    

    In your example, you cannot access obj[myCatID][myModelID][addMe] because the inner object "myModelID" has never been initialized as an object. Thus the access obj[myCatID][myModelID] will return undefined, so you would try to call undefined['prop3'] which results in an error.

    The simple solution: Check each inner object whether it's already been initialized. This is what happens in your code at if (typeof obj[myCatID] == 'undefined').