Master en Artes Digitales (IUA-UPF)
Módulo de Programación

JavaScript y HTML

Noción de Objeto | Noción de Programación Orientada a Objeto | El JavaScript sus objetos, sus propiedades y sus métodos | Ejercicios

Noción de Objeto: propiedades, métodos, encapsulación

En un lenguaje orientado a objeto, un objeto, informalmente, se puede definir como una estructura de datos la cual agrupa unas variables (o propiedades) y unas funciones (o métodos):

Diagrama de flujo de las llamadas a funciones

Un objeto debe representar una idea o concepto completo y proveer las propìedades necesarias para poder contener los datos asociados a ese concepto, y los métodos necesarios para poder manipular esas propiedades.

Por ejemplo, un objeto podria ser una ficha de un paciente de un dentista:

PACIENTE
Nombre: Jaume Fitor
Edad: 34
Dirección: c. Major de la Vila
Tel: 938754352
DNI: 47890621

Cada campo de la ficha sería una propiedad del objeto PACIENTE. En este caso podrían definirse métodos para insertar el nombre, o para escribir toda la ficha ya debidamente formateada.

Algunas propiedades (o variables) del objeto pueden definirse como no accesibles desde el exterior de forma que sólo se pueda trabajar con ellas a través de los métodos (o funciones) que el objeto provée al programador. Estas propiedades que no son accesibles desde el exterior se dice que son privadas, en cambio las que si son accesibles desde fuera se les llama públicas. Esto es útil por las siguientes razones:

A esta característica de poder ocultar la estructura interna del objeto se le llama encapsulación.

NOTA: Debido a que el JavaScript no es un lenguaje 100% orientado a objeto (O-O), no entraremos en detalle en los conceptos básicos de los lenguajes O-O como son: la encapsulación, los constructores, destructores, la privacidad, la herencia, etc.

 

Noción de Programación Orientada a Objeto

La idea detrás de la Programación Orientada a Objeto es, precisamente, la utilización de objetos para tener una gestión de los datos y las funciones más integrada.

Para poder definir objetos se necesita una especie de molde que nos especifique las características de esos objetos.

Por ejemplo, si queremos definir tres fichas de pacientes del dentista: paciente1, paciente2 y paciente3, necesitamos que las tres tengan exáctamente las mismas características. Con esta misión, los lenguages OO (Orientados a Objeto) tienen un mecanismo de definición de moldes llamados clases. En el ejemplo se debería definir una clase de objetos tipo paciente para poder generar a partir de ella todas las copias exactas de las tres fichas de paciente que necesitamos.

 

El JavaScript sus objetos, sus propiedades y sus métodos

En el caso del JavaScript una clase se define a partir de una función constructora de ese tipo de objetos.

Por ejemplo en el caso de la ficha de un paciente, se podría definir una clase del estilo:

function oPaciente(nombre,edad,direccion,tel,dni) {
   this.nombre=nombre
   this.edad=edad
   this.direccion=direccion
   this.tel=tel
   this.dni=dni
}

paciente1 = new oPaciente("Jaume Fitor",34,"c. Major de la Vila","938754352","47890621")
paciente2 = new oPaciente("Laura Mas",18,"Pl. Catalunya","972456789","32645722")
paciente3 = new oPaciente("Joan Pages",34,"Pg. del Carme","93543300","78000906")

Analicemos esta definición. La función oPaciente (cuyo nombre pretende dar a entender que crea objetos de tipo Paciente) es el molde del que hablamos más arriba. Esta función se encarga de definir las propiedades del nuevo objeto. Este nuevo objeto se referencía desde dentro de la función con el nombre this. Así pues, se le asocia al nuevo objeto (a this) la propiedad de nombre, a continuación la de edad, etc.

Para que en el momento de crear el nuevo objeto ya se le pueda asignar un valor a cada propiedad, estos valores iniciales se le pasan por parámetro.

Finalmente, para crear cada objeto nuevo, se utiliza la fórmula new junto con la función de construcción del nuevo objeto (y los valores iniciales): new oPaciente(...). El nuevo objeto generado se asigna a una variable para después poder referenciarlo: paciente1 = new oPaciente(...). Así, si después queremos hacer referencia a la propiedad nombre de paciente1 para asignarle un nuevo valor "Jordi Tenes", lo haremos de la siguiente forma:

paciente1.nombre = "Jordi Tenes"

donde la propiedad se une al nombre del objeto mediante un punto para definir totalmente aquello que estamos referenciando.

 

Ejemplos de objetos a programar en el entorno EP-NAR-6

Ejemplo 1 :

Definir una ficha de una fruta para una base de datos de una frutería. Crear una ficha y leer de teclado los valores de las propiedades para asignarlas. Las propiedades deseadas són: nombre, origen, precio por kilo, caducidad en días, proveedor. Una vez rellenado, escribir el contenido de la ficha por pantalla.

