4

Code is available here to play with - http://jsfiddle.net/dsjbirch/zgweW/14/

This is basically a straight copy and paste of crockfords explanation of private variables.

I have added Object.create() and a bit of tracing.

Why does the second object share the private members of the first? How do I avoid this situation but continue to use Object.create()

function Container(param) {

    function dec() {
        if (secret > 0) {
            secret -= 1;
            return true;
        } else {
            return false;
        }
    }

    this.member = param;
    var secret = 3;
    var that = this;

    this.service = function () {
        return dec() ? that.member : null;
    };
}

var first = new Container("private");

var second = Object.create(first);

document.write(first.service() + "<br/>");
document.write(first.service() + "<br/>");
document.write(first.service() + "<br/>");
document.write(first.service() + "<br/>");

document.write(second.service() + "<br/>");
document.write(second.service() + "<br/>");
document.write(second.service() + "<br/>");
document.write(second.service() + "<br/>");

http://jsfiddle.net/dsjbirch/zgweW/14/

I would expect to see

private
private
private
null

private
private
private
null

But actuall the second object's output is all null.

private
private
private
null

null
null
null
null

I conclude second is therefor sharing the first object's secret member.

hippietrail
  • 15,848
  • 18
  • 99
  • 158
bluekeys
  • 2,217
  • 1
  • 22
  • 30
  • I'm confused about what your expectations are vs what you're seeing on jsFiddle. Can you give a little more detail on what you don't understand? – Kevin Ennis Jun 28 '12 at 01:05
  • -1 for jsfiddle.net (@Ashish Gupta). Why don't you paste the code here, along with the results? – Bergi Jun 28 '12 at 01:53

3 Answers3

2

Object.create() and new are used for different purposes.

You would use Object.create() to inherit from an existing object.
Where you use new to create a new instance of an object.

See the following questions and answers for details:

Understanding the difference between Object.create() and new SomeFunction()

Using "Object.create" instead of "new"

Community
  • 1
  • 1
JonWarnerNet
  • 1,112
  • 9
  • 19
1

Object.create() won't run a constructor. But in your example, the constructor is where your private magic happens. Instead, Object.create() will simply simply make a new object, and copy the properties over to it.

So what happens then is the constructor creates a scope, which is shared because the functions created in that scope get copied around. And when the instance is cloned, so is access to that scope.

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
  • 1
    It does not copy properties, it sets up the prototype chain. – Bergi Jun 28 '12 at 01:51
  • 1
    Yeah I guess that's more accurate, but it still makes the privileged function available to the created objects. That's the important bit. – Alex Wayne Jun 28 '12 at 02:06
1

They are not static, they are instance members of the "first" object. You never created any new instance members for the "second" object because you never called its constructor. Instead you set the prototype of "second" to "first", which means whenever a missing property is accessed on "second", you will get the value from "first".

You can call the constructor after using Object.create with something like

Container.call(second, param);
rich remer
  • 3,407
  • 2
  • 34
  • 47