Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the array property work in JS object

Tags:

javascript

For the following code, why the propB of myObj is updated? And why test.childObj doesn't have the own property propB?

var myObj = { propA: '', propB: [] }
var fatherObj = {
    childObj: null,
    init: function() {
        this.childObj = Object.create(myObj);
        this.childObj.propA = 'A';
        this.childObj.propB.push(2);
    }
}

var test = Object.create(fatherObj);
test.init();

console.log(myObj.propB.length);
console.log(test.childObj.hasOwnProperty('propA'));
console.log(test.childObj.hasOwnProperty('propB'));
like image 699
Rick Avatar asked Nov 29 '18 07:11

Rick


People also ask

Can a property of an object be an array?

Just as object properties can store values of any primitive data type (as well as an array or another object), so too can arrays consist of strings, numbers, booleans, objects, or even other arrays.

How does array work in JavaScript?

JavaScript arrays are zero-indexed: the first element of an array is at index 0 , the second is at index 1 , and so on — and the last element is at the value of the array's length property minus 1 . JavaScript array-copy operations create shallow copies.


2 Answers

Using Object.create you do not copy an object, but you create a new object that inherits the passed one:

  this.childObj { } ->  myObj { propA: "", propB: [] }

Now when you get a property, it gets looked up in the inheritance chain. As it can't be found in the child object, it gets looked up in myObj. That is usually not a problem, as setting an objects property directly sets it on the object itself without using the inheritance chain, therefore this:

  this.childObj.propA += "test";

looks up propA on myObj but sets propA on the childObj. With reference types however, you do not rewrite the property, therefore this:

  this.childObj.propB.push(1);

looks up propB in myObj, and pushes to that, the result is:

 this.childObj { propA: "test" } ->  myObj { propA: "", propB: [1] }

To resolve that, the childObj has to have its own propB array:

 this.childObj.propB = this.childObj.propB.slice();

That results in:

 this.childObj { propA: "test", propB: [1] } ->  myObj { propA: "", propB: [1] }

and now pushing to propB pushes to the array in childObj.

like image 98
Jonas Wilms Avatar answered Sep 23 '22 03:09

Jonas Wilms


That is because myObj becomes a prototype of newly created test object (caused by creating it via Object.create.

Due to you just modify underlying prop propB of childObj (and not assign the new value like for propA) you only modify the prop of prototype. Please read more about inheritance in javascript.

like image 27
falinsky Avatar answered Sep 20 '22 03:09

falinsky