2015-06-01 2 views
0

У меня есть класс JS, который принимает в нескольких аргументах:Instantiate JS объект, которые принимают массив аргументов от имени Струнного

var MyClassName = function(arg1, arg2, arg3){ // Do stuff };

У меня есть строка, которая представляет имя класса, и массив аргументов.

var class = "MyClassName" 
var args = ["1", "2", "3"] 

Использование строки имени класса и массива аргументов, как я могу создать экземпляр класса? Прототип Bind/apply кажется несколько актуальным, но я не могу понять, как все это работает. Я также пытался использовать окно ["MyClassName"], но это порождает неопределенную ошибку. Какие-либо предложения?

+0

возможно дубликат [Какие методы могут быть использованы для определения класса в JavaScript, и каковы их компромиссы?] (HTTP: // stackoverflow.com/questions/387707/what-techniques-can-be-used-to-define-a-class-in-javascript-and-what-are-their) – RafaelKr

+0

Извините, тогда я не отменил ваш ответ. – RafaelKr

+0

Чтобы уточнить, я пытаюсь создать экземпляр нового экземпляра класса на основе строки имени класса. Класс принимает несколько аргументов, но я хочу передать только массив или аргументы. – ph34r

ответ

0

Спасибо всем за прекрасные предложения. Я объединил часть ответов здесь, в дополнение к this SO answer:

var className = new window['MyClassName'] var instantiatedClass = className.bind.apply(className, [null, arg1, arg2, ...]);

1

Вы можете использовать eval:

var a = eval("new " + className + " (" + arguments.toString() + ")"); 

Пример:

JSFIDDLE: https://jsfiddle.net/s40ave7r/

function A(a1,a2,a3) { 
    this.a1 = a1; 
    this.a2 = a2; 
    this.a3 = a3; 
} 

var className = "A"; 
var arguments = [1,2,3]; 

var a = eval("new " + className + " (" + arguments.toString() + ")"); 

console.log(a); // A {a1:1, a2:2, a3:3} 

Примечание:

Использование eval в целом является б идея объявления. Если вы можете попытаться избежать этого. Вот некоторые проблемы, связанные с eval:

  1. Неправильного использование Eval открывает код для атак пути внедрения
  2. Отладка может быть более сложной (без номеров строк и т.д.)
  3. eval «d код выполняет более медленно (нет возможности компиляции/кэш eval «d код)

Решение 2

Другим решением является присоединение определения класса к объекту. Например, когда вы определяете класс в глобальной области видимости, он по умолчанию привязывается к объекту window в браузере или к объекту global в узле. Так что вы можете сделать:

Browser

function MyClass() {} 
new window["MyClass"](arg1, arg2..); 

Узел

function MyClass() {} 
new window["MyClass"](arg1, arg2..); 
1

Вы можете определить свой 'класс', как

window.MyClassName = function(arg1, arg2, ...) { 
    this.arg1 = arg1; 
    //... 
}; 

, то вы можете назвать его

var instance = new window['MyClassName'](arg1, arg2, ...) 

или

var instance = new window.MyClassName(arg1, arg2, ...); 

или лучше не использовать окно, использовать собственный объект.

var classes = { 
    MyClassName: function(arg1, arg2, ...) { 
     this.arg1 = arg1; 
     //... 
    } 
}; 

var instance = new classes.MyClassName(arg1); 

Edit: Вы сказали, что окно [ «MyClassName»] не работает, но если определить «класс» в глобальном масштабе, то вы можете назвать это так. Не могли бы вы добавить ошибку, которую вы имели в виду?

function testClass(arg1) { 
    this.foo = arg1; 
} 

var instance = new window['testClass']('bar'); 
console.log(instance.foo); // The output will be bar 

Этот код работает, но, возможно, вы забыли «новое». Если вы попытаетесь это сделать без «нового», то он выдает эту ошибку в Chrome:

Uncaught TypeError: Cannot read property 'foo' of undefined