Esta traducción está incompleta. Por favor, ayuda a traducir este artículo del inglés.

Con lo básico fuera del camino, nos enfocaremos en Javascript Orientado a Objetos (JSOO) — este artículo presenta una vista básica de la teoría de la Programación Orientada a Objetos (POO), luego explora cómo Javascript emula classes de objeto via funciones constructoras, y cómo crea instancias de objetos.

Prerequisitos: Conocimientos básicos de computación, entendimiento básico de HTML y CSS, familiaridad con las bases de Javascript (ver Primeros pasos con JavaScript y JavaScript construyendo bloques) y las bases de JSOO (ver Introducción a objetos).
Objetivo:

Entender la teoría base de la programación orientada a objetos, como se relaciona esta con JavaScript ("todo es un objeto"), y como crear constructores e instacias de objetos.

Programacion Orientada a Objetos— lo básico

Para empezar, daremos una visión simple y de alto nivel acerca de lo que es la Programación Orientada a Objetos (POO). Decimos simple, porque la POO puede volverse complicada rápidamente, y darle un tratamiento completo ahora, probablemente podría confundir más que ayudar. La idea básica de la POO es que usamos objetos para modelar cosas del mundo real que queremos representar en nuestros programas, y/o proveemos una simple manera para acceder a la funcionalidad que, de otra manera, sería difícil o imposible de usar.

Los objetos pueden contener información y código relacionados, los cuales representan información acerca de lo que estás tratando de modelar, y la funcionalidad o comportamiento que deseas que tenga.  Los datos de un Objeto (y usualmente también las funciones) pueden ser almacenados ordenadamente (la palabra oficial es encapsulada) dentro del paquete de un objeto (al que se puede asignar un nombre específico, llamado a veces espacio de nombres), haciéndolo fácil de estructurar y acceder; los objetos también se usan comúnmente como almacenes de datos que pueden ser enviados fácilmente a través de la red.

Definiendo una plantilla de objeto

Vamos a considerar un simple programa que muestra información sobre estudiantes y profesores en una escuela. Aquí daremos un vistazo a la POO (Programación Orientada a Objetos) en general, no en el contexto de algún lenguaje de programación específico.

Para empezar, podríamos volver a ver al objeto Persona de nuestro artículo de primeros objetos, que define los datos generales y funcionalidades de una persona. Hay muchas cosas que podrías saber acerca de una persona (su dirección, altura, tamaño de calzado, perfil de ADN, número de pasaporte, rasgos significantes de su personalidad...), pero en este caso, solo estamos interesados en mostrar su nombre, edad, género e intereses, y además una pequeña introducción sobre este individuo basada en los datos anteriores. También queremos que sea capaz de saludar. 

Esto es conocido como abstracción —  crear un modelo simple de algo complejo que represente sus aspectos más importantes y que sea fácil de manipular para los propósitos de nuestro programa.

En algunos lenguajes de POO, esta definición de tipo de objeto se la llama class (JavaScript utiliza diferentes mecanismos y terminologías, como verás a continuación) — esto no es en realidad un objeto, en vez de esto es un modelo que define las características que un objeto debería tener.

Creando objetos

Partiendo de nuestra clase, podemos crear instancias de objetos — objetos que contienen los datos y funcionalidades definidas en la clase original. Teniendo a nuestra clase Persona, ahora podemos crear gente con características más específicas: 

Cuando una instancia de objeto es creada a partir de una clase, se ejecuta la función constructora (constructor en inglés) de la clase para crearla. El proceso de crear una instancia de objeto desde una clase se llama instanciación.

Clases especializadas

En este caso nosotros nosotros no queremos personas genericas, queremos docentes y estudiantes, que son los dos tipos más específicos de personas. En POO, podemos crear nuevas clases basadas en otras clases, estas nuevas clases secundarias pueden hacerse para  heredar los datos y código de su clase primaria, de modo que puede reutilizar la funcionalidad común a todos los tipos de objetos en lugar de tener que duplicarla. Cuando la funcionalidad difiere entre clases, puede definir funciones especializadas directamente en ellas según sea necesario.

