Foro de elhacker.net

Programación => Desarrollo Web => Mensaje iniciado por: Dext3rCode en 4 Mayo 2016, 19:53 pm



Título: Ayuda con objetos de javascript (NodeJS)
Publicado por: Dext3rCode en 4 Mayo 2016, 19:53 pm
Que tal gente! Les escribo porque tengo una inquietud...

Estoy creando un 'mini framework' a modo de practica en NodeJs de un servidor HTTP (mas o menos algo entre connect y express).

Tengo la función http.createServer() la cual recibe la peticion y respuesta (request y response) sabemos que request es de la clase http.IncomingMessage y response corresponde a http.ServerResponse. Lo que sucede es que quiero añadirle nuevos metodos a el objeto response, cree un prototipo de la siguientr manera:

Código:

var res = { __proto__: http.ServerResponse.prototype }

res.enviar = (msg) => {... // nuevo metodo enviar
this.statusCode = 200;
this.setHeader("Content-Type","text/html");
this.write(msg);
this.end();
}


Lo que quiero es que el objeto que recibe como parametro mi funcion CreateServer() adquiera los métodos de mi nuevo objeto.

Lo implementé de la siguiente manera pero cuando en el método enviar uso this.end() o res.end() me lanza un error de undefined relacionado con el metodo connection. Lo he cambiado por res en vez the this pero tambien me lanza el err (error asignando valor content_type a undefined):

Código:

http.createServer(request, response){
 response.__proto__ = res; // o res.prototype
 response.enviar("foo"); // aqui el error
}


Título: Re: Ayuda con objetos de javascript (NodeJS)
Publicado por: MinusFour en 4 Mayo 2016, 20:22 pm
Cambiar el prototipo de un objeto en runtime no es lo ideal. El error no es relacionado a herencia, sino el hecho de que las funciones flecha no ofrecen contexto de objeto, lo que significa que no tienen this. Una función normal debería funcionar (aunque no estoy seguro si haya algún otro error).

Si quieres extender un objeto yo usaría Object.assign
Código
  1. var respuesta = Object.assign(Object.create(response), res);
  2. //res = objeto con las funciones a extender
  3. //response = el objeto inyectado en la funcion
  4. respuesta.enviar('foo');


Título: Re: Ayuda con objetos de javascript (NodeJS)
Publicado por: Dext3rCode en 5 Mayo 2016, 00:43 am
Cambiar el prototipo de un objeto en runtime no es lo ideal. El error no es relacionado a herencia, sino el hecho de que las funciones flecha no ofrecen contexto de objeto, lo que significa que no tienen this. Una función normal debería funcionar (aunque no estoy seguro si haya algún otro error).

Si quieres extender un objeto yo usaría Object.assign
Código
  1. var respuesta = Object.assign(Object.create(response), res);
  2. //res = objeto con las funciones a extender
  3. //response = el objeto inyectado en la funcion
  4. respuesta.enviar('foo');






@MinusFour Hermano muchisimas gracias, estaba dandole vueltas por que no funcionaba y me acabas de llevar a la respuesta. Muchas Gracias!

Algo que anadir es que implemente el codigo de la siguiente manera:

Código
  1.  
  2. // en el archivo response.js --->
  3.  
  4. var response = Object.assign(Object.create(http.ServerResponse));
  5. response.enviar  = function enviar(str){ ... // nuevo metodo enviar };
  6. // otros metodos
  7.  
  8. module.exports = response;
  9.  
  10.  


y en mi funcion handle que recibe los parametros 'req' y 'res' ==>

Código
  1.  
  2. var handle = function(req,res){
  3. var respuesta = Object.assign(res,response);
  4. /*
  5. siendo claramente res el parametro y response mi nuevo objeto
  6. */
  7. respuesta.enviar("Hola");
  8. }
  9.  

Es decir, tuve que omitir la parte de Object.Create en el 'asign' para que heredara los metodos anteriores porque sino solo creaba un nuevo objeto con los nuevos que yo cree y agregaba los demas en ejecucion segun los llamaba.

Al parecer esto porque con el create creaba uno nuevo y lo pasaba por parametro pero si pongo el objeto tal cual, hereda todo lo que traia mi parametro 'res'.


De Nuevo muchas gracias y esto lo dejo por si alguien quiere trastear con el codigo de la mismo forma que lo estoy haciendo.




Título: Re: Ayuda con objetos de javascript (NodeJS)
Publicado por: MinusFour en 5 Mayo 2016, 04:24 am
El punto de Object.create es de no mutar el objeto inicial.

Esta linea que has puesto:
Código
  1. var response = Object.assign(Object.create(http.ServerResponse));

La parte de Object.assign no te sirve de nada porque no estás asignando nada al objeto que estás creando. Realmente no es siquiera necesario que este objeto tenga como prototipo ServerResponse, porque al hacer Object.assign las propiedades acaban en el otro objeto.

Es decir, tuve que omitir la parte de Object.Create en el 'asign' para que heredara los metodos anteriores porque sino solo creaba un nuevo objeto con los nuevos que yo cree y agregaba los demas en ejecucion segun los llamaba.

Quitar la parte de Object.create no te exime de la asignación de las propiedades del objeto en ejecución, como mencione anteriormente la única diferencia es que con Object.create no estás mutando res y las propiedades del objeto como quiera siguen compartidas por el prototipo del objeto. Lo único es que las propiedades a extender se realizan sobre un objeto nuevo. Honestamente, no se que tan compatible sea esto con la interfaz de ServerResponse, es probable que no puedas evitar la mutación.