If I create multiple objects using Object.create() on an object literal, I get multiple unique objects that don't share property values. However, when I use Object.create() on an object returned from a module, it looks like they share the same reference? Why is that?
var objModule = (function () {
var name = "module 1";
var setName = function( strName ) {
name = strName;
};
var getName = function() {
return name;
};
return {
setName: setName,
getName: getName
};
}());
var objModule2 = Object.create(objModule);
objModule2.setName("module 2");
console.log(objModule.getName()); // WRONG prints "module 2"
console.log(objModule2.getName()); // prints "module 2"
var objLiteral = {
name : "literal 1"
};
var objLiteral2 = Object.create(objLiteral);
objLiteral2.name = "literal 2";
console.log(objLiteral.name); // prints "literal 1"
console.log(objLiteral2.name); // prints "literal 2"
var module = function () {
var name = "module 1";
var setName = function( strName ) {
name = strName;
};
var getName = function() {
return name;
};
return {
setName: setName,
getName: getName
};
};
var objModule1 = module();
var objModule2 = module();
objModule2.setName("module 2");
console.log(objModule1.getName()); // prints "module 1"
console.log(objModule2.getName()); // prints "module 2"
If I use the module like a constructor (as suggested by @Matt Browne) and create 2 objects, the result is like using an object literal. What I'd like to understand is why does module example #1 behave differently than module example #3?
As @ben336 explained, the code:
var objModule2 = Object.create(objModule);
will set the objModule2's prototype to objModule. That doesn't happen in example #3, so those two objects don't share the same closure property.
The first argument of Object.create
specifies the prototype object for the new object being created. Since in your first example you're setting your existing object to be the prototype of your new object, when you call the functions they're modifying the variable you've stored in a closure, which is then accessed by both your existing object and the new one.
The 2 key things to understand here are:
This code
var objModule = function () {
var name = "module 1";
var setName = function( strName ) {
name = strName;
};
var getName = function() {
return name;
};
return {
setName: setName,
getName: getName
};
}();
creates a closure with the functions getName and setName holding access to the name
variable.
those functions are properties of objModule, and when you call Object.create
you set objModule to be the prototype of objModule2, and it gains access to those functions as well.
Since the 2 objects share those functions, and they have access to the closure created by the module rather than storing the name property locally on either object, when you call the set function with one object, it will update the closure and thus update both objects.
In the second example you're also setting the object to be the prototype of the new object, but you're declaring a property on the local object which overrides the property on the prototype.
objModule2.setName
refers to the same function as objModule.setName
, but with a different this
. (Object.create
doesn't copy anything)
Calling it will set the same local variable.
objLiteral2.name = "literal 2"
creates a new property on objLiteral2
, which shadows the inherited objLiteral.name
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With