Esto es realmente útil, los profesores y los estudiantes comparten muchas características comunes como el nombre, el género y la edad, por lo que es conveniente tener que definir esas características solo una vez. También puede definir la misma característica por separado en diferentes clases, ya que cada definición de esa característica estará en un espacio de nombres diferente. Por ejemplo, el saludo de un estudiante puede tener la forma "Yo, soy [Name]" (por ejemplo, Yo, soy Sam), mientras que un profesor puede usar algo más formal, como "Hola, mi nombre es [Prefix] [lastName], y enseño [Asunto] ". (Por ejemplo, Hola, mi nombre es Sr. Griffiths, y yo enseño Química).

Nota:  la palabra elegante para la capacidad de múltiples tipos de objetos de implementar la misma funcionalidad es polimorfismo. Por si acaso te preguntabas.

You can now create object instances from your child classes. For example:

In the rest of the article, we'll start to look at how OOP theory can be put into practice in JavaScript.

Constructors and object instances

Some people argue that JavaScript is not a true object-oriented language — for example, its class statement is just syntactical sugar over existing prototypical inheritance and is not a class in a traditional sense. JavaScript, uses special functions called constructor functions to define objects and their features. They are useful because you'll often come across situations in which you don't know how many objects you will be creating; constructors provide the means to create as many objects as you need in an effective way, attaching data and functions to them as required.

When a new object instance is created from a constructor function, its core functionality (as defined by its prototype, which we'll explore in the article Object prototypes) is not all copied over to the new object like "classic" OO languages — instead the functionality is linked to via a reference chain called a prototype chain. So this is not true instantiation, strictly speaking — JavaScript uses a different mechanism to share functionality between objects.

Note: Not being "classic OOP" is not necessarily a bad thing; as mentioned above, OOP can get very complex very quickly, and JavaScript has some nice ways to take advantage of OO features without having to get too deep into it.

Let's explore creating classes via constructors and creating object instances from them in JavaScript. First of all, we'd like you to make a new local copy of the oojs.html file we saw in our first Objects article.

Un ejemplo simple

  1. Comencemos por ver como puedes definir una persona con una funcion normal. Agrega esta funcion dentro del elemento script:
    function createNewPerson(name) {
      var obj = {};
      obj.name = name;
      obj.greeting = function() {
        alert('Hi! I\'m ' + this.name + '.');
      };
      return obj;
    }
  2. Ahora puedes crear una nueva persona llamando esta funcion — prueba con las siguientes lineas en la consola Javascript de tu navegador:
    var salva = createNewPerson('Salva');
    salva.name;
    salva.greeting();
    This works well enough, but it is a bit long-winded; if we know we want to create an object, why do we need to explicitly create a new empty object and return it? Fortunately JavaScript provides us with a handy shortcut, in the form of constructor functions — let's make one now!
  3. Replace your previous function with the following:
    function Person(name) {
      this.name = name;
      this.greeting = function() {
        alert('Hi! I\'m ' + this.name + '.');
      };
    }

The constructor function is JavaScript's version of a class. You'll notice that it has all the features you'd expect in a function, although it doesn't return anything or explicitly create an object — it basically just defines properties and methods. You'll see the this keyword being used here as well — it is basically saying that whenever one of these object instances is created, the object's name property will be equal to the name value passed to the constructor call, and the greeting() method will use the name value passed to the constructor call too.

Note: A constructor function name usually starts with a capital letter — this convention is used to make constructor functions easier to recognize in code.

So how do we call a constructor to create some objects?

  1. Add the following lines below your previous code addition:
    var person1 = new Person('Bob');
    var person2 = new Person('Sarah');
  2. Save your code and reload it in the browser, and try entering the following lines into your JS console:
    person1.name
    person1.greeting()
    person2.name
    person2.greeting()

Cool! You'll now see that we have two new objects on the page, each of which is stored under a different namespace — when you access their properties and methods, you have to start calls with person1 or person2; they are neatly packaged away so they won't clash with other functionality. They do, however, have the same name property and greeting() method available. Note that they are using their own name value that was assigned to them when they were created; this is one reason why it is very important to use this, so they will use their own values, and not some other value.

Let's look at the constructor calls again:

var person1 = new Person('Bob');
var person2 = new Person('Sarah');

In each case, the new keyword is used to tell the browser we want to create a new object instance, followed by the function name with its required parameters contained in parentheses, and the result is stored in a variable — very similar to how a standard function is called. Each instance is created according to this definition:

function Person(name) {
  this.name = name;
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name + '.');
  };
}

