Search code examples
javascriptprototypeobject-create

Why does Object.create make my private variables static?


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.


Solution

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