validacion - llamar dinámicamente a la función local en javascript
validar formulario javascript html5 (4)
hay muchas preguntas similares sobre llamar funciones por nombre dinámicamente. Sin embargo, no puedo encontrar una solución a mi problema específico donde tengo funciones locales dentro de un cierre sin exponer las funciones a la interfaz pública de mi objeto.
Veamos un poco de código (este es un ejemplo ficticio) ...
(function(window,$) {
MyObject = (function($) {
var obj = {};
obj.publicMethod = function(number,otherarg) {
this[''privateMethod''+number].apply(this,[otherarg]);
};
var privateMethod1 = function(arg) {
//do something with arg
};
var privateMethod2 = function(arg) {
//do something else with arg
};
return obj;
})($);
window.MyObject = MyObject;
})(window,jQuery);
Esto no funciona porque "this" es MyObject y las funciones locales no están expuestas. También me gustaría poder verificar si la función existe antes de intentar llamarla. p.ej.
var func_name = ''privateMethod''+number;
if($.isFunction(this[func_name])) {
this[func_name].apply(this,[otherarg]);
}
No estoy seguro de cómo proceder, salvo para exponer mis funciones privadas a la interfaz pública, todo funciona entonces.
obj.privateMethod1 = function(arg) {
//do something with arg
};
obj.privateMethod2 = function(arg) {
//do something else with arg
};
Me estoy quedando sin ideas. Su ayuda y consejo es muy apreciada.
El hecho de que no pueda llamar a estas funciones desde fuera del ámbito en el que están definidas es una parte fundamental de javascript, y de hecho, de todos los lenguajes de programación.
La única forma de llamar a estas funciones es hacerlas públicas. Sin embargo, se puede aplicar un enfoque basado en la convención. El prefijo de subrayado es bastante omnipresente y generalmente se entiende que significa "no destinado a ser llamado como una función pública", por ejemplo:
obj._privateMethod1 = function(arg) {
//...
};
Las funciones privadas son variables locales y no son parte de ningún objeto. Por lo tanto, la [...]
notación para acceder a una propiedad nunca va a funcionar ya que no hay ningún objeto del que las funciones privadas sean propiedades.
En cambio, podría hacer dos objetos: private
y public
:
var public = {},
private = {};
public.publicMethod = function(number, otherarg) {
// `.apply` with a fixed array can be replaced with `.call`
private[''privateMethod'' + number].call(this, otherarg);
};
private.privateMethod1 = function(arg) {
//do something with arg
};
private.privateMethod2 = function(arg) {
//do something else with arg
};
return public; // expose public, but not private
No puede obtener una referencia a una variable local mediante una cadena. Tienes que agregar los objetos locales a un espacio de nombres:
(function(window,$) {
// Use "var MyObject = " instead of "MyObject = "!! Otherwise, you''re assigning
// the object to the closest parent declaration of MyVar, instead of locally!
var MyObject = (function($) {
var obj = {};
var local = {}; // <-- Local namespace
obj.publicMethod = function(number,otherarg) {
local[''privateMethod''+number].call(this, otherarg);
};
var privateMethod1 = local.privateMethod1 = function(arg) {
//do something with arg
};
var privateMethod2 = local.privateMethod2 = function(arg) {
//do something else with arg
};
return obj;
})($);
window.MyObject = MyObject;
})(window,jQuery);
Me sorprende que la respuesta incorrecta esté marcada como aceptada. En realidad, PUEDE obtener una referencia a una variable local mediante una cadena. Solo usando eval
:
(function(window,$) {
MyObject = (function($) {
var obj = {};
obj.publicMethod = function(number,otherarg) {
// Gets reference to a local variable
var method = eval(''privateMethod''+number);
// Do with it whatever you want
method.apply(this,[otherarg]);
};
var privateMethod1 = function(arg) {
//do something with arg
};
var privateMethod2 = function(arg) {
//do something else with arg
};
return obj;
})($);
window.MyObject = MyObject;
})(window,jQuery);
En realidad este código es muy malo y en el 99.9% de los casos no deberías usar eval
. Pero debes saber cómo funciona y qué puedes hacer con él. Yo mismo tuve algunos casos muy específicos cuando el uso de eval
era necesario.