DE .NET, SQLSERVER Y MÁS, APRENDE CONMIGO!✔

Desarrollo de todo tipo de aplicaciones y Administración de Base de datos con Tecnología Microsoft


UNETE

Objetos en JavaScript

0

 



En Javascript, como en cualquier lenguaje, un objeto no es más que un conjunto de atributos y funciones (sus métodos). A cada objeto podemos añadirle nuevas propiedades y funciones de diferentes maneras que iremos viendo. Sin embargo la herencia, tal y como la conocemos de otros lenguajes como Java, no existe, pues no existen las clases: para crear un nuevo objeto que tenga los mismos atributos que otro, estos deben ser copiados. A esta forma de trabajar se llama herencia basada en prototipos. Esto significa que no hay clases o interfaces como en Java o C++: solo hay objetos que copian (heredan) sus propiedades de otros objetos, llamados prototipos. Así que olvidémonos de la clásica definición de “objeto como instancia de una clase”, porque aquí no hay clases (y por esta razón, cuando hable de clases en Javascript, lo haré entre comillas así: “clases”). Pero vayamos por partes:

Creando objetos

Pare crear un nuevo objeto podemos hacerlo de cualquiera de estas dos formas:

1

var obj1 = new Object()

2

var obj2 = {}

La segunda forma se llama “objeto literal”. Es la que usamos para crear lo que en otros lenguajes se llaman diccionarios, mapas o hashtables y que sigue, afortunadamente, la misma sintaxis que JSON.

Para añadir una nueva propiedad, solo tenemos que asignársela:

1

var obj1 = new Object()

2

obj1.nombre = "mundo"

 

3

 

4

alert("hola "+obj1.nombre) // "hola mundo"

Para eliminar una propiedad, usaremos el operador delete:

1

var obj1 = new Object()

2

alert(obj1.nombre)   // undefined

 

3

 

4

obj1.nombre = "mundo"

 

5

alert(obj1.nombre)   // "mundo"

6

 

 

7

delete obj1.nombre

8

 

 

9

alert(obj1.nombre)   // undefined otra vez

Y para añadir un método, solo hay que añadirle una función como expresión, teniendo siempre en cuenta que para que un método pueda acceder a las propiedades del objeto donde reside, tenemos que usar el prefijo this.

1

var obj1 = new Object()

2

obj1.nombre = "mundo"

 

3

obj1.saluda = function() { alert("hola "+this.nombre) }

4

obj1.saluda()

Aquí vemos como es necesario usar this.nombre dentro de la función saluda() para acceder al atributo nombre del objeto.

Otra forma de construir objetos es como literales:

1

var obj1 = {nombre:"mundo",

2

            saluda: function() { alert("hola "+this.nombre) }

 

3

}

4

obj1.saluda()

En Javascript podemos acceder a las propiedades de un objeto usando la notación objeto.propiedad; o de manera indexada como un array, con objeto[prop]. En este segundo caso, prop es una variable de tipo String cuyo contenido es el nombre de la propiedad a acceder. Ejemplo:

01

var obj1 = new Object()

02

obj1.nombre = "mundo"

 

03

obj1.saluda = function() { alert("hola "+this.nombre) }

04

 

 

05

alert("hola "+obj1.nombre)       // Acceso normal

06

alert("hola "+obj1[ "nombre" ])  // Acceso indexado con un literal

 

07

var prop = "nombre"

08

alert("hola "+obj1[ prop ])      // Acceso indexado con una variable

 

09

 

10

obj1.saluda()         // Invocación normal

 

11

obj1[ "saluda" ]()    // Acceso indexado con un literal

12

var func = "saluda"

 

13

obj1[ func ]()        // Acceso indexado con una variable

Podemos usar esta segunda forma de acceder a las propiedades de un objeto para listarlas todas, sin importar cuantas tenga ni su nombre:

01

var obj1 = new Object()

02

obj1.nombre = "mundo"

 

03

obj1.fecha = new Date()

04

obj1.luckyNumbers = [4,8,15,16,23,42]

 

05

obj1.saluda = function() { alert("holas "+this.nombre) }

