代码可以在这里玩 - http://jsfiddle.net/dsjbirch/zgweW/14/
这基本上是克罗克福德对私有变量的解释的直接复制和粘贴。
我添加了Object.create()
和一些跟踪。
为什么第二个对象共享第一个对象的私有成员?如何避免这种情况但继续使用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/
我希望看到
private
private
private
null
private
private
private
null
但实际上第二个对象的输出都是空的。
private
private
private
null
null
null
null
null
我的结论是second
因此共享first
对象的secret
成员。
Object.create()
和new
用于不同的目的。
您可以使用Object.create()
从现有对象inherit
。
使用new
创建对象的新instance
的位置。
有关详细信息,请参阅以下问题和解答:
了解 Object.create() 和 new SomeFunction() 之间的区别
使用"Object.create"而不是"new"
它们不是静态的,它们是"第一个"对象的实例成员。 您从未为"第二个"对象创建任何新的实例成员,因为您从未调用其构造函数。 相反,您将"second"的原型设置为"first",这意味着每当在"second"上访问缺少的属性时,您将从"first"获得值。
你可以在使用 Object.create 后调用构造函数,
如下所示Container.call(second, param);
Object.create()
不会运行构造函数。 但是在你的例子中,构造函数是你的私人魔术发生的地方。 相反,Object.create()
将简单地创建一个新对象,并将属性复制到其中。
是共享的,因为在该作用域中创建的函数被复制。 克隆实例时,对该范围的访问也会被克隆。