Peter Saxton
Peter Saxton

Reputation: 4676

creating multiple instances of a object property

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

Answers (5)

tikider
tikider

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

Tiberiu C.
Tiberiu C.

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

LeGEC
LeGEC

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();
});

fiddle

Upvotes: 4

Tibos
Tibos

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

Elorfin
Elorfin

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

Related Questions