I have a basic wrapper for Object.create to be used for our application. Basically the process is to use Object.create
on a parent object, then .extend({})
to add new functionality to it. If we need to call a method on the parent class, we just use ParentClass.myFunc.apply(this, arguments);
in the method override. The issue I'm having is when I intialize an object and call the init
function of the parent object, it overrides the parent' object's properties. How can I prevent this from happening?
Here's the main Object.create wrapper:
/**
* Simple wrapper for Object.create and Object.extend
* functionality.
*/
var My_Object = {
/**
* Simple extend function for inheritance
* @param props An object of functions to place in the new object.
* @returns {My_Object}
*/
extend: function(props) {
for(var prop in props)
this[prop] = props[prop];
return this;
},
/**
* Basic function that checks if a function is native or user-created
* @author Yong (http://stackoverflow.com/users/962254/yong)
*
* @param f The function to test if it is native
* @returns {boolean}
*
* @see http://stackoverflow.com/questions/6598945/detect-if-function-is-native-to-browser
*/
isFuncNative: function(f) {
return !!f && (typeof f).toLowerCase() == 'function'
&& (f === Function.prototype
|| /^\s*function\s*(\b[a-z$_][a-z0-9$_]*\b)*\s*\((|([a-z$_][a-z0-9$_]*)(\s*,[a-z$_][a-z0-9$_]*)*)\)\s*{\s*\[native code\]\s*}\s*$/i.test(String(f)));
},
/**
* Simple polyfill wrapper for native Object.create. Using a polyfill
* instead of native incase for some reason consumer would have overwritten
* it with unexpected usage.
*/
create: function(obj) {
// If the browser supports Object.create and hasn't been overwritten,
// use the native version instead of the polyfill
if(My_Object.isFuncNative(Object.create)) {
// If extend hasn't been defined, add it
if(!obj.hasOwnProperty('extend'))
obj.extend = My_Object.extend;
return Object.create(obj);
}
// Create empty function for polyfill
function F(){}
F.prototype = o;
// If extend hasn't been defined, add it
if(!F.prototype.extend)
F.prototype.extend = My_Object.extend;
return new F()
}
};
Then I define a base object:
var SomeParentObject = {
options: {
a: 'a',
b: 'b'
},
init: function(options) {
this.options = $.extend(this.options, options || {});
return this;
}
};
And some children object:
var ChildObject1 = My_Object.create(SomeParentObject).extend({
init: function() {
SomeParentObject.init.call(this, {b: 'c'});
return this;
}
}).init();
var ChildObject2 = My_Object.create(SomeParentObject).extend({}).init();
Now the desired result is that SomeParentObject
's options should never be modified. I can't figure out what exactly is the cause of it, but I'm sure it's something stupid I'm doing. If you do some basic console.log
s, you can see that when ChildObject2
has some options to override, it overrides it for SomeParentObject
, and therefore for all children.
console.log('<<SomeParentObject.a, SomeParentObject.b>>');
console.log(SomeParentObject.options.a + ', ' + SomeParentObject.options.b);
console.log('<<ChildObject1.a, ChildeObject1.b>>');
console.log(ChildObject1.options.a + ', ' + ChildObject1.options.b);
console.log('<<ChildObject2.a, ChildeObject2.b>>');
console.log(ChildObject2.options.a + ', ' + ChildObject2.options.b);
Which outputs:
<<SomeParentObject.a, SomeParentObject.b>>
a, c
<<ChildObject1.a, ChildeObject1.b>>
a, c
<<ChildObject2.a, ChildeObject2.b>>
a, c
What should be outputted is this:
<<SomeParentObject.a, SomeParentObject.b>>
a, b
<<ChildObject1.a, ChildeObject1.b>>
a, c
<<ChildObject2.a, ChildeObject2.b>>
a, b