Javascript 模块模式 - Object.create
Javascript module pattern - Object.create
对这里到底发生了什么有点困惑。
给定这个简单的代码:
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 仍然会影响该对象的原型,因此当您创建一个新对象时,他的原型会发生变化,从而导致 'modified'版本。
这在很多层面上似乎都是错误的,谁能解释一下这是怎么回事?
使用以下模式无法重现此行为:
stuff = (function(){
function setFoo(bar)
{
this.foo = bar;
}
var foo;
return { foo : foo, setFoo: setFoo};
})();
所以我怀疑 $.extend 是罪魁祸首。
任何输入都会很棒!
此问题与模块模式无关,与原型有关。
zz = Object.create(stuff)
创建一个以 stuff
作为其原型的新对象。
vv = Object.create(stuff)
创建一个新对象,其原型与 stuff
对象相同。
zz
和 vv
共享同一个原型对象,因此如果您修改原型对象 stuff
,那么更改将反映在派生对象 zz
和vv
。您是通过 $.extend
还是其他方式修改原型并不重要,您是通过派生对象还是原型修改原型也无关紧要。
在您的代码中,foo
对象附加到原型,而不是派生对象 zz
和 vv
。当在派生对象 zz
上调用 extendFoo
时,它正在修改原型上的 foo
,因此对 foo
的更改由派生对象共享。
在你的第二个例子中,setFoo
this.foo = bar;
发生的事情是您在派生对象上设置了 foo
属性,所以现在它覆盖了原型的 foo
。在派生对象上 运行 setFoo
之后,该对象的 foo
不再是原型的 foo
。你可以通过运行ning
看到这个
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
查看
zz = Object.create(stuff);
console.log(zz.hasOwnProperty('foo')); // false
zz.extendFoo({bar:'bar'});
console.log(zz.hasOwnProperty('foo')); // false
对这里到底发生了什么有点困惑。
给定这个简单的代码:
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 仍然会影响该对象的原型,因此当您创建一个新对象时,他的原型会发生变化,从而导致 'modified'版本。
这在很多层面上似乎都是错误的,谁能解释一下这是怎么回事?
使用以下模式无法重现此行为:
stuff = (function(){
function setFoo(bar)
{
this.foo = bar;
}
var foo;
return { foo : foo, setFoo: setFoo};
})();
所以我怀疑 $.extend 是罪魁祸首。
任何输入都会很棒!
此问题与模块模式无关,与原型有关。
zz = Object.create(stuff)
创建一个以 stuff
作为其原型的新对象。
vv = Object.create(stuff)
创建一个新对象,其原型与 stuff
对象相同。
zz
和 vv
共享同一个原型对象,因此如果您修改原型对象 stuff
,那么更改将反映在派生对象 zz
和vv
。您是通过 $.extend
还是其他方式修改原型并不重要,您是通过派生对象还是原型修改原型也无关紧要。
在您的代码中,foo
对象附加到原型,而不是派生对象 zz
和 vv
。当在派生对象 zz
上调用 extendFoo
时,它正在修改原型上的 foo
,因此对 foo
的更改由派生对象共享。
在你的第二个例子中,setFoo
this.foo = bar;
发生的事情是您在派生对象上设置了 foo
属性,所以现在它覆盖了原型的 foo
。在派生对象上 运行 setFoo
之后,该对象的 foo
不再是原型的 foo
。你可以通过运行ning
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
zz = Object.create(stuff);
console.log(zz.hasOwnProperty('foo')); // false
zz.extendFoo({bar:'bar'});
console.log(zz.hasOwnProperty('foo')); // false