2017-01-27 11 views
0

Рассмотрим следующий пример:Динамически вызова конструктора из IIFE

function windowTest() { } 

(function() { 
    function test() { } 

    var test1 = new test(); // Works fine. 
    var test2 = new window["windowTest"](); // Works since windowsTest is declared globally. 
    var test3 = new window["test"](); // Fails since in an IIFE. 

    // How can I create a testObj if I only have the string "test"? 
})(); 

В принципе, я хочу, чтобы создать объект, функция которого была объявлена ​​в IIFE.

+1

Re 'test3' : Зачем вам нужно получить доступ к этой функции в объекте 'window', а не использовать его напрямую? –

+1

Почему новый тест() не работает? –

+0

test() действительно работает, обновил комментарий. – smulz

ответ

2

Причина

var test3 = new window["test"](); 

терпит неудачу, потому что test не был объявлен во всем мире. Если вы хотите получить доступ к элементам, объявленным непосредственно внутри IIFE, как вы знаете, вы можете получить к ним доступ по имени.

new test(); 

Другой способ сохранить вашу функцию внутри какого-то объекта, то доступ к этому объекту, как вы делали с window. Это почти всегда решение этих проблем.

(function() { 
 
    var context = { 
 
    test: function() { 
 
     console.log('new test'); 
 
    } 
 
    }; 
 
    
 
    var test = new context['test'](); 
 
})();

Последний способ использует eval. eval почти всегда a really bad idea. Действительно, его следует избегать, если вы не злоупотребляете языком просто ради интереса. Но вы может использовать его в этом случае.

(function() { 
 
    function test() { 
 
    console.log('new test'); 
 
    } 
 
    
 
    var test = eval('new test()'); 
 
})();

1

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

(function() { 
    this.test = function() {} 
    console.log(this["test"]()) 
})() 

Или используйте отдельную переменную:

(function() { 
    var foobar = { 
     test: function() { } 
    }; 
    console.log(foobar["test"]()) 
})(); 
+2

Примечание: использование 'this' не будет выполняться в строгом режиме, так как' this' будет 'undefined'. В нестрогом режиме вы будете добавлены значения для глобального объекта. –

1

Вы можете связать свои функции следующим образом:

function(){ 
//your code using 
this.test("Hi"); 
this["test"]("Hi"); 
}.call({ 
//function declarations: 
test:window.alert, 
}); 

Все еще IIFE так это обыкновение работать в глобальном контексте:

this.test("Hi");//reference Error