1 function range ( from , to ) { 2 var r = Object . create ( range . methods ) ; 3 r . from = from ; 4 r . to = to ; 5 return r ; 6 } 7 range . methods = { 8 includes : function ( x ) { return this . from <= x && x <= this . to ; } , 9 foreach : function ( f ) { for ( var x = Math . c e i l ( this . from ) ; x <= this . to ; x++) { f ( x ) ; } } 10 } ;
Para crear un objeto y utilizar sus funciones se realizan las siguientes llamadas: 1 var r = range (1 ,3) ; 2 r . includes (2) ; 3 var callback = function ( x ) { console . log ( " Valor de x : " + x ) } ; 4 r . foreach ( callback ) ;
Para crear un objeto y utilizar sus funciones se realizan las siguientes llamadas: 1 var r = range (1 ,3) ; 2 r . includes (2) ; 3 var callback = function ( x ) { console . log ( " Valor de x : " + x ) } ; 4 r . foreach ( callback ) ; En la forma anterior se usa una función generadora, no hay constructor de clase.
Para crear un objeto y utilizar sus funciones se realizan las siguientes llamadas: 1 var r = range (1 ,3) ; 2 r . includes (2) ; 3 var callback = function ( x ) { console . log ( " Valor de x : " + x ) } ; 4 r . foreach ( callback ) ; En la forma anterior se usa una función generadora, no hay constructor de clase. Es posible replantear el metodo anterior usando un constructor
1 function Range ( from , to ) { 2 this . from = from ; 3 this . to = to ; 4 } 5 Range . prototype = { 6 includes : function ( x ) { return this . from <= x && x <= this . to ; } , 7 foreach : function ( f ) { for ( var x = Math . c e i l ( this . from ) ; x <= this . to ; x++) { f ( x ) ; } } 8 } ; 9 var r2 = new Range (1 ,3) ; 10 r2 . includes (2) ; 11 var callback = function ( x ) { console . log ( " Valor de x : " + x ) } ; 12 r2 . foreach ( callback ) ;
En ambos casos se usa la variable prototype, pero si se fijan en el segundo caso no se crea objeto pues ya eso lo hace el new El new llama a la función como constructor, crea un nuevo objeto y coloca el prototype automáticamente en el objeto creado.
En ambos casos se usa la variable prototype, pero si se fijan en el segundo caso no se crea objeto pues ya eso lo hace el new El new llama a la función como constructor, crea un nuevo objeto y coloca el prototype automáticamente en el objeto creado. Es importante notar que aunque las declaraciones e inicializaciones son distintas, el resto del uso permanece igual.
Se puede utilizar la función instanceof para determinar si un objeto pertenece a una clase. En este caso verificamos si el prototype del constructor determina el objeto creado: 1 r2 instanceof Range ;
Se puede utilizar la función instanceof para determinar si un objeto pertenece a una clase. En este caso verificamos si el prototype del constructor determina el objeto creado: 1 r2 instanceof Range ; Esto NO funciona con la primera forma de crear clases 1 r instanceof range ;
estáticas Son propiedades propias de la Clase, no de los objetos En otros lenguajes son también conocidos como static En otros lenguajes hay variables o funciones de clase, para el caso de JAVASCRIPT, nos referimos solamente a propiedades, solo que pueden ser un valor o una función (en este último caso, tal como ya vimos, se llaman métodos).
estáticas Son propiedades propias de la Clase, no de los objetos En otros lenguajes son también conocidos como static En otros lenguajes hay variables o funciones de clase, para el caso de JAVASCRIPT, nos referimos solamente a propiedades, solo que pueden ser un valor o una función (en este último caso, tal como ya vimos, se llaman métodos). Para el caso de Javascript basta con definir las propiedades al constructor una vez se hayan declarado las funciones. Ejemplo:
estáticas Algunos usos: 1 var i1 = new Complex (8 , 0) ; 2 var i2 = new Complex (9 , 0) ; 3 i1 . add ( i2 ) ; 4 var i3 = Complex . parse ( " {1 ,3} " ) ; 5 i3 = i3 . add ( Complex . I ) ; 6 var i4 = i3 . add ( Complex . parse ( " {4 ,2} " ) ) ; Las propiedades de la clase se acceden con el nombre del constructor. En JAVASCRIPT se debe usar this para acceder a las variables del objeto.
No es posible lograr el comportamiento exacto de un tipo por parte de una clase como otros lenguajes. Se pueden usar varios métodos (ninguna completamente satisfactorio) para determinar el nombre de la clase: instanceof, usando la propiedad constructor, usando la varible no estándar name
No es posible lograr el comportamiento exacto de un tipo por parte de una clase como otros lenguajes. Se pueden usar varios métodos (ninguna completamente satisfactorio) para determinar el nombre de la clase: instanceof, usando la propiedad constructor, usando la varible no estándar name Todos estos intentos tienen problemas de alguna forma, así que usualmente se usa ducktyping
No es posible lograr el comportamiento exacto de un tipo por parte de una clase como otros lenguajes. Se pueden usar varios métodos (ninguna completamente satisfactorio) para determinar el nombre de la clase: instanceof, usando la propiedad constructor, usando la varible no estándar name Todos estos intentos tienen problemas de alguna forma, así que usualmente se usa ducktyping ’Cuando veo un ave que camina como pato, nada como pato y hace kuack como un pato, entonces yo le llamo pato’.
No es posible lograr el comportamiento exacto de un tipo por parte de una clase como otros lenguajes. Se pueden usar varios métodos (ninguna completamente satisfactorio) para determinar el nombre de la clase: instanceof, usando la propiedad constructor, usando la varible no estándar name Todos estos intentos tienen problemas de alguna forma, así que usualmente se usa ducktyping ’Cuando veo un ave que camina como pato, nada como pato y hace kuack como un pato, entonces yo le llamo pato’. Básicamente se revisa si el objeto contiene algunas funciones y si las tiene, decimos que pertenece a cierta clase.
Como ya hablamos antes, toString se invoca cada vez que se necesita un string en una expresión 1 Range . prototype . toString = function ( ) { return this . from + " . . . " + this . to ; } ; 2 var r = new Range(50 , 100) ; 3 console . log ( " " + r ) ;
Como ya hablamos antes, toString se invoca cada vez que se necesita un string en una expresión 1 Range . prototype . toString = function ( ) { return this . from + " . . . " + this . to ; } ; 2 var r = new Range(50 , 100) ; 3 console . log ( " " + r ) ; Se debe recordar que el operador + si encuentra un string lo lleva todo a string.
Como ya hablamos antes, toString se invoca cada vez que se necesita un string en una expresión 1 Range . prototype . toString = function ( ) { return this . from + " . . . " + this . to ; } ; 2 var r = new Range(50 , 100) ; 3 console . log ( " " + r ) ; Se debe recordar que el operador + si encuentra un string lo lleva todo a string. Adicionalmente se puede definir toLocaleString, valueOf, toJSON
valueOf devuelve un valor primitivo, se utiliza en aquellas operaciones en las que sea necesario un tipo básico, como por ejemplo, en operaciones aritméticas
valueOf devuelve un valor primitivo, se utiliza en aquellas operaciones en las que sea necesario un tipo básico, como por ejemplo, en operaciones aritméticas Aunque algunas clases puede que no tenga sentido definirlos, hay otras en las que si.
de comparación En vez de utilizar los valores por defecto se definen las funciones que se necesiten Las funciones usualmente definidas son: equals, compareTo, esta última devuelve un número menor a cero, 0 o mayor a cero si el objeto comparado es menor, igual o mayor a la referencia. 1 Range . prototype . compareTo = function ( v ) { return ( this . to - this . from ) - ( v . to - v . from ) ; } ; 2 var a = [ r1 , r2 ] ; 3 a . sort ( function ( a , b) { return a . compareTo (b) ; } ) ;
Una subclase contiene todas las funciones y propiedades de la clase que está extendiendo y puede sobreescribir a las clases que desee reimplementar 1 function NonNullRange ( ) { Range . apply ( this , arguments ) ; } 2 NonNullRange . prototype = Range . prototype ; 3 var s = new NonNullRange (3 ,5) ; 4 s ;