Reputation: 4676
I am trying to create multiple versions of an object which has an init function. I have tried using the javascript 'new' function but in this case that does not work and the console notifies me this is because it is not a function. See the code for a clearer description of what I am trying to do. I understand why this code will alert item two and not item one but I do not know how to get the correct behaviour.
var myApp = {
menu: {
init: function (name) {
this.name = name;
},
alertName: function () {
alert(this.name);
}
}
}
$(document).ready(function () {
var first = myApp.menu;
var second = myApp.menu;
first.init('item one');
second.init('item two');
first.alertName();
});
Upvotes: 0
Views: 856
Reputation: 550
You can implement your own new
if you want, this should work:
var myApp = {
menu: {
init: function (name) {
this.name = name;
},
alertName: function () {
alert(this.name);
},
new: function () {
var func = function () {}
func.prototype = this
return new func;
}
}
}
$(document).ready(function () {
var first = myApp.menu.new();
var second = myApp.menu.new();
first.init('item one');
second.init('item two');
first.alertName();
});
Upvotes: 0
Reputation: 3523
Declaring objects with {} is actually inline initialization, is already an instance and not a constructor, one solution for your problem would be to create a declarative object.
Please refer to this reference for more info:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
A quick implementation for your problem is here :
http://jsbin.com/OsoWECA/1/edit
var myApp = {
menu: function () {
this.init = function (name) {
this.name = name;
};
this.alertName = function () {
alert(this.name);
};
return this;
}
};
$(document).ready(function () {
var first = new myApp.menu();
var second = new myApp.menu();
first.init('item one');
second.init('item two');
first.alertName();
second.alertName();
});
Upvotes: 0
Reputation: 52206
You can use javascript's constructor functions, and call new
to instanciate different objects :
var myApp = {
menu: function(name){
// if menu is called as a constructor function, `this` will refer
// to the object being built
this.name = name;
}
}
myApp.menu.prototype.alertName = function(){
alert(this.name);
}
$(document).ready(function () {
var first = new myApp.menu('item one');
var second = new myApp.menu('item two');
first.alertName();
});
Upvotes: 4
Reputation: 27853
The reason only 'item two'
is alerted is because when you do first = myApp.menu
and second=myApp.menu
, both first
and second
refer to the same object. When you set the name
property of that object (this.name = name
in init
), both references point to the same object with the changed property.
The simplest way to do this is like this:
var myApp = {
menu : {
init: function (name) {
this.name = name;
},
alertName: function () {
alert(this.name);
}
}
}
var first = Object.create(myApp.menu);
var second = Object.create(myApp.menu);
first.init('item one');
second.init('item two');
first.alertName();
Demo: http://jsbin.com/OrEkaPe/1/edit
Object.create
creates a new object (duh) and sets the parameter as prototype for the new object. When you access a property on the new object and it doesn't exist, it will be accessed from the prototype instead, giving you the inheritance you want.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
Upvotes: 3
Reputation: 2497
You have to clone your object. In javascript, your variables first
and second
are two references to the same object : when modifying first
, you modify second
too.
You can use jQuery.extend()
to clone your object.
var first = jQuery.extend(true, {}, myApp.menu);
var second = jQuery.extend(true, {}, myApp.menu);
Upvotes: 2