admin管理员组

文章数量:1344975

I have two objects defined something like this (simplified for sake of the question):

var firstObject = function(){ };
firstObject.prototype.doSomethingFirstObjectsDo();

var secondObject = function(){ };
secondObject.prototype.doSomethingSecondObjectsDo();

Next I have an Object Manager which works as a sort of interface for my main application to create objects:

var ObjectManager = function()
{
    this.create = {
        FIRST:firstObject,
        SECOND:secondObject
    };
};

ObjectManager.prototype.createObject = function(type)
{
    return new this.create[type]();
};

Finally an example of the main application using the Object Manager to Dynamically Create Either firstObjects or secondObjects:

var MainApplication = function(options)
{
    this.objectTypes = options.objectTypes;
    this.objManager = new ObjectManager();
};

MainApplication.prototype.createObjects = function()
{
    //Iterate through all the types this application needs to create
    for (var type in this.objectTypes)
    {
        var dynamicallyCreatedObject = this.objManager.createObject(type);
        //Do Something Else
    }
};

This approach works great, but has one disadvantage that I can see - being that you need to formally define the name of the Constructor Function for each Object "Type" that could be created.

In the event that I wanted to create a "thirdObject" - which would be already formally defined - I would also need to go back and add a reference to the "thirdObject"'s constructor function in the ObjectManager.

Ideally, I would like to remove the need for an "ObjectManager" and simply be able to dynamically call the constructor method with the "new" keyword like this:

//Inside MainApplication
for (var type in this.objectTypes)
{
    var dynamicallyCreateObject = new [type]();  //Invalid Syntax
};

Anybody have any thoughts on a better way to handle dynamically creating different objects in JavaScript using the "new" keyword?


Responding to Some Initial Comments:

I should have mentioned that the entire application is enclosed within an anonymous function.

(function(){
    //All of My Mentioned Code is Found Here
    $(document).ready(function(){
        mainApp = window.mainApp = new MainApplication(options);
    });
});

@casablanca: From what you are saying I believe I'll need to actually define a NameSpace inside the entire anonymous function, since once it finishes I have no real way to directly refer to that scope again. I think I know what I need to do now, I was kind of hoping there was another way to work with that "new" keyword - but it doesn't seem like that is the case.

I have two objects defined something like this (simplified for sake of the question):

var firstObject = function(){ };
firstObject.prototype.doSomethingFirstObjectsDo();

var secondObject = function(){ };
secondObject.prototype.doSomethingSecondObjectsDo();

Next I have an Object Manager which works as a sort of interface for my main application to create objects:

var ObjectManager = function()
{
    this.create = {
        FIRST:firstObject,
        SECOND:secondObject
    };
};

ObjectManager.prototype.createObject = function(type)
{
    return new this.create[type]();
};

Finally an example of the main application using the Object Manager to Dynamically Create Either firstObjects or secondObjects:

var MainApplication = function(options)
{
    this.objectTypes = options.objectTypes;
    this.objManager = new ObjectManager();
};

MainApplication.prototype.createObjects = function()
{
    //Iterate through all the types this application needs to create
    for (var type in this.objectTypes)
    {
        var dynamicallyCreatedObject = this.objManager.createObject(type);
        //Do Something Else
    }
};

This approach works great, but has one disadvantage that I can see - being that you need to formally define the name of the Constructor Function for each Object "Type" that could be created.

In the event that I wanted to create a "thirdObject" - which would be already formally defined - I would also need to go back and add a reference to the "thirdObject"'s constructor function in the ObjectManager.

Ideally, I would like to remove the need for an "ObjectManager" and simply be able to dynamically call the constructor method with the "new" keyword like this:

//Inside MainApplication
for (var type in this.objectTypes)
{
    var dynamicallyCreateObject = new [type]();  //Invalid Syntax
};

Anybody have any thoughts on a better way to handle dynamically creating different objects in JavaScript using the "new" keyword?


Responding to Some Initial Comments:

I should have mentioned that the entire application is enclosed within an anonymous function.

(function(){
    //All of My Mentioned Code is Found Here
    $(document).ready(function(){
        mainApp = window.mainApp = new MainApplication(options);
    });
});

@casablanca: From what you are saying I believe I'll need to actually define a NameSpace inside the entire anonymous function, since once it finishes I have no real way to directly refer to that scope again. I think I know what I need to do now, I was kind of hoping there was another way to work with that "new" keyword - but it doesn't seem like that is the case.

Share Improve this question edited Nov 18, 2010 at 23:12 John asked Nov 18, 2010 at 22:54 JohnJohn 1,03711 silver badges19 bronze badges 2
  • 1 What are you trying to achieve? That seems like an awful lot of code to do not much of anything. – Pointy Commented Nov 18, 2010 at 23:03
  • I am working on making an application that is flexible enough to respond to a variety of data that will all need to be interpreted, displayed, and interacted with in pletely different ways. Setting up a nice interface like this makes it way easier for me to change code behavior for particular objects later, without having to go back and re-factor a other objects, such as an "ObjectManager". I don't want my code to assume that it knows it is going to create a 'firstObject' or a 'secondObject' so hard-coding it is not an object for me. – John Commented Nov 18, 2010 at 23:14
Add a ment  | 

2 Answers 2

Reset to default 8

This:

var dynamicallyCreateObject = new [type]();

is almost correct, except you need an outer object to access properties. In the case that your constructors are global, you can use window:

var dynamicallyCreateObject = new window[type]();

Ideally, they should be within your own namespace, in which case you can do something similar:

var dynamicallyCreateObject = new MyNamespace[type]();

Assuming I understand your desire (and I'm not sure that I do) you can use the global window object in DOM 0 browsers, or create your own reference to the global scope, and use that to look up variables defined locally.

var $global = this;
var firstObject = function(){};

var objName = "firstObject";
var instance = new $global[objName];

本文标签: design patternsBetter way to Dynamically Create New Objects in JavaScriptStack Overflow