Foros del Web » Programando para Internet » Javascript »

[SOLUCIONADO] Añadir métodos a una clase no enumerables.

Estas en el tema de Añadir métodos a una clase no enumerables. en el foro de Javascript en Foros del Web. Buenas, Tengo el siguiente problema añadiendo nuevos métodos a una clase Javascript. Por ejemplo, defino estos dos métodos: @import url("http://static.forosdelweb.com/clientscript/vbulletin_css/geshi.css"); Código Javascript : Ver original ...
  #1 (permalink)  
Antiguo 17/12/2013, 05:45
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Añadir métodos a una clase no enumerables.

Buenas,

Tengo el siguiente problema añadiendo nuevos métodos a una clase Javascript. Por ejemplo, defino estos dos métodos:

Código Javascript:
Ver original
  1. Array.prototype.equal = function( e )
  2. {
  3.     return !( this < e || e < this );
  4. }
  5.  
  6. Array.prototype.findIndex = function( callback ) {
  7.     for( i in this )
  8.         if( callback(i,this[i],this) )
  9.             return i;
  10.     return -1;
  11. }

Y los aplico:
Código Javascript:
Ver original
  1. console.log( [3,4].equal([3,4]) );
  2. console.log( [[6,3],[1,2]].findIndex( function(e){ return e.equal([1,2]) }) );
Y me manda el siguiente error:
Código Javascript:
Ver original
  1. true test.js:85
  2. Uncaught TypeError: Object 0 has no method 'equal'
No sé a que se refiere al objeto 0. Así que debugueo un poco:
Código Javascript:
Ver original
  1. Array.prototype.findIndex = function( callback ) {
  2.     for( i in this )
  3.         console.log( i );
  4.         /*if( callback(i,this[i],this) )
  5.             return i;
  6.     return -1;*/
  7. }
Y veo que me enumera tanto los indices 0,1 como los nuevos métodos definidos equal y findIndex:
Código Javascript:
Ver original
  1. true test.js:85
  2. 0 test.js:16
  3. 1 test.js:16
  4. equal test.js:16
  5. findIndex test.js:16
  6. undefined
He mirado a que se debe y he encontrado que existe un método Object.defineProperty que por un lado evitaría que recorriera las nuevas propiedades equal y findIndex , poniendo el valor de "enumerable" a false. Sin embargo, se describe Object.defineProperty como modificador de un objeto/instancia y no de una clase. A mi me gustaría añadir un método no enumerable en una clase.

¿Hay alguna manera de hacerlo? ¿El error "Uncaught TypeError: Object 0 has no method 'equal' " tiene algo que ver con que al recorrer el array se recorren también dichos nuevos métodos definidos?

Un saludo y gracias!
__________________
github.com/xgbuils | npm/xgbuils
  #2 (permalink)  
Antiguo 17/12/2013, 07:13
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 3 meses
Puntos: 206
Respuesta: Añadir métodos a una clase no enumerables.

El problema que tienes es una tontería.
Estás llamando a callback con los argumentos en un orden que no vas a poder usar tal y como has definido la función que mandas como callback en el último console.log. Mandas "i" al callback, que es un "string" que corresponde a un entero) cuando lo que se espera es un Array.

Para usarlo como quieres, pon:
callback(this[i],this,i) dentro del prototipo findIndex de array.

Por cierto, bonita forma de comparar arrays de tipos primitivos xd. Pero no funcionará bien cuando el array contenga objetos.

Última edición por marlanga; 17/12/2013 a las 07:24
  #3 (permalink)  
Antiguo 17/12/2013, 08:32
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Respuesta: Añadir métodos a una clase no enumerables.

Gracias, menudo fallo más tonto he tenido.

De todas maneras el tema de no querer enumerar los nuevos métodos del array sigue vigente. Pues si quisiera hacer algo como:
Código Javascript:
Ver original
  1. var array = [[6,3],[1,2]];
  2. for( var i in array )
  3.     console.log( array[i].equal([1,2]) );
Me devuelve:
Código Javascript:
Ver original
  1. false test.js:87
  2. true test.js:87
  3. Uncaught TypeError: Object function ( e )
  4. {
  5.     return !( this < e || e < this );
  6. } has no method 'equal'
Vaya, que el array recorre [6,3], [1,2], equal y findIndex. Cuando sólo quiero que recorra los dos primeros. Investigaré un poco más a ver, pero Object.defineProperty he visto que es para objetos/intancias y no para clases.

Cita:
Iniciado por marlanga
Por cierto, bonita forma de comparar arrays de tipos primitivos xd. Pero no funcionará bien cuando el array contenga objetos.
Dejo como pendiente lo de generalizarlo. De momento sólo lo he creado para que funcione en el caso que me interesa. Si javascript pudiera sobrecargar definiciones de operadores como a la C++ ya sería genial.
__________________
github.com/xgbuils | npm/xgbuils
  #4 (permalink)  
Antiguo 17/12/2013, 08:47
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 3 meses
Puntos: 206
Respuesta: Añadir métodos a una clase no enumerables.

Sí puedes usar defineProperty para declarar métodos.

Código Javascript:
Ver original
  1. Object.defineProperty(Array.prototype, "equal", {
  2.     value: function(e)
  3.     {
  4.         return !( this < e || e < this );
  5.     },
  6.     enumerable: false
  7. });
  8.  
  9. var array = [[6,3],[1,2]];
  10. for( var i in array )
  11.     console.log( array[i].equal([1,2]) );

Javascript no permite sobrecarga, pero hay formas de emularla mediante el número de argumentos y su tipo.

Última edición por marlanga; 17/12/2013 a las 09:28
  #5 (permalink)  
