I've been trying to see if there's a way around the typical process of extending an object, whereby it shows that it's assigning the extended properties to prototype of the object, but attached to the 'extend' method itself on the current object. I want the properties to be assigned DIRECTLY on the current object (ie. "this.property" and not "this.extend.property"). Let me explain:
As far as I know, there are two ways to "extend" an object in Javascript:
1) global function:
function extend(a, b){
for(var key in b)
if(b.hasOwnProperty(key))
a[key] = b[key];
return a;
}
I can then run this code to "extend" my App object:
function App() {
extend(this, {
command: function () {
alert('command!');
}
});
console.log(this);
return this;
}
2) Another way to extend is to use the Object prototype directly, ie:
Object.prototype.extend = function(obj) {
for(i in obj)
this[i] = obj[i];
};
And then extend App with:
function App() {
this.extend({
command: function () {
alert('command!');
}
});
console.log(this);
return this;
}
command: function () {
arguments: null,
caller: null,
length: 0,
name: "",
prototype: App.extend.command
}
Notice the 'App.extend.command'? I am wondering if there is ANY way to extend the properties so that they are DIRECT attributes of the App object, so that prototype will show: "prototype: App.command".
I can achieve this if I assign the propertie directly to "this", like:
function App() {
this.command = function () {
alert('command!');
}
console.log(this);
return this;
}
Which outputs:
command: function () {
arguments: null,
caller: null,
length: 0,
name: "",
prototype: App.command
}
However, I don't want to have to use the format of "this.blah = function()" for all of my properties. I would rather just extend the current object with a JSON list of properties as shown in the first two examples. Is there anyway to do this so that I can still keep my 'newable' function declarations?
I will add that is preferable to NOT use the prototype method, as this will add the 'extend' property to ALL objects in the application, which is not desirable for certain objects.
Thanks for reading!
To get things more clearly you should inspect all three ways you've posted with Firebug in Firefox. What the webkit-consoles output there has nothing to do with App.prototype but is the hierarchy of all functions called to setup the command
-property. The App.prototype you find under App.__proto__
.
With your way 1) you definitely set all properties of object b as own properties of each App instance (= this). These props and also function extend()
becomes not part of the App prototype. You can check it out:
console.log(App.prototype);
// or you create an instance of App and search for its prototype:
var myapp = new App(); console.log(Object.getPrototypeOf(myapp));
You achieve exactly the same result as by way 1) when you incorporate function extend()
in the App constructor like this:
function App(b) {
if (typeof b == 'object') for (var key in b) this[key] = b[key];
console.log(this);
// Aside: you don't need 'return this', it's done automatically when you use 'new App()'
}
var obj = {command: function () {alert('command!');}};
var myapp = new App(obj);
I would prefer this method because it's easy to rule which App object gets what properties simply by passing them in as argument.
Only with your way 2) function extend()
becomes a property of App.prototype because you explicitely define it so. Then its inherited to all App instances.