Javascript模块模式 - Object.create

时间:2015-03-01 22:49:25

标签: 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进行的操作仍会影响该Object的原型,因此当您创建一个新对象时,他的原型会被更改,从而导致修改&# 39;版本

这在许多层面上似乎都是错误的,任何人都可以解释这里发生的事情吗?

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

stuff = (function(){

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

    return { foo : foo, setFoo: setFoo};

})();

所以我怀疑$ .extend应该归咎于此。

任何输入都会很棒!

2 个答案:

答案 0 :(得分:1)

此问题与模块模式无关,与原型无关。

zz = Object.create(stuff) 

创建一个以stuff为原型的新对象。

vv = Object.create(stuff) 

使用与其原型相同的stuff对象创建一个新对象。

zzvv共享相同的原型对象,因此如果修改原型对象stuff,则更改将反映在派生对象zz和{{ 1}}。您是否通过vv或其他方式修改原型并不重要,您是否通过派生对象或原型修改原型并不重要

在您的代码中,$.extend对象附加到原型,而不是附加到派生对象foozz。在派生对象vv上调用extendFoo时,它正在修改原型上的zz,因此派生对象共享对foo的更改。

在您的第二个示例中,foo

setFoo

发生的事情是您在派生对象上设置this.foo = bar; 属性,现在它会覆盖原型foo。在派生对象上运行foo后,该对象的setFoo不再是原型foo。你可以通过运行

来看到这一点
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

您正在修改对象$.extend(this.foo,bar); ,而不是覆盖。您还可以通过this.foo

查看此信息
hasOwnProperty

答案 1 :(得分:-1)

$。extend接受第一个对象,并在其中添加第二个对象中定义的方法和变量。所以:

var a = { foo: 1 };
var b = { bar: function () {} }
var c = $.extend(a, b);

现在:

c == a == { foo: 1, bar: function () {} )

在您的原始示例中,我怀疑:

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

正在创建一个闭包,以便this继续引用stuff,以便扩展原型。

在第二个例子中,setFoo只是设置一个局部变量的值,当创建一个新的东西实例时,它不会被转发。