Antiguo 17/12/2013, 11:04
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 2 meses
Puntos: 260
Sonrisa Respuesta: Añadir métodos a una clase no enumerables.

Hola,

Posiblemente, otra forma de hacerlo:

Cita:
Iniciado por Pantaláimon Ver Mensaje
Código Javascript:
Ver original
  1. for( var i in array )
Código Javascript:
Ver original
  1. for( i = 0; i < array.length; i++ )

Saludos,
  #6 (permalink)  
Antiguo 17/12/2013, 13:32
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Respuesta: Añadir métodos a una clase no enumerables.

Gracias marlanga.

Tengo que mirar de encajar las piezas sueltas de los conocimientos prototype, pues por un lado sé que sirve para aplicar herencia con javascript. Por otro lado, puedo definir métodos de clase con este, y ahora veo que puede introducirse también como parámetro del método defineProperty, pero aún no he mirado documentación referente a prototype en general.

[QUOTE="HackmanC" ]Posiblemente, otra forma de hacerlo:[/QUOTE]
Posiblemente, no. ¡Claramente! Aquí dejo otras por si te interesa:


[HIGHLIGHT="Javascript"]for( i = 0; i < array.length; ++i )
[/HIGHLIGHT]
Código Javascript:
Ver original
  1. var i = 0;
  2. while( i < array.length ) {
  3.      ...
  4.      i++;
  5. }
Código Javascript:
Ver original
  1. var i = 0;
  2. while( i < array.length ) {
  3.      ...
  4.      ++i;
  5. }
__________________
github.com/xgbuils | npm/xgbuils

Última edición por Pantaláimon; 17/12/2013 a las 13:39
  #7 (permalink)  
Antiguo 17/12/2013, 13:43
Avatar de marlanga  
Fecha de Ingreso: enero-2011
Ubicación: Murcia
Mensajes: 1.024
Antigüedad: 13 años, 3 meses
Puntos: 206
Respuesta: Añadir métodos a una clase no enumerables.

Te has olvidado de
Código Javascript:
Ver original
  1. var n=array.length;
  2. while (n--)
  3. {
  4.     console.log(array[n]);
  5. }

Se me ha caído un mito.
  #8 (permalink)  
Antiguo 17/12/2013, 14:51
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Respuesta: Añadir métodos a una clase no enumerables.

Cita:
Iniciado por marlanga Ver Mensaje
Se me ha caído un mito.
Lo siento! No sabía que en Javascript podían hacer bucles descendientes. Hubiera optado directamente por la recursión:

Código Javascript:
Ver original
  1. var array = [1,2,3,4,5];
  2. (function f(array,n){
  3.     if( n > 0 ) {
  4.         console.log( array[n-1] );
  5.         f(array,n-1);
  6.     }
  7. })( array, array.length );
__________________
github.com/xgbuils | npm/xgbuils
  #9 (permalink)  
Antiguo 17/12/2013, 16:08
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 2 meses
Puntos: 260
Sonrisa Respuesta: Añadir métodos a una clase no enumerables.

Hola,

Cita:
Iniciado por Pantaláimon Ver Mensaje
Posiblemente, no. ¡Claramente! Aquí dejo otras por si te interesa:
Seguramente hay muchas.

Me refería a que para usar arreglos se usa siempre for(;;), el for(in) se usa para objetos.

Saludos,
  #10 (permalink)  
Antiguo 17/12/2013, 17:26
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Respuesta: Añadir métodos a una clase no enumerables.

Array es un objeto HackmanC. Por eso tanto funciona for(in) como for(;;). De hecho, aunque no pondría la mano en el fuego, porque hace poco que estoy estudiando Javascript, estoy bastante seguro que, excepto los tipos undefined, null, boolean, number y string, lo demás son objetos.

Un saludo.
__________________
github.com/xgbuils | npm/xgbuils

Última edición por Pantaláimon; 17/12/2013 a las 17:32
  #11 (permalink)  
Antiguo 17/12/2013, 19:35
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 2 meses
Puntos: 260
Sonrisa Respuesta: Añadir métodos a una clase no enumerables.

Hola,

Cita:
Iniciado por Pantaláimon Ver Mensaje
Array es un objeto HackmanC. Por eso tanto funciona for(in) como for(;;). ...
Exactamente, veamos, el punto es el siguiente, el Array es un objeto, pero en ese caso, que necesitas solamente los valores del Array y no todas sus propiedades y métodos, como es la mayoría de los casos en los cuales recorres un Array, se usa el for(;;).

Eso no significa que el Array deje de ser un Objeto, ni que el for(in) no funcione realizando su actividad correctamente; simplemente que además de devolver los valores que contiene el Array, también te va a devolver sus propiedades y métodos.

Es por eso que en la mayoría de la documentación se refiere a que cuando necesitas recorrer un Array debes usar sus indices numéricos, es decir, con for(;;) simplemente.

Saludos,
  #12 (permalink)  
Antiguo 18/12/2013, 05:23
Avatar de CHuLoSoY  
Fecha de Ingreso: febrero-2002
Ubicación: Ribeira (Galicia)
Mensajes: 1.900
Antigüedad: 22 años, 2 meses
Puntos: 29
Respuesta: Añadir métodos a una clase no enumerables.

Cita:
Iniciado por Pantaláimon Ver Mensaje
[...] estoy bastante seguro que, excepto los tipos undefined, null, boolean, number y string, lo demás son objetos.
String también es un objeto! xD

Código Javascript:
Ver original
  1. var string = new String();
  2. string = "abcdefg";
  3. string.replace("d", "h");
__________________
ESQUIO Dominios y Hosting
Las mejores características con los mejores precios.

Etiquetas: clase, js
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 21:47.