How does the array property work in JS object











up vote
11
down vote

favorite
1












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'));












share|improve this question




























    up vote
    11
    down vote

    favorite
    1












    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'));












    share|improve this question


























      up vote
      11
      down vote

      favorite
      1









      up vote
      11
      down vote

      favorite
      1






      1





      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'));












      share|improve this question















      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'));








      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'));





      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'));






      javascript






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 29 at 8:26









      falinsky

      3,35831942




      3,35831942










      asked Nov 29 at 7:57









      Rick

      1277




      1277
























          4 Answers
          4






          active

          oldest

          votes

















          up vote
          11
          down vote



          accepted










          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.






          share|improve this answer






























            up vote
            3
            down vote













            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.






            share|improve this answer




























              up vote
              2
              down vote













              By using Object.create(myObj);, myObj becomes the prototype of childObj. If a property is not found in an object and is found in the prototype, the one from the prototype is used. Also note that hasOwnProperty tells if the objects owns the property itself, and will return false if it exists only in the prototype and not in the object. By assigning directly a property on an object, you set it on the object, not on the prototype, but when you modify the property propB with push, the property is not found directly in childObject, so you modify the prototype.



              You have to be careful with that, as all objects created this way will share the same prototype object and by modifying one, you will modify it for all instances.



              You have also to be extra careful because it can be tricky to know in javascript where in the prototype chain your property come from, as myObj also have a prototype.






              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('test: ', test);
              console.log('test prototype: ', test.__proto__);
              console.log('test.childObj: ', test.childObj);
              console.log('test.childObj prototype: ', test.childObj.__proto__);
              console.log(test.childObj.hasOwnProperty('propA'));
              console.log(test.childObj.hasOwnProperty('propB'));








              share|improve this answer






























                up vote
                1
                down vote













                Javascript inheritance does not work like in most other languages. When using var x = Object.create(someObj), the new object x is actually empty (it has no properties of its own) along with a reference to its prototype: the separate object someObj.



                Any property or function that you then try to access from x which does not resolve there, will be looked up in someObj - or even higher up, if someObj also has a prototype object, etc.



                Things can get confusing when inherited properties are modifiable objects, as in your example. As we have seen, trying to modify the array x.propB by pushing an item to it, will actually modify the inherited array contained in someObj.



                I'm strongly convinced that it is bad style to have modifiable objects (both arrays and regular objects) in prototype objects. Instead, prototype objects should contain only functions and no data, or at least no data beyond simple strings, numbers and booleans which are not modifiable.



                To summarize:




                • Functions are useful to inherit, they are not modifiable (you can't change the function body), and can still be overridden/replaced if needed.

                • Data becomes shared data by all inheritors, unless/until they override it by a re-assignment, which is a burden in itself.






                share|improve this answer























                  Your Answer






                  StackExchange.ifUsing("editor", function () {
                  StackExchange.using("externalEditor", function () {
                  StackExchange.using("snippets", function () {
                  StackExchange.snippets.init();
                  });
                  });
                  }, "code-snippets");

                  StackExchange.ready(function() {
                  var channelOptions = {
                  tags: "".split(" "),
                  id: "1"
                  };
                  initTagRenderer("".split(" "), "".split(" "), channelOptions);

                  StackExchange.using("externalEditor", function() {
                  // Have to fire editor after snippets, if snippets enabled
                  if (StackExchange.settings.snippets.snippetsEnabled) {
                  StackExchange.using("snippets", function() {
                  createEditor();
                  });
                  }
                  else {
                  createEditor();
                  }
                  });

                  function createEditor() {
                  StackExchange.prepareEditor({
                  heartbeatType: 'answer',
                  convertImagesToLinks: true,
                  noModals: true,
                  showLowRepImageUploadWarning: true,
                  reputationToPostImages: 10,
                  bindNavPrevention: true,
                  postfix: "",
                  imageUploader: {
                  brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                  contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                  allowUrls: true
                  },
                  onDemand: true,
                  discardSelector: ".discard-answer"
                  ,immediatelyShowMarkdownHelp:true
                  });


                  }
                  });














                  draft saved

                  draft discarded


















                  StackExchange.ready(
                  function () {
                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53534256%2fhow-does-the-array-property-work-in-js-object%23new-answer', 'question_page');
                  }
                  );

                  Post as a guest















                  Required, but never shown

























                  4 Answers
                  4






                  active

                  oldest

                  votes








                  4 Answers
                  4






                  active

                  oldest

                  votes









                  active

                  oldest

                  votes






                  active

                  oldest

                  votes








                  up vote
                  11
                  down vote



                  accepted










                  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.






                  share|improve this answer



























                    up vote
                    11
                    down vote



                    accepted










                    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.






                    share|improve this answer

























                      up vote
                      11
                      down vote



                      accepted







                      up vote
                      11
                      down vote



                      accepted






                      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.






                      share|improve this answer














                      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.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Nov 29 at 8:23

























                      answered Nov 29 at 8:14









                      Jonas Wilms

                      53.7k42547




                      53.7k42547
























                          up vote
                          3
                          down vote













                          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.






                          share|improve this answer

























                            up vote
                            3
                            down vote













                            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.






                            share|improve this answer























                              up vote
                              3
                              down vote










                              up vote
                              3
                              down vote









                              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.






                              share|improve this answer












                              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.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Nov 29 at 8:10









                              falinsky

                              3,35831942




                              3,35831942






















                                  up vote
                                  2
                                  down vote













                                  By using Object.create(myObj);, myObj becomes the prototype of childObj. If a property is not found in an object and is found in the prototype, the one from the prototype is used. Also note that hasOwnProperty tells if the objects owns the property itself, and will return false if it exists only in the prototype and not in the object. By assigning directly a property on an object, you set it on the object, not on the prototype, but when you modify the property propB with push, the property is not found directly in childObject, so you modify the prototype.



                                  You have to be careful with that, as all objects created this way will share the same prototype object and by modifying one, you will modify it for all instances.



                                  You have also to be extra careful because it can be tricky to know in javascript where in the prototype chain your property come from, as myObj also have a prototype.






                                  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('test: ', test);
                                  console.log('test prototype: ', test.__proto__);
                                  console.log('test.childObj: ', test.childObj);
                                  console.log('test.childObj prototype: ', test.childObj.__proto__);
                                  console.log(test.childObj.hasOwnProperty('propA'));
                                  console.log(test.childObj.hasOwnProperty('propB'));








                                  share|improve this answer



























                                    up vote
                                    2
                                    down vote













                                    By using Object.create(myObj);, myObj becomes the prototype of childObj. If a property is not found in an object and is found in the prototype, the one from the prototype is used. Also note that hasOwnProperty tells if the objects owns the property itself, and will return false if it exists only in the prototype and not in the object. By assigning directly a property on an object, you set it on the object, not on the prototype, but when you modify the property propB with push, the property is not found directly in childObject, so you modify the prototype.



                                    You have to be careful with that, as all objects created this way will share the same prototype object and by modifying one, you will modify it for all instances.



                                    You have also to be extra careful because it can be tricky to know in javascript where in the prototype chain your property come from, as myObj also have a prototype.






                                    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('test: ', test);
                                    console.log('test prototype: ', test.__proto__);
                                    console.log('test.childObj: ', test.childObj);
                                    console.log('test.childObj prototype: ', test.childObj.__proto__);
                                    console.log(test.childObj.hasOwnProperty('propA'));
                                    console.log(test.childObj.hasOwnProperty('propB'));








                                    share|improve this answer

























                                      up vote
                                      2
                                      down vote










                                      up vote
                                      2
                                      down vote









                                      By using Object.create(myObj);, myObj becomes the prototype of childObj. If a property is not found in an object and is found in the prototype, the one from the prototype is used. Also note that hasOwnProperty tells if the objects owns the property itself, and will return false if it exists only in the prototype and not in the object. By assigning directly a property on an object, you set it on the object, not on the prototype, but when you modify the property propB with push, the property is not found directly in childObject, so you modify the prototype.



                                      You have to be careful with that, as all objects created this way will share the same prototype object and by modifying one, you will modify it for all instances.



                                      You have also to be extra careful because it can be tricky to know in javascript where in the prototype chain your property come from, as myObj also have a prototype.






                                      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('test: ', test);
                                      console.log('test prototype: ', test.__proto__);
                                      console.log('test.childObj: ', test.childObj);
                                      console.log('test.childObj prototype: ', test.childObj.__proto__);
                                      console.log(test.childObj.hasOwnProperty('propA'));
                                      console.log(test.childObj.hasOwnProperty('propB'));








                                      share|improve this answer














                                      By using Object.create(myObj);, myObj becomes the prototype of childObj. If a property is not found in an object and is found in the prototype, the one from the prototype is used. Also note that hasOwnProperty tells if the objects owns the property itself, and will return false if it exists only in the prototype and not in the object. By assigning directly a property on an object, you set it on the object, not on the prototype, but when you modify the property propB with push, the property is not found directly in childObject, so you modify the prototype.



                                      You have to be careful with that, as all objects created this way will share the same prototype object and by modifying one, you will modify it for all instances.



                                      You have also to be extra careful because it can be tricky to know in javascript where in the prototype chain your property come from, as myObj also have a prototype.






                                      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('test: ', test);
                                      console.log('test prototype: ', test.__proto__);
                                      console.log('test.childObj: ', test.childObj);
                                      console.log('test.childObj prototype: ', test.childObj.__proto__);
                                      console.log(test.childObj.hasOwnProperty('propA'));
                                      console.log(test.childObj.hasOwnProperty('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('test: ', test);
                                      console.log('test prototype: ', test.__proto__);
                                      console.log('test.childObj: ', test.childObj);
                                      console.log('test.childObj prototype: ', test.childObj.__proto__);
                                      console.log(test.childObj.hasOwnProperty('propA'));
                                      console.log(test.childObj.hasOwnProperty('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('test: ', test);
                                      console.log('test prototype: ', test.__proto__);
                                      console.log('test.childObj: ', test.childObj);
                                      console.log('test.childObj prototype: ', test.childObj.__proto__);
                                      console.log(test.childObj.hasOwnProperty('propA'));
                                      console.log(test.childObj.hasOwnProperty('propB'));






                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Nov 29 at 8:31

























                                      answered Nov 29 at 8:22









                                      Kaddath

                                      2,3251315




                                      2,3251315






















                                          up vote
                                          1
                                          down vote













                                          Javascript inheritance does not work like in most other languages. When using var x = Object.create(someObj), the new object x is actually empty (it has no properties of its own) along with a reference to its prototype: the separate object someObj.



                                          Any property or function that you then try to access from x which does not resolve there, will be looked up in someObj - or even higher up, if someObj also has a prototype object, etc.



                                          Things can get confusing when inherited properties are modifiable objects, as in your example. As we have seen, trying to modify the array x.propB by pushing an item to it, will actually modify the inherited array contained in someObj.



                                          I'm strongly convinced that it is bad style to have modifiable objects (both arrays and regular objects) in prototype objects. Instead, prototype objects should contain only functions and no data, or at least no data beyond simple strings, numbers and booleans which are not modifiable.



                                          To summarize:




                                          • Functions are useful to inherit, they are not modifiable (you can't change the function body), and can still be overridden/replaced if needed.

                                          • Data becomes shared data by all inheritors, unless/until they override it by a re-assignment, which is a burden in itself.






                                          share|improve this answer



























                                            up vote
                                            1
                                            down vote













                                            Javascript inheritance does not work like in most other languages. When using var x = Object.create(someObj), the new object x is actually empty (it has no properties of its own) along with a reference to its prototype: the separate object someObj.



                                            Any property or function that you then try to access from x which does not resolve there, will be looked up in someObj - or even higher up, if someObj also has a prototype object, etc.



                                            Things can get confusing when inherited properties are modifiable objects, as in your example. As we have seen, trying to modify the array x.propB by pushing an item to it, will actually modify the inherited array contained in someObj.



                                            I'm strongly convinced that it is bad style to have modifiable objects (both arrays and regular objects) in prototype objects. Instead, prototype objects should contain only functions and no data, or at least no data beyond simple strings, numbers and booleans which are not modifiable.



                                            To summarize:




                                            • Functions are useful to inherit, they are not modifiable (you can't change the function body), and can still be overridden/replaced if needed.

                                            • Data becomes shared data by all inheritors, unless/until they override it by a re-assignment, which is a burden in itself.






                                            share|improve this answer

























                                              up vote
                                              1
                                              down vote










                                              up vote
                                              1
                                              down vote









                                              Javascript inheritance does not work like in most other languages. When using var x = Object.create(someObj), the new object x is actually empty (it has no properties of its own) along with a reference to its prototype: the separate object someObj.



                                              Any property or function that you then try to access from x which does not resolve there, will be looked up in someObj - or even higher up, if someObj also has a prototype object, etc.



                                              Things can get confusing when inherited properties are modifiable objects, as in your example. As we have seen, trying to modify the array x.propB by pushing an item to it, will actually modify the inherited array contained in someObj.



                                              I'm strongly convinced that it is bad style to have modifiable objects (both arrays and regular objects) in prototype objects. Instead, prototype objects should contain only functions and no data, or at least no data beyond simple strings, numbers and booleans which are not modifiable.



                                              To summarize:




                                              • Functions are useful to inherit, they are not modifiable (you can't change the function body), and can still be overridden/replaced if needed.

                                              • Data becomes shared data by all inheritors, unless/until they override it by a re-assignment, which is a burden in itself.






                                              share|improve this answer














                                              Javascript inheritance does not work like in most other languages. When using var x = Object.create(someObj), the new object x is actually empty (it has no properties of its own) along with a reference to its prototype: the separate object someObj.



                                              Any property or function that you then try to access from x which does not resolve there, will be looked up in someObj - or even higher up, if someObj also has a prototype object, etc.



                                              Things can get confusing when inherited properties are modifiable objects, as in your example. As we have seen, trying to modify the array x.propB by pushing an item to it, will actually modify the inherited array contained in someObj.



                                              I'm strongly convinced that it is bad style to have modifiable objects (both arrays and regular objects) in prototype objects. Instead, prototype objects should contain only functions and no data, or at least no data beyond simple strings, numbers and booleans which are not modifiable.



                                              To summarize:




                                              • Functions are useful to inherit, they are not modifiable (you can't change the function body), and can still be overridden/replaced if needed.

                                              • Data becomes shared data by all inheritors, unless/until they override it by a re-assignment, which is a burden in itself.







                                              share|improve this answer














                                              share|improve this answer



                                              share|improve this answer








                                              edited Nov 29 at 8:49

























                                              answered Nov 29 at 8:41









                                              Peter B

                                              12.6k51941




                                              12.6k51941






























                                                  draft saved

                                                  draft discarded




















































                                                  Thanks for contributing an answer to Stack Overflow!


                                                  • Please be sure to answer the question. Provide details and share your research!

                                                  But avoid



                                                  • Asking for help, clarification, or responding to other answers.

                                                  • Making statements based on opinion; back them up with references or personal experience.


                                                  To learn more, see our tips on writing great answers.





                                                  Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                                  Please pay close attention to the following guidance:


                                                  • Please be sure to answer the question. Provide details and share your research!

                                                  But avoid



                                                  • Asking for help, clarification, or responding to other answers.

                                                  • Making statements based on opinion; back them up with references or personal experience.


                                                  To learn more, see our tips on writing great answers.




                                                  draft saved


                                                  draft discarded














                                                  StackExchange.ready(
                                                  function () {
                                                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53534256%2fhow-does-the-array-property-work-in-js-object%23new-answer', 'question_page');
                                                  }
                                                  );

                                                  Post as a guest















                                                  Required, but never shown





















































                                                  Required, but never shown














                                                  Required, but never shown












                                                  Required, but never shown







                                                  Required, but never shown

































                                                  Required, but never shown














                                                  Required, but never shown












                                                  Required, but never shown







                                                  Required, but never shown







                                                  Popular posts from this blog

                                                  Quarter-circle Tiles

                                                  build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

                                                  Mont Emei