Javascript 模块模式 - Object.create

标签 javascript module-pattern revealing-module-pattern

对于这里到底发生了什么有点困惑。

给出这个简单的代码:

stuff = (function(){
    function extendFoo(bar)
    {
        $.extend(this.foo,bar);
    }
    this.foo = {};

    return { foo : foo, extendFoo: extendFoo};
})();

按照这个简单的操作:

zz = Object.create(stuff);
zz.extendFoo({bar:'bar'});
vv = Object.create(stuff); //foo is still extended(??)

据我所知,对 Object.create 返回的对象进行的操作仍然会影响该对象的原型(prototype),因此当您创建一个新对象时,他的原型(prototype)会发生变化,从而产生“修改”版本。

这在很多层面上似乎都是错误的,谁能解释一下这里发生了什么?

使用以下模式无法重现此行为:

stuff = (function(){

    function setFoo(bar)
    {
        this.foo = bar;
    }
    var foo;

    return { foo : foo, setFoo: setFoo};

})();

所以我怀疑 $.extend 是罪魁祸首。

任何输入都会很棒!

最佳答案

这个问题与模块模式无关,而与原型(prototype)有关。

zz = Object.create(stuff) 

创建一个以 stuff 作为原型(prototype)的新对象。

vv = Object.create(stuff) 

创建一个新对象,其原型(prototype)具有相同的 stuff 对象。

zzvv 共享相同的原型(prototype)对象,因此如果修改原型(prototype)对象 stuff,则更改将反射(reflect)在两者的派生中对象 zzvv。无论您是通过 $.extend 还是其他方式修改原型(prototype),都没有关系,无论您是通过派生对象还是原型(prototype)修改原型(prototype),都没有关系。

在您的代码中,foo 对象附加到原型(prototype),而不是附加到派生对象 zzvv。当在派生对象 zz 上调用 extendFoo 时,它正在修改原型(prototype)上的 foo,因此更改为 foo由派生对象共享。

在第二个示例中,在 setFoo

this.foo = bar;

发生的情况是您在派生对象上设置了 foo 属性,因此现在它覆盖了原型(prototype)的 foo 。在派生对象上运行 setFoo 后,该对象的 foo 不再是原型(prototype)的 foo。您可以通过运行看到这一点

zz = Object.create(stuff);
console.log(zz.hasOwnProperty('foo')); // false
zz.setFoo(bar);
console.log(zz.hasOwnProperty('foo')); // true
delete zz.foo;
console.print(zz.foo); // foo is the original foo, not null
console.log(zz.hasOwnProperty('foo')); // false

您实际上会取回原始的 foo 而不是 null

setFoo 在第二种情况下起作用的原因是因为您不再修改原型(prototype),因此派生对象之间不再共享更改。与原版的

$.extend(this.foo,bar);

您正在就地修改对象 this.foo 而不是覆盖。您还可以通过 hasOwnProperty

查看
zz = Object.create(stuff);
console.log(zz.hasOwnProperty('foo')); // false
zz.extendFoo({bar:'bar'});
console.log(zz.hasOwnProperty('foo')); // false

关于Javascript 模块模式 - Object.create,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28800185/

相关文章:

javascript - 为什么将 NGINX 与 Meteor 结合使用?

javascript - (揭示)模块模式、公共(public)变量和返回语句

Javascript:揭示模块模式。访问私有(private)成员(member)

javascript - 需要一个使用揭示模块模式的模块

javascript - 导航按钮可见性

javascript - 是什么导致了 "jqGrid is not a function "错误?

javascript - 检查链接(不是 URL)是否包含某些文本(.jpg、.gif、.png)

javascript - jQuery 插件的每个实例如何拥有自己的属性和方法?

javascript - 在模块模式中设置和获取私有(private)变量

Javascript 揭示模块模式 - this 和内部函数调用