Então, digamos que você siga um padrão de design específico em JavaScript, em que você cria um “namespace” para todas as suas funções, como:
window.App = {};
window.App.coolTrick = function( value ) {
return 'Foo stands for: ' + value;
}
Agora você pode fazer algo incrível como:
var foo_stands_for = App.coolTrick( 'found obligatory object' );
console.log( foo_stands_for );
Agora, o que acontece se de alguma forma você tiver o valor da string de uma função com namespace particular? Talvez você tenha obtido a string de uma resposta JSON, ou talvez você esteja fazendo uma loucura de “convenção sobre configuração”, ou talvez você apenas tenha a string sem motivo aparente.
var function_name = 'coolTrick';
O que você pode fazer com este nome de função? Bem, obviamente você poderia apenas fazer algo assim:
foo_stands_for = App[ function_name ]( 'Fill Oswald Orderly' );
OU podemos fazer algo ligeiramente mágico, como isto:
String.prototype.functionize = function() {
var string_value = this;
var theFunction = App[ string_value ];
return theFunction.prototype.apply( window, arguments );
}
foo_stands_for = function_name.functionize( 'forged oblivion oreo' );
// also the same as
foo_stands_for = 'coolTrick'.functionize( 'foolish orthopedic operator' );
“Caramba”, você diz. “Mal posso esperar para experimentar”, você proclama. Mas espere, há 2 coisas que você deve saber:
1) Eu não testei este código, então certamente há um bug em algum lugar
2) Este exemplo não faz o melhor uso dele … fique ligado
C) Isso se destina a iniciar sua solução criativa de problemas.
Esperamos que você compreenda essas 2 coisas antes de seguir em frente. Compreendê-los? Então vamos continuar.
Um cenário decente (er)
Portanto, vamos supor que você tenha um bom conhecimento sobre injeção de dependência. Você deseja minimizar as dependências do código. Se você estiver trabalhando em um aplicativo bastante grande, pode começar a pensar “Meu código vai quebrar se eu tiver que mudar minha convenção de namespacing?” ou alguma bobagem como essa. Deixe-me ilustrar aqui:
// let's set up our primary namespace
window.App = { Models : {}, Views : {}, Routers : {}, Helpers : {} };
// now all future models, views, routers, helpers, etc can
// live in this namespace
( function() {
var someModel = function() {
}
return window.App.Models.someModel = someModel;
})();
Ok, até agora tudo bem. temos um modelo chamado someModel e tem um namespace bonito e agradável. Mas isso requer que o código para algum modelo precisa conhecer a convenção de namespacing utilizada pelo seu aplicativo. E se você pudesse fazer isso:
String.prototype.modelNamespace = function( model ) {
var name = this
return window.App.Models[ name ] = model;
}
( function() {
var name = 'theNameOfThisModel';
var someModel = function() {
}
// all the model knows is his own name, a method
// to make a namespace of his name, and that
// he is, in fact, a model
return name.modelNamespace( someModel );
})();
Novamente, você provavelmente encontrará alguns bugs neste código não testado, mas espero que isso o inspire a ponderar um pouco mais sobre como chegar a algumas soluções incríveis e legais.