06

 

 

07

var name

08

for (name in obj1) {

 

09

    alert(name+" : "+ obj1[name])

10

}

Prototipos

Pero claro, con esto solo definimos un único objeto, con sus atributos y métodos. Pero, ¿qué pasa si queremos crear una “clase” de la que poder instanciar objetos? Como hemos dicho antes, en Javascript no hay clases, sino prototipos: objetos de los que se copian otros objetos. Así que lo que haremos es crear un objeto del que poder copiar sus propiedades. Para esto Javascript tiene un gran truco: hace que cualquier función pueda ser instanciada como un nuevo objeto usando la palabra clave “new”.

1

// Una simple función

2

function Saludator() {

 

3

    alert("Saludos factory!!")

4

}

 

5

// Y una simple llamada

6

Saludator()

A simple vista no es más que una función, ¡y es verdad que lo es! pues podemos llamar a Saludator() como una función de toda la vida. Pero eso no quita que sea también una factoría y que con ella podamos crear nuevos objetos:

1

// Una función... pero también un prototipo!

2

function Saludator() {

 

3

    alert("Saludos factory!!")

4

}

 

5

// Un nuevo objeto a partir de su "clase" prototipo

6

var saludo = new Saludator()

Pero claro, con este ejemplo tan sumamente sencillo no se aprecia que hemos creado un nuevo objeto. Así que vamos a añadirle un par de propiedades y métodos (recordemos que solo tenemos que declararlas con el prefijo this).

01

function Saludator(nom) {

02

    alert("Saludos factory!!")

 

03

    this.nombre = nom+"s"

04

    this.saluda = function() {

 

05

        alert("hola "+this.nombre)

06

    }

 

07

}

08

var obj1 = new Saludator("mundo")

 

09

var obj2 = new Saludator("gente")

10

obj1.saluda() // "hola mundos"

 

11

obj2.saluda() // "hola gentes"

En este ejemplo ya vemos cosas nuevas:
– Que la función Saludator() es el constructor del objeto, y podemos pasarle parámetros que posteriormente podemos usar en los atributos del objeto.
– Que dentro de la función saluda sigue siendo necesario usar this.nombre para acceder al atributo nombre.

Por cierto, podemos crear nuestros prototipos usando funciones como expresiones, y no como declaraciones. El siguiente código es completamente equivalente al anterior:

1

var Saludator = function(nom) {

2

    alert("Saludos factory!!")

 

3

    this.nombre = nom+"s"

4

    this.saluda = function() {

 

5

        alert("hola "+this.nombre)

6

    }

 

7

}

Es necesario señalar que las funciones que servirán para crear objetos se suelen nombrar con la primera letra en mayúscula. Esto es así para evitar que se confundan con funciones normales o variables.

Métodos privados

Podemos crear métodos “privados” (es decir, métodos que son solo accesibles desde dentro del objeto, nunca desde fuera), creando funciones como declaración, no como expresión. La principal desventaja es que estos tipos de métodos no tienen ligado el “this” con el objeto actual, por lo que no pueden acceder a sus datos internos. Para evitar esto, tenemos que enviar como parámetros los datos del objeto que necesiten. Además, no podemos usar el prefijo this para llamar a estos métodos:

01

var Saludator = function(nom) {

02

    this.nombre = nom

 

03

    this.saluda = function() {

04

        alert("hola "+plural(this.nombre))

 

05

    }

06

    function plural(n) {

 

07

        return n + "s"

08

    }

 

09

}

10

var obj1 = new Saludator("mundo")

 

11

obj1.saluda()

12

// obj1.plural()  // fallaría porque plural() es privado

La llamada al método plural() no es accesible desde fuera, por lo que fallaría (por eso está comentada). Observemos también como la llamada a plural() no se hace con this.plural(). Y que para acceder al atributo nombre hemos tenido que pasárselo como parámetro.

Los métodos privados no son dinámicos, en el sentido que no se pueden definir condicionalmente en tiempo de ejecución. Así que el siguiente código no fallará, pero no funcionará correctamente (de hecho, su funcionamiento dependerá del navegador):

