关于这里到底发生了什么,有点混乱。
给出这个简单的代码:
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应该归咎于此。
任何输入都会很棒!
答案 0 :(得分:1)
此问题与模块模式无关,与原型无关。
zz = Object.create(stuff)
创建一个以stuff
为原型的新对象。
vv = Object.create(stuff)
使用与其原型相同的stuff
对象创建一个新对象。
zz
和vv
共享相同的原型对象,因此如果修改原型对象stuff
,则更改将反映在派生对象zz
和{{ 1}}。您是否通过vv
或其他方式修改原型并不重要,您是否通过派生对象或原型修改原型并不重要
在您的代码中,$.extend
对象附加到原型,而不是附加到派生对象foo
和zz
。在派生对象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只是设置一个局部变量的值,当创建一个新的东西实例时,它不会被转发。