4

代码可在此处使用 - http://jsfiddle.net/dsjbirch/zgweW/14/

这基本上是对私有变量的 crockfords 解释的直接复制和粘贴。

我已经添加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成员。

4

3 回答 3

2

Object.create()new用于不同的目的。

您可以从现有对象中使用Object.create()to 。 用于创建新对象的位置。inherit
newinstance

有关详细信息,请参阅以下问题和答案:

了解 Object.create() 和 new SomeFunction() 之间的区别

使用“Object.create”而不是“new”

于 2012-06-28T01:09:22.180 回答
1

Object.create()不会运行构造函数。但是在您的示例中,构造函数是您的私有魔法发生的地方。相反,Object.create()将简单地创建一个新对象,并将属性复制到它。

所以接下来发生的是构造函数创建了一个作用域,该作用域是共享的,因为在该作用域中创建的函数会被复制。当实例被克隆时,对该范围的访问也是如此。

于 2012-06-28T01:12:53.127 回答
1

它们不是静态的,它们是“第一个”对象的实例成员。您从未为“第二个”对象创建任何新的实例成员,因为您从未调用过它的构造函数。相反,您将“second”的原型设置为“first”,这意味着每当在“second”上访问缺少的属性时,您都会从“first”获得值。

您可以在使用 Object.create 之后调用构造函数,例如

Container.call(second, param);
于 2014-03-17T02:56:56.760 回答