Esse escopo é possível em javascript?
-
24-09-2019 - |
Pergunta
Estou trabalhando em uma estrutura javascript.Eu tenho vários scripts independentes parecidos com este:
core.modules.example_module = function(sandbox){
console.log('wot from constructor ==', wot);
return{
init : function(){
console.log('wot from init ==', wot);
}
};
};
esta função é chamada de outro script externo.Estou tentando passar variáveis para esta função para que possam ser acessadas without using the this keyword.
O exemplo acima apresentará um erro ao dizer que o que é indefinido.
Se eu envolver a função em uma função anônima e declarar as variáveis lá, obtenho os resultados desejados esperados
(function(){
var wot = 'omg';
core.modules.example_module = function(sandbox){
console.log('wot from creator ==', wot);
return{
init : function(){
console.log('wot from init ==', wot);
}
};
};
})();
O que estou tentando fazer é declarar as variáveis mais acima na cadeia de escopo para que possam ser acessadas no módulo sem usar a palavra-chave this como no segundo exemplo.Não acredito que isso seja possível, pois parece que o escopo de execução das funções está selado na declaração da função.
update
Para esclarecer onde estou tentando definir o que.Em um arquivo javascript separado, tenho um objeto que chama uma função de módulo de registro como esta
core = function(){
var module_data = Array();
return{
registerModule(){
var wot = "this is the wot value";
module_data['example_module'] = core.modules.example_module();
}
};
};
Solução
O que você está procurando se chama "escopo dinâmico", onde as ligações são resolvidas pesquisando a cadeia de chamadas atual.Não é muito comum fora da família Lisp (Perl suporta, através do local
palavra-chave).O escopo dinâmico não é compatível com JS, que usa escopo léxico.
Outras dicas
Considere este exemplo, usando seu código
var core = {}; // define an object literal
core.modules = {}; // define modules property as an object
var wot= 'Muhahaha!';
core.modules.example_module = function(sandbox){
console.log('wot from creator ==', wot);
return {
init: function() {
console.log('wot from init ==', wot);
}
}
}
// logs wot from creator == Muhahaha! to the console
var anObject = core.modules.example_module();
// logs wot from init == Muhahaha! to the console
anObject.init();
Contanto que wot
é definido em algum lugar na cadeia de escopo para core.modules.example_module
no ponto em que é executado, funcionará conforme o esperado.
Um pouco fora do assunto, mas você abordou o escopo das funções.As funções possuem escopo léxico, ou seja, criam seu escopo no ponto em que são definidas (ao contrário de executadas) e permitem a criação de fechamentos;Um fechamento é criado quando uma função mantém um link para seu escopo pai mesmo após o retorno do pai.
Colocando var wot;
no início do seu construtor deveria fazer isso
core.modules.example_module = function(sandbox){
var wot;
wot = 'foo'; //just so you can see it working
console.log('wot from constructor ==', wot);
return{
init : function(){
console.log('wot from init ==', wot);
}
};
};