01

// Atención, codigo erróneo a modo de ejemplo, NO USAR!

02

var Saludator = function(nom, enPlural) {

 

03

    this.nombre = nom

04

    this.saluda = function() {

 

05

        alert("hola "+quien(this.nombre))

06

    }

 

07

    // NO HACER ESTO NUNCA!!!!!!!

08

    if (enPlural) {

 

09

        function quien(n) { // Arggg!!

10

            return n + "s"

 

11

        }

12

    } else {

 

13

        function quien(n) { // Ouch!!

14

            return n

 

15

        }

16

    }

 

17

}

18

var obj1 = new Saludator("mundo", false)

 

19

var obj2 = new Saludator("mundo", true)

20

obj1.saluda() // "hola mundo"

 

21

obj2.saluda() // "hola mundo", pero es incorrecto!

En su lugar, definiendo los métodos con funciones como expresiones, si que funciona correctamente, ya que la creación del método no es más que una asignación que se produce dentro de una bifurcación condicional:

01

var Saludator = function(nom, enPlural) {

02

    this.nombre = nom

 

03

    this.saluda = function() {

04

        alert("hola "+this.quien())

 

05

    }

06

    if (enPlural) {

 

07

        this.quien = function() {

08

            return this.nombre + "s" // En plural

 

09

        }

10

    } else {

 

11

        this.quien = function() {

12

            return this.nombre  // En singular!!

 

13

        }

14

    }

 

15

}

16

var obj1 = new Saludator("mundo", false)

 

17

var obj2 = new Saludator("mundo", true)

18

obj1.saluda() // "hola mundo"

 

19

obj2.saluda() // "hola mundos", correto!

Métodos y atributos estáticos

Para crear un método estático tan solo lo tenemos que asignar a nuestra “clase” una propiedad más (recordemos que no es más que una función):

01

var Saludator = function(nom, enPlural) {

02

    this.nombre = nom

 

03

    this.enPlural = enPlural

04

    this.saluda = function() {

 

05

        alert("hola "+this.nombre)

06

    }

 

07

}

08

// Añadimos un método estático como atributo de la "clase" Saludator

 

09

Saludator.cloneSaludo = function(saludo) {

10

    return new Saludator("clonado "+saludo.nombre, saludo.enPlural)

 

11

}

12

 

 

13

var obj1 = new Saludator("mundo", false)

14

var obj2 = Saludator.cloneSaludo(obj1)

 

15

obj2.saluda() // "hola mundo"

16

obj2.saluda() // "hola clonado mundo"

Por supuesto, podemos añadir también atributos estáticos. Todas las propiedades estáticas (atributos o métodos) son siempre públicas y necesitan SIEMPRE el prefijo con el nombre de la “clase” delante siempre para acceder a ellas.

En este ejemplo, se usa la propiedad estática count de la clase Saludator para llevar la cuenta del número de objetos que se han creado:

01

var Saludator = function(nom) {

02

    // Se inicializa count a 0, si no existe

 

03

    Saludator.count = Saludator.count?Saludator.count:0

04

    Saludator.count ++

 

05

    this.nombre = nom

06

    this.saluda = function() {

 

07

        alert("hola "+this.nombre)

08

    }

 

09

 

10

}

 

11

Saludator.cloneSaludo = function(saludo) {

12

    return new Saludator("clonado "+saludo.nombre)

 

13

}

14

 

 

15

var obj1 = new Saludator("mundo", false)

16

var obj2 = Saludator.cloneSaludo(obj1)

 

17

obj2.saluda()

18

 

 

19

alert(Saludator.count) // "2", pues se han creado 2 objetos



DEMOSTRACIÓN

En el espacio de nombre del proyecto creado en los artículos anteriores damos click derecho y seleccionamos Add à New Items


En la siguiente ventana seleccionamos la Opción “Pagina HTML” y colocamos como nombre del archivo “Objetos.html”, para luego presionar el botón Add.


Escribimos el siguiente Script:


Ejecutamos una vez más





Tal vez te interesen estas entradas

No hay comentarios