1

Please see the fiddle/code below: http://jsfiddle.net/kmiklas/3YdTA/4/

Questions:

  • Why does a call to the setter function of a child--in the example, the call to Object.create(99)--change the setting of the parent? Note how, although we've invoked this function in the context of orange, it's also changing the value for red.
  • More importantly, how can inherited getter/setter functions be applied to the child, and not the parent?
  • What am I missing here?

var Square = function () {
    var side;
    this.setSide = function(s) {
        side = s
    }
    this.getSide = function() {
        return side;
    }
}
var red = new Square();
var orange = Object.create(red);
red.setSide(100);
var $container = $('#container');
$container.append('orange.getSide(): ' + orange.getSide() + '<br>');
$container.append('red.getSide(): ' + red.getSide() + '</br><br>');
$container.append('<i>Now we call orange.setSide(99)...</i><br></br>');
orange.setSide(99);
$container.append('orange.getSide(): ' + orange.getSide() + ' <i>...as expected.<br></i>');
$container.append('red.getSide(): ' + red.getSide() + '!? <i>Why does the call to orange.setSide(99) affect the side length of the parent?</i></br>');
kmiklas
  • 13,085
  • 22
  • 67
  • 103
  • 3
    I don't understand what `Object.create(99)`, `orange` and `red` have to do with the code you posted. ...and there's no inheritance in that code. – cookie monster Jan 21 '14 at 18:57
  • You have to look at the fiddle... Did you vote this as off-topic? It is not; please remove on-hold status. – kmiklas Jan 21 '14 at 19:28
  • 3
    You need to put all relevant information needed to reproduce the issue directly in your question. I didn't vote it off-topic. A moderator did. – cookie monster Jan 21 '14 at 19:43
  • ok... added in the rest of the code needed to answer the question. – kmiklas Jan 22 '14 at 15:26
  • 2
    Just so you're clear on what prototypal inheritance is, it's really just a chain of objects used for looking up properties. In your example, the chain goes `orange -> red -> Square.prototype -> Object.prototype -> null`. So when you ask `orange` for a property, if it doesn't have it, it goes to `red`, and so on until it finds it or fails. So in your case, the property you're looking for is the `setSide` method. Because `orange` has no such method, it looks for it on `red` and finds it. Therefore it returns the `side` variable that was created in the `Square` constructor. – cookie monster Jan 22 '14 at 15:37
  • Yes! Helpful description... but I am calling `setSide()` in the context of `orange`; e.g., `orange.setSide(99)`. Why is this applied to `red`? Why does this not set the side length for the `orange` object? – kmiklas Jan 22 '14 at 17:49
  • 2
    It's because `side` is a local variable in the `Square` constructor, and not a property on any object. The only access to that variable is via the two methods that you placed on the `red` object. To make it more typical prototypal inheritance, but both methods on `Square.prototype`, get rid of the `var side`, and have the methods do `this.side = s;` in the setter, and `return this.side;` in the getter. Variables and properties are entirely separate things in JavaScript. – cookie monster Jan 22 '14 at 18:06
  • Ok. Only problem is that I was trying to keep side "private" by creating it as a local variable in the constructor. If I use `this.side = s;`, then `side` is now public, correct? – kmiklas Jan 22 '14 at 18:15
  • 1
    Correct. If you want it to be private, then it's not going to be accessible anywhere except via those methods. No matter how those methods are invoked, they'll always operate on the `var side;` created in that invocation of `Square`. Even if you do `var set = red.setSide; var get = red.getSide; set(123); get(); // 123;`, you're still manipulating the same variable. – cookie monster Jan 22 '14 at 18:23
  • 1
    ...if you do `Square.call(orange);`, this will invoke `Square` with the `orange` object as the `this` value. Because `Square` is being invoked, it's creating a new variable scope with its own `side` and `get/setSide` methods which are put on `this` (orange). – cookie monster Jan 22 '14 at 18:25

1 Answers1

2

The Object.create() method creates a new object with the specified prototype object and properties.

MDN

 var orange = Object.create(red);

You are not cloning the object this way, you are creating a new ref to it so any changes you mad to the original object will affect the all the copies to this object

var x = {name:"foo",phone:"bar"};
var y = Object.create(x);

x.u = "123";

console.log(y);//{name: "foo", phone: "bar", u: "123"} 
console.log(x);//{name: "foo", phone: "bar", u: "123"} 

object are copied by Ref in javaScript

DEMO

see this on How do I correctly clone a JavaScript object?

Community
  • 1
  • 1
Mina Gabriel
  • 23,150
  • 26
  • 96
  • 124