A bit of confusion regarding what exactly is going on here.
given this simple code :
stuff = (function(){
function extendFoo(bar)
{
$.extend(this.foo,bar);
}
this.foo = {};
return { foo : foo, extendFoo: extendFoo};
})();
Following this simple operation :
zz = Object.create(stuff);
zz.extendFoo({bar:'bar'});
vv = Object.create(stuff); //foo is still extended(??)
So from what I realized, operations conducted on the returned object form Object.create still affect the prototype of that Object, So when you create a new object, his prototype is changed, thus resulting in a 'modified' version.
This seems wrong on a lot of levels, Can anyone explain what's going on here?
this behavior is not reproducible using the following pattern :
stuff = (function(){
function setFoo(bar)
{
this.foo = bar;
}
var foo;
return { foo : foo, setFoo: setFoo};
})();
So I suspect $.extend is to blame here.
Any input would be great!
This problem has nothing to do with the module pattern and everything to do with prototypes.
zz = Object.create(stuff)
creates a new object with stuff
as its prototype.
vv = Object.create(stuff)
creates a new object with the same stuff
object as its prototype.
Both zz
and vv
share the same prototype object, so if you modify the prototype object stuff
, then changes will reflect in both derived objects zz
and vv
. It doesn't matter whether you're modifying the prototype via $.extend
or other means, and it doesn't matter whether you're modifying the prototype via your derived object or your prototype.
In your code, the foo
object is attached to the prototype, not to the derived objects zz
and vv
. When extendFoo
is invoked on the derived object zz
, it is modifying foo
on the prototype, so changes to foo
are shared by the derived objects.
In your second example, in setFoo
this.foo = bar;
what's happening is that you're setting the foo
property on the derived object so now it overrides the prototype's foo
. After you run setFoo
on a derived object, that object's foo
is no longer the prototype's foo
. You can see this by running
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
you'd actually get back your original foo
instead of null
.
The reason why setFoo
works in the second case is because you are no longer modifying the prototype, so the changes are no longer shared between derived objects. With the original's
$.extend(this.foo,bar);
you're modifying the object this.foo
in place and not overriding. You can also see this via hasOwnProperty
zz = Object.create(stuff);
console.log(zz.hasOwnProperty('foo')); // false
zz.extendFoo({bar:'bar'});
console.log(zz.hasOwnProperty('foo')); // false