Ejemplo 2 :

Definir una base de datos de frutas a partir de un array de 10 fichas de frutas como la definida en el ejemplo anterior. Leer de teclado los valores de las propiedades de cada fruta y finalmente escribirlo todo por pantalla.


En esta sección no pretendemos pasar por todos los objetos y propiedades de JavaScript, para esto existen libros y web sites que desciben de forma completa todo el lenguaje. Algunas buenas referencias para consultar todos los objetos, sentencias, eventos, etc., del JavaScript, son:

Links:

Libros:

No obstante, dos tipos de objetos muy utilizados en JavaScript son los Arrays y los Strings, que si veremos a continuación.

Arrays

Los Arrays, como hemos visto de forma informal ya anteriormente, són un tipo de objeto que representa una tabla de valores los cuales pueden ser accedidos por un índice.

También, como ya sabemos, un nuevo Array se consigue mediante la función constructora Array(), de forma que si queremos tener nuestro nuevo array miArray de 10 elementos, lo definiremos:

miArray = new Array(10)

Otra forma de inicializar un Array es:

miArray = new Array("Pere", "Roser", "Albert", "Lluïsa")

Los Arrays tienen algunas propiedades y métodos interesantes (no los veremos todos):

Propiedades:

length: la propiedad longitud, de un Array nos dice cuantos elementos hay definidos en un Array. Por ejemplo, en el array definido arriba, si miramos su longitud con la sentencia:

write(miArray.length)

obtendremos 10 por pantalla, que es la cantidad de elementos de nuestro array.

Esto puede ser muy útil para pasar por todas las posiciones de un array sin necesidad de saber su longitud a priori. Por ejemplo:

for(i=0; i < miArray.length; i++){
  miArray[i] = readstr()
}

Con lo que conseguimos leer un valor para cada posición del array sin definir la longitud del array en el bucle for.

Métodos:

reverse(): Este método, como su nombre indica, invierte el orden de los valores guardados en las posiciones del Array. Por ejemplo, si tenemos un Array definido como:

miArray = new Array("Pere", "Roser", "Albert", "Lluïsa")

entonces, si aplicamos el método reverse() haciendo:

miArray.reverse()

y escribimos las posiciones por pantalla:

for(i=0; i < miArray.length; i++){
  write(miArray[i]+"\n")
}

obtendremos:

Lluïsa
Albert
Roser
Pere

Es decir, se han invertido los nombres en su orden dentro del array.

sort(): Este método ordena los valores guardados en las posiciones del Array. Si son strings, se ordenan alfabéticamente. Si son números, también se ordenan alfabéticamente como si fuesen strings. Por ejemplo, si tenemos un Array definido como:

miArray = new Array("Pere", "Roser", "Albert", "Lluïsa")

entonces, si aplicamos el método sort() haciendo:

miArray.sort()

y escribimos las posiciones por pantalla:

for(i=0; i < miArray.length; i++){
  write(miArray[i]+"\n")
}

obtendremos:

Albert
Lluïsa
Pere
Roser

Es decir, se han ordenado los nombres dentro del array.

Strings

Los Strings, aunque hasta ahora los hemos visto siempre como un tipo de datos simple y los hemos definido símplemente asignándoles un valor:

miString = "esto es un string"

También pueden ser definidos por una función (o método) constructor:

miString = new String("esto es un string")
miString = "ahora el string contiene esto"
miString = miString + " y le añadimos esto"

Aquí vemos como podemos pasar el valor inicial a la función constructora. Evidentemente después podemos cambiar el valor directamente; es decir, ya no debemos utilizar la fucnión constructora ya que, de hecho, estaríamos creando un nuevo objeto y perdiendo el anterior.

Los Strings tienen algunas propiedades y métodos interesantes (no los veremos todos):

Propiedades:

length: la propiedad longitud, de un String, de forma similar a los Arrays, nos dice la cantidad de carácteres de ese string. Por ejemplo, en el string definido arriba, si miramos su longitud con la sentencia:

write(miString.length)

obtendremos 48 por pantalla, que es la cantidad de carácteres de nuestro string.

Esto puede ser muy útil para saber si se nos ha dado un string demasiado largo. Por ejemplo:

miString = readstr()
if(miString.length > 50){
  write("Texto demasiado largo.")
}

Métodos:

toLowerCase(): Convierte todos los carácteres de un string a minúscules. Por ejemplo, si tenemos el string:

miString = new String("Narcis Pares")

y lo scribimos aplicando este método:

write( miString.toLowerCase() )

obtendremos por pantalla: narcis pares

charAt(indice): Este método utiliza un número como índice para devolver el carácter cuya posición dentro del string es precisamente la indicada por el índice. Por ejemplo:

miString = new String("Hello World!")
write( miString.charAt(0) ) // --> H
write( miString.charAt(6) ) // --> W

substr(inicio[, long]): Este método da la fracción del string que empieza en la posición dada por el inicio y cuya longitud es long. La longitud es opcional, y si no se da, se supone que se desea obtener el string desde la posición inicio hasta el fin del string original. Por ejemplo:

miString = new String("Hello World!")
write( miString.substr(0) ) // --> Hello World!
write( miString.substr(6) ) // --> World!
write( miString.substr(2,3) ) // --> llo
write( miString.substr(6,5) ) // --> World
write( miString.substr(4,3) ) // --> o W

indexOf(cadenaBuscada[, dePosicion]): Este método da la posición inicial en que se encuentra una cierta cadena de carácteres, cadenaBuscada, dentro de un string. También se puede dar una posición inicial, dePosicion, a partir de la cual se deba buscar la cadena. Por ejemplo:

miString = new String("Hello World!")
write( miString.indexOf("Hello") ) // --> 0
write( miString.indexOf("World") ) // --> 6
write( miString.indexOf("o") ) // --> 4
write( miString.indexOf("o",5) ) // --> 7
write( miString.indexOf("l") ) // --> 2
write( miString.indexOf("l",3) ) // --> 3
write( miString.indexOf("l",4) ) // --> 9
write( miString.indexOf("X") ) // --> -1 (significa no encontrado)

Para más información sobre propiedades y métodos mirar en: Arrays y Strings.


Ejemplos de funciones a programar en el entorno EP-NAR-6

Ejemplo 1 :

  • Definir un array de 10 posiciones.
  • Definir una ficha de persona con los campos: nombre, edad, telefono. (Nota: por nombre se entiende nombre de pila y primer apellido).
  • Crer una ficha para cada posición del array.
  • Leer de teclado los datos de las 10 personas.
  • Escribir por pantalla todas las fichas de las personas cuyo nombre empiece por "A".
  • Escribir por pantalla todas las fichas de las personas cuyo apellido sea "Soler".
  • Escribir por pantalla todas las fichas de las personas cuya edad sea mayor de 20.
  • Escribir por pantalla todas las fichas de las personas cuyo teléfono sea de Barcelona (prefijo de área 93).

Soluciones:

Ejemplo 1 :

function main(){
   personas = new Array(10)  // Creamos el Array
   for(i=0; i<10; i++){  // Creamos las Fichas
      personas[i] = new fichaPersonas()
   }
   for(i=0; i<10; i++){  // Rellenamos los datos de cada Ficha
      personas[i].nombre = readstr()
      personas[i].edad = readval()
      personas[i].tel = readstr()
   }
   // Primera salida de resultados
   write("Fichas de personas con inicial A:\n")
   for(i=0; i<10; i++){
      if(personas[i].nombre.charAt(0) == "A"){  // Que el carácter en la posición cero sea A
         escribirFicha(personas[i])
      }
   }
   // Segunda salida de resultados
   write("\nFichas de personas con apellido Soler:\n")
   for(i=0; i<10; i++){
      if(personas[i].nombre.indexOf("Soler") != -1){  // Que se encuentre la cadena
         escribirFicha(personas[i])
      }
   }
   // Tercera salida de resultados
   write("\nFichas de personas mayores de 20 años:\n")
   for(i=0; i<10; i++){
      if(personas[i].edad > 20){  // Que la edad sea mayor que 20
         escribirFicha(personas[i])
      }
   }
   // Cuarta salida de resultados
   write("\nFichas de personas con teléfono de Barcelona:\n")
   for(i=0; i<10; i++){
      if(personas[i].tel.charAt(0) == "9" && personas[i].tel.charAt(1) == "3"){
        // Que el primer carácter sea 9 y el segundo 3
         escribirFicha(personas[i])
      }
   }
}

function fichaPersonas(){
   this.nombre = ""
   this.edad = 0
   this.tel = ""
}

function escribirFicha(f){
   write("  Nombre: " + f.nombre + "\n")
   write("    Edad: " + f.edad + "\n")
   write("Teléfono: " + f.tel + "\n")
}

Ejercicios: Escribir programas que hagan lo siguiente
  1. Se da un array de objetos con las siguientes propiedades: nombre, edad, siguiente. Este array está ordenado por orden alfabético de las propiedades nombre de cada objeto. Se desea generar una lista que ordene los objetos por edad mediante la propiedad siguiente. Estas propiedades deberán contener el índice del array del siguiente objeto en orden creciente de edad. Esto formará un enhebrado de índices como se muestra:



    El objeto que ya no tenga siguiente deberá tener un -1 en su propiedad siguiente, significando que ya no hay siguiente.


< Sesión Anterior | Índice | Siguiente Sesión >