After the new objects have been created, the person1 and person2 variables contain the following objects:

{
  name: 'Bob',
  greeting: function() {
    alert('Hi! I\'m ' + this.name + '.');
  }
}

{
  name: 'Sarah',
  greeting: function() {
    alert('Hi! I\'m ' + this.name + '.');
  }
}

Note that when we are calling our constructor function, we are defining greeting() every time, which isn't ideal. To avoid this, we can define functions on the prototype instead, which we will look at later.

Creating our finished constructor

The example we looked at above was only a simple example to get us started. Let's now get on and create our final Person() constructor function.

  1. Remove the code you inserted so far, and add in this replacement constructor — this is exactly the same as the simple example in principle, with just a bit more complexity:
    function Person(first, last, age, gender, interests) {
      this.name = {
        'first': first,
        'last' : last
      };
      this.age = age;
      this.gender = gender;
      this.interests = interests;
      this.bio = function() {
        alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.');
      };
      this.greeting = function() {
        alert('Hi! I\'m ' + this.name.first + '.');
      };
    }
  2. Now add in the following line below it, to create an object instance from it:
    var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);

You'll now see that you can access the properties and methods just like we did previously — try these in your JS console:

person1['age']
person1.interests[1]
person1.bio()
// etc.

Note: If you are having trouble getting this to work, try comparing your code against our version — see oojs-class-finished.html (also see it running live).

Further exercises

To start with, try adding a couple more object creation lines of your own, and try getting and setting the members of the resulting object instances.

In addition, there are a couple of problems with our bio() method — the output always includes the pronoun "He", even if your person is female, or some other preferred gender classification. And the bio will only include two interests, even if more are listed in the interests array. Can you work out how to fix this in the class definition (constructor)? You can put any code you like inside a constructor (you'll probably need a few conditionals and a loop). Think about how the sentences should be structured differently depending on gender, and depending on whether the number of listed interests is 1, 2, or more than 2.

Note: If you get stuck, we have provided an answer inside our GitHub repo (see it live) — try writing it yourself first though!

Otras formas de crear object instances

So far we've seen two different ways to create an object instance — declaring an object literal, and using a constructor function (see above).

These make sense, but there are other ways — we want to make you familiar with these in case you come across them in your travels around the Web.

El constructor Object()

First of all, you can use the Object() constructor to create a new object. Yes, even generic objects have a constructor, which generates an empty object.

  1. Try entering this into your browser's JavaScript console:
    var person1 = new Object();
  2. This stores an empty object in the person1 variable. You can then add properties and methods to this object using dot or bracket notation as desired; try these examples in your console:
    person1.name = 'Chris';
    person1['age'] = 38;
    person1.greeting = function() {
      alert('Hi! I\'m ' + this.name + '.');
    };
  3. You can also pass an object literal to the Object() constructor as a parameter, to prefill it with properties/methods. Try this in your JS console:
    var person1 = new Object({
      name: 'Chris',
      age: 38,
      greeting: function() {
        alert('Hi! I\'m ' + this.name + '.');
      }
    });

Usando el metodo create()

Constructors can help you give your code order—you can create constructors in one place, then create instances as needed, and it is clear where they came from.

However, some people prefer to create object instances without first creating constructors, especially if they are creating only a few instances of an object. JavaScript has a built-in method called create() that allows you to do that. With it, you can create a new object based on any existing object.

  1. With your finished exercise from the previous sections loaded in the browser, try this in your JavaScript console:
    var person2 = Object.create(person1);
  2. Now try these:
    person2.name
    person2.greeting()

You'll see that person2 has been created based on person1—it has the same properties and method available to it.

One limitation of create() is that IE8 does not support it. So constructors may be more effective if you want to support older browsers.

We'll explore the effects of create() in more detail later on.

Resumen

This article has provided a simplified view of object-oriented theory — this isn't the whole story, but it gives you an idea of what we are dealing with here. In addition, we have started to look at how JavaScript relates to and how it differs from "classic OOP", how to implement classes in JavaScript using constructor functions, and different ways of generating object instances.

In the next article, we'll explore JavaScript object prototypes.

 

En este modulo

 

Etiquetas y colaboradores del documento

Colaboradores en esta página: djdouta, paulaco, martinGerez, anyruizd, Michelangeur
Última actualización por: djdouta,