0

I'm reading Crockford's book on Javascript and trying its inheritance method "Beget", but I'm puzzled by the result.

Could you explain why the following code returns "Values: blue_small / blue_big"? I would expect it to return "Values: blue_small / red_big".

if (typeof Object.beget !== 'function') {
   Object.beget = function (o) {
      var F = function () {};
      F.prototype = o;
      return new F();
   };
}

function calculate(){  
    var object1 = {
        color: "red",
        size: "small"
    };

    var object2 = Object.beget(object1);

    object2.size = "big";

    object1.color = "blue";

    return "Values: "+object1.color +"_" + object1.size +" \/ " + object2.color+"_" + object2.size || "unknown";
}
Mighty duck
  • 63
  • 1
  • 5
  • 1
    Do `console.dir(object2)` and have a look at the prototype chain. `object1` is the prototype of `object2`, so every change you make to `object1` is also reflected in `object2` (unless `object2` shadows a property of `object1`). Also see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain – Felix Kling Apr 05 '14 at 18:30
  • Crockford has called object.create returning a clone but that's completely missing the point of prototype. MDN has clone in quotes. What prototype is is explained in this answer http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711 – HMR Apr 06 '14 at 14:06
  • What he calls classical inheritance he always does wrong and then criticizes it for the things he does wrong. He insists on privates but breaks encapsulation by changing objects he doesn't own: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain#Bad_practice.3A_Extension_of_native_prototypes – HMR Apr 06 '14 at 14:16

3 Answers3

2

In Javascript, when the value of a property is not set on an instance, getting the value refers to the prototype chain.

In this example, the object2 is created and object1 is its prototype. But the value of the color property is never set on object2 in an explicit way.

This means that reading the value refers to the prototype which is object1 and since the value there is set to blue, you have the result.

Your confusion probably stems from the fact that you would expect creating new object to create a copy that includes all properties. In fact however, the newly created object has no properties set in an explicit way. Whenever you get a value of a property, prototype chain is referred.

Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106
1

Your object2 inherits from your object1.

First step

object1 = { color: "red", size: "small" }; => object 1 = red/small

Second step

var object2 = Object.beget(object1); => object 2 = red/small

Third step

object2.size = "big"; => object 2 = red/big

Fourth step

object1.color = "blue"; => object 1 = blue/small and object 2 = blue/big


Why that?

Because you've never changed the Object 2 color, so it will get the color from Object 1, who is its father. So, when you change Object 1, the Object 2 will automatically update this property. If, at any time, you had changed the Object 2 color, then, it would bypass the inheritance.

Buzinas
  • 11,597
  • 2
  • 36
  • 58
  • Actually `object2` will not automatically be updated when `object1.color` is set. The inheritance comes only into play when the `color` property is *read* from `object2`. – Bergi Apr 05 '14 at 18:39
0

Because beget does not create a copy of object1, but creates a new empty object2 which inherits its properties from object1. This inheritance is dynamic, and when you change object1 then that new property value is also visible on object2.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375