aboutsummaryrefslogtreecommitdiff
path: root/files/es/learn/javascript/objects/inheritance/index.html
blob: e1cbba42da16ed2348b8b9a6b0ca7965ef385098 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
---
title: Herencia en JavaScript
slug: Learn/JavaScript/Objects/Inheritance
translation_of: Learn/JavaScript/Objects/Inheritance
---
<div>{{LearnSidebar}}</div>

<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</div>

<p class="summary">Con la mayoría de los detalles internos de OOJS (<em>JavaScript Orientado a Objetos) </em>explicados, este artículo muestra cómo crear clases "hijo" (constructores) que heredan características de sus clases "padre". Además, presentamos algunos consejos sobre cuándo y dónde puedes usar OOJS y cómo se crean las clases con la sintaxis moderna de ECMAScript.</p>

<table class="learn-box standard-table">
 <tbody>
  <tr>
   <th scope="row">Pre-requisitos:</th>
   <td>Conocimientos básicos de informática, una comprensión básica de HTML y CSS, familiaridad con los principios básicos de JavaScript (ver <a href="/en-US/docs/Learn/JavaScript/First_steps">Primeros pasos</a> y <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Construyendo bloques</a>) y conceptos básicos de OOJS (ver <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduccion a objetos</a>).</td>
  </tr>
  <tr>
   <th scope="row">Objetivo:</th>
   <td>Entender cómo es posible implementar la herencia en JavaScript.</td>
  </tr>
 </tbody>
</table>

<h2 id="Herencia_prototípica">Herencia prototípica</h2>

<p>Hasta ahora hemos visto algo de herencia en acción — hemos visto cómo funcionan las cadenas de prototipos, y cómo los miembros son heredados subiendo una cadena. Pero principalmente esto ha involucrado funciones integradas del navegador. ¿Cómo creamos un objeto en JavaScript que hereda de otro objeto?</p>

<p>Exploremos cómo hacer esto con un ejemplo concreto.</p>

<h2 id="Primeros_pasos">Primeros pasos</h2>

<p>Primero que nada, hazte una copia local de nuestro archivo  <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-start.html">oojs-class-inheritance-start.html</a> (míralo <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-start.html">corriendo en vivo</a> también). Dentro de aquí encontrarás el mismo ejemplo de constructor de <code>Persona()</code> que hemos estado usando a través del módulo, con una ligera diferencia — hemos definido solo las propiedades dentro del constructor:</p>

<pre class="brush: js notranslate">function Persona(nombrePila, apellido, edad, genero, intereses) {
  this.nombre = {
    nombrePila,
    apellido
  };
  this.edad = edad;
  this.genero = genero;
  this.intereses = intereses;
};</pre>

<p><em>Todos</em> los métodos están definidos en el prototipo del constructor. Por ejemplo:</p>

<pre class="brush: js notranslate">Persona.prototype.saludo = function() {
  alert('¡Hola! soy ' + this.nombre.nombrePila + '.');
};</pre>

<div class="note">
<p><strong>Nota</strong>: En el código fuente, también verá los métodos <code>bio()</code> y <code>despedida()</code> definidos. Más tarde verá cómo estos pueden ser heredados por otros constructores.</p>
</div>

<p>Digamos que quisieramos crear una clase de <code>Profesor</code>, como la que describimos en nuestra definición inicial orientada a objetos, que hereda todos los miembros de <code>Persona</code>, pero también incluye:</p>

<ol>
 <li>Una nueva propiedad, <font face="consolas, Liberation Mono, courier, monospace"><span>materia</span></font> — esto contendrá la materia que el profesor enseña.</li>
 <li>Un método actualizado de <code>saludo()</code>, que suena un poco más formal que el método estándar de <code>saludo()</code> — más adecuado para un profesor que se dirige a algunos estudiantes en la escuela.</li>
</ol>

<h2 id="Definiendo_un_constructor_Profesor">Definiendo un constructor Profesor()</h2>

<p>Lo primero que tenemos que hacer es crear el constructor Profesor<code>()</code>  — añadimos lo siguiente tras el código existente:</p>

<pre class="brush: js notranslate">function Profesor(nombrePila, apellido, edad, genero, intereses, materia) {
  Person.call(this, nombrePila, apellido, edad, genero, intereses);

  this.materia = materia;
}</pre>

<p>Esto es similar al constructor de Persona en muchos aspectos, pero hay algo extraño aquí que no hemos visto antes: la función call (). Esta función básicamente le permite llamar a una función definida en otro lugar, pero en el contexto actual.<br>
 El primer parámetro especifica el valor de this que desea utilizar al ejecutar la función, y los otros parámetros son aquellos que deben pasarse a la función cuando se invoca.</p>

<p>Queremos que el constructor Profesor() tome los mismos parámetros que el constructor Persona() del que está heredando, por lo que los especificamos todos como parámetros en la invocación call().</p>

<p>La última línea dentro del constructor simplemente define la nueva propiedad subject que los profesores tendrán y que las personas genéricas no tienen.</p>

<p>Como nota, podríamos haber simplemente hecho esto:</p>

<pre class="brush: js notranslate">function Profesor(nombrePila, apellido, edad, genero, intereses, materia) {
  this.nombre = {
    nombrePila,
    apellido
  };
  this.edad = edad;
  this.genero = genero;
  this.intereses = intereses;
  this.materia = materia;
}</pre>

<p>Pero esto es solo definir las propiedades de nuevo, no heredarlas de Persona(), por lo que anula el punto de lo que estamos tratando de hacer. También lleva más líneas de código.</p>

<h3 id="Heredando_de_un_constructor_sin_parámetros">Heredando de un constructor sin parámetros</h3>

<p>Nótese que si el constructor del cual se está heredando no toma los valores de sus propiedades de parámetros, no se necesita especificarlos como argumentos adicionales en <code>call()</code>. Por ejemplo, si se tuviera algo muy simple como esto:</p>

<pre class="brush: js notranslate">function Brick() {
  this.width = 10;
  this.height = 20;
}</pre>

<p>Se podrían heredar las propiedades <code>width</code> y <code>height</code> haciendo esto (así como los otros pasos descritos a continuación, por supuesto):</p>

<pre class="brush: js notranslate">function BlueGlassBrick() {
  Brick.call(this);

  this.opacity = 0.5;
  this.color = 'blue';
}</pre>

<p>Nótese que solo especificamos <code>this</code> dentro de <code>call()</code> — no se requieren otros parámetros ya que no estamos heredando ninguna propiedad del padre que sea establecida por parámetros.</p>

<h2 id="Estableciendo_el_prototipo_de_Profesor_y_su_referencia_al_constructor">Estableciendo el prototipo de Profesor() y su referencia al constructor</h2>

<p>Todo va bien hasta ahora, pero tenemos un problema. Definimos un nuevo constructor, y tiene una propiedad <code>prototype</code>, la cual por defecto solo contiene una referencia a la función constructor en sí misma. No contiene los métodos de la propiedad <code>prototype</code> del constructor <code>Persona</code>. Para ver esto, introduzca <code>Object.getOwnPropertyNames(Profesor.prototype)</code> ya sea en el campo de texto o en la consola de Javascript . Introdúzcalo nuevamente, reemplazando <code>Profesor</code> con <code>Persona</code>. El nuevo constructor tampoco hereda esos métodos. Para ver esto, compare los resultados de <code>Persona.prototype.saludo</code> and <code>Profesor.prototype.saludo</code>. Necesitamos obtener <code>Profesor()</code> para obtener los métodos definidos en el prototipo de <code>Persona()</code>. ¿Cómo lo hacemos?</p>

<ol>
 <li>Añade la siguiente línea debajo de tu adición anterior:
  <pre class="brush: js notranslate">Profesor.prototype = Object.create(Persona.prototype);</pre>
  Aquí es cuando nuestro amigo <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code> sale al rescate de nuevo. En este caso lo estamos usando para crear un nuevo objeto y hacerlo el valor de <code>Profesor.prototype.</code> El nuevo objeto tiene <code>Persona.prototype</code> como su prototipo y por lo tanto heredará, si y cuando lo necesite, todos los métodos disponibles en <code>Persona.prototype</code>.</li>
 <li>Necesitamos hacer una cosa más antes de proseguir. Después de agregar la última línea, la propiedad <code>constructor </code>de  <code>Profesor.prototype</code> es ahora igual a <code>Persona()</code>, debido a que acabamos de asignar <code>Profesor.prototype</code> para que haga referencia a un objeto que hereda sus propiedades de <code>Persona.prototype</code>! Ahora prueba guardando tu código, carga la página en un explorador e intenta verificar en la consola el valor de  <code>Profesor.prototype.constructor</code>.</li>
 <li>Esto puede volverse un problema, así que necesitamos corregirlo. Puedes hacerlo regresando a tu código y agregando la siguiente línea al final:
  <pre class="brush: js notranslate">Profesor.prototype.constructor = Profesor;</pre>
 </li>
 <li>Ahora, si guardas y actualizas, el valor de <code>Profesor.prototype.constructor</code> debe regresar <code>Profesor()</code>, como se espera, además de que ahora estamos heredando de <code>Persona()</code>!</li>
</ol>

<h2 id="Dándole_a_Profesor_un_nuevo_método_saludo">Dándole a Profesor() un nuevo método saludo()</h2>

<p>Para finalizar nuestro código, necesitamos definir un nuevo método <code>saludo()</code> en el constructor de <code>Profesor()</code>.</p>

<p>La manera más fácil es definirlo en el prototipo de <code>Profesor()</code> — agrega lo siguiente al final de tu código:</p>

<pre class="brush: js notranslate">Profesor.prototype.saludo = function() {
  var prefijo;

  if (this.genero === 'masculino' || this.genero === 'Masculino' || this.genero === 'm' || this.genero === 'M') {
    prefijo = 'Sr.';
  } else if (this.genero === 'female' || this.genero === 'Femenino' || this.genero === 'f' || this.genero === 'F') {
    prefijo = 'Sra.';
  } else {
    prefijo = 'Sx.';
  }

  alert('Hola. Mi nombre es ' + prefijo + ' ' + this.nombre.apellido + ', y enseño ' + this.materia + '.');
};</pre>

<p>Esto muestra el saludo del profesor, el cual además utiliza un prefijo apropiado para su género, resuelto utilizando un bloque else-if.</p>

<h2 id="Probando_el_ejemplo">Probando el ejemplo</h2>

<p>Ahora que ha ingresado todo el código, intente creando una instancia de objeto desde <code>Profesor()</code> poniendo lo que sigue al final de su archivo (o algo similar a su elección):</p>

<pre class="brush: js notranslate">var teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');</pre>

<p>Ahora guarde y actualice, e intente accediendo a las propiedades y metodos de su nuevo<code> teacher1</code> objecto, por ejemplo:</p>

<pre class="brush: js notranslate">teacher1.name.first;
teacher1.interests[0];
teacher1.bio();
teacher1.subject;
teacher1.greeting();
teacher1.farewell();</pre>

<p>Esto deberia trabajar bien. Las consultas de las líneas 1, 2, 3, y 6 acceden a miembros heredados del genérico<code> Person()</code> constructor (clase). La consulta de la línea 4 accede un miembro que es disponible solamente en el mas especializado<code> Teacher()</code> constructor (clase). La consulta de la línea 5 accedería a un miembro desde<code> Person()</code>, excepto por el hecho que <code>Teacher()</code> tiene sus propios miembros con el mismo nombre, entonces la consulta accede a ese miembro.</p>

<div class="note">
<p><strong>Nota</strong>: Si tiene problemas con el funcionamiento, compare su código con nuestra <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-finished.html">versión final</a> (vea <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-finished.html">corriendo en vivo</a> también).</p>
</div>

<p>La técnica que mostramos aquí no es la única para crear herencia de clases en JavaScript, pero funciona OK, y le dá una buena idea acerca de cómo implementar herencia en JavaScript.</p>

<p>También estará interesado en verificar algo de las nuevas características de {{glossary("ECMAScript")}} que nos permiten hacer herencia mas claramente en JavaScript (véase <a href="/en-US/docs/Web/JavaScript/Reference/Classes">Classes</a>). No se cubrió todo aquí, como tampoco es soportado aún por todos los navegadores. Todo el otro código de constructores que se discutió aquí en estos artículos son soportados por IE9 o superior, y hay caminos para lograr superiores soportes que estos.</p>

<p>Un simple camino es usar una librería de JavaScript — la mayoría de las opciones mas populares tienen un facil ajuste de funcionalidad disponible para hacer herencia mas facil y rápido. <a href="http://coffeescript.org/#classes">CoffeeScript</a> por ejemplo provee<code> class</code>, <code>extends</code>, etc.</p>

<h2 id="Un_ejercicio_mas_allá">Un ejercicio mas allá</h2>

<p>En nuestra <a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS#Object-oriented_programming_from_10000_meters">Sección teórica de POO</a>, también incluimos una clase <code>Student</code> como un concepto, el cual hereda todas las características de <code>Person</code>, y también tiene un método diferende de <code>greeting()</code> que <code>Person</code> que es mas informal que el saludo de los profesores <code>Teacher</code>. Dele una mirada al saludo de los estudiantes, y trate de implementar su propio constructor de saludo <code>Student()</code> que herede todas las características de <code>Person()</code>, e implemente las diferentes funciones de saludo <code>greeting()</code>.</p>

<div class="note">
<p><strong>Nota</strong>: Si tiene problemas resolviendo esto, dele una mirada a nuestra<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-student.html"> versión final</a> (véala tambien <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-student.html">funcionando</a> ).</p>
</div>

<h2 id="Resúmen_de_miembros_objeto">Resúmen de miembros objeto</h2>

<p>To summarize, you've basically got three types of property/method to worry about:</p>

<ol>
 <li>Those defined inside a constructor function that are given to object instances. These are fairly easy to spot — in your own custom code, they are the members defined inside a constructor using the <code>this.x = x</code> type lines; in built in browser code, they are the members only available to object instances (usually created by calling a constructor using the <code>new</code> keyword, e.g. <code>var myInstance = new myConstructor()</code>).</li>
 <li>Those defined directly on the constructor themselves, that are available only on the constructor. These are commonly only available on built-in browser objects, and are recognized by being chained directly onto a constructor, <em>not</em> an instance. For example, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code>.</li>
 <li>Those defined on a constructor's prototype, which are inherited by all instances and inheriting object classes. These include any member defined on a Constructor's prototype property, e.g. <code>myConstructor.prototype.x()</code>.</li>
</ol>

<p>If you are not sure which is which, don't worry about it just yet — you are still learning, and familiarity will come with practice.</p>

<h2 id="ECMAScript_2015_Classes">ECMAScript 2015 Classes</h2>

<p>ECMAScript 2015 introduces <a href="/en-US/docs/Web/JavaScript/Reference/Classes">class syntax</a> to JavaScript as a way to write reusable classes using easier, cleaner syntax, which is more similar to classes in C++ or Java. In this section we'll convert the Person and Teacher examples from prototypal inheritance to classes, to show you how it's done.</p>

<div class="note">
<p><strong>Note</strong>: This modern way of writing classes is supported in all modern browsers, but it is still worth knowing about how the underlying prototypal inheritance in case you work on a project that requires supporting a browser that doesn't support this syntax (most notably Internet Explorer).</p>
</div>

<p>Let's look at a rewritten version of the Person example, class-style:</p>

<pre class="brush: js notranslate">class Person {
  constructor(first, last, age, gender, interests) {
    this.name = {
      first,
      last
    };
    this.age = age;
    this.gender = gender;
    this.interests = interests;
  }

  greeting() {
    console.log(`Hi! I'm ${this.name.first}`);
  };

  farewell() {
    console.log(`${this.name.first} has left the building. Bye for now!`);
  };
}
</pre>

<p>The <a href="/en-US/docs/Web/JavaScript/Reference/Statements/class">class</a> statement indicates that we are creating a new class. Inside this block, we define all the features of the class:</p>

<ul>
 <li>The <code><a href="/en-US/docs/Web/JavaScript/Reference/Classes/constructor">constructor()</a></code> method defines the constructor function that represents our <code>Person</code> class.</li>
 <li><code>greeting()</code> and <code>farewell()</code> are class methods. Any methods you want associated with the class are defined inside it, after the contructor. In this example, we've used <a href="/en-US/docs/Web/JavaScript/Reference/Template_literals">template literals</a> rather than string concatenation to make the code easier to read.</li>
</ul>

<p>We can now instantiate object instances using the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/new"><code>new</code> operator</a>, in just the same way as we did before:</p>

<pre class="brush: js notranslate">let han = new Person('Han', 'Solo', 25, 'male', ['Smuggling']);
han.greeting();
// Hi! I'm Han

let leia = new Person('Leia', 'Organa', 19, 'female' ['Government']]);
leia.farewell();
// Leia has left the building. Bye for now
</pre>

<div class="note">
<p><strong>Note</strong>: Under the hood, your classes are being converted into prototypal Inheritance models — this is just syntactic sugar. But I'm sure you'll agree that it's easier to write.</p>
</div>

<h3 id="Inheritance_with_class_syntax">Inheritance with class syntax</h3>

<p>Above we created a class to represent a person. They have a series of attributes that are common to all people; in this section we'll create our specialized <code>Teacher</code> class, making it inherit from <code>Person</code> using modern class syntax. This is called creating a subclass or subclassing.</p>

<p>To create a subclass we use the <a href="/en-US/docs/Web/JavaScript/Reference/Classes/extends">extends keyword</a> to tell JavaScript the class we want to base our class on.</p>

<pre class="brush: js notranslate">class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    this.name = {
      first,
      last
    };

  this.age = age;
  this.gender = gender;
  this.interests = interests;
  // subject and grade are specific to Teacher
  this.subject = subject;
  this.grade = grade;
  }
}</pre>

<p>We can make the code more readable by defining the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/super"><code>super()</code> operator</a> as the first item inside the <code>constructor()</code>. This will call the parent class' constructor, and inherit the members we specify as parameters of <code>super()</code>, as long as they are defined there:</p>

<pre class="brush: js notranslate">class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    super(first, last, age, gender, interests);

    // subject and grade are specific to Teacher
    this.subject = subject;
    this.grade = grade;
  }
}
</pre>

<p>When we instantiate <code>Teacher</code> object instances, we can now call methods and properties defined on both <code>Teacher</code> and <code>Person</code>, as we'd expect:</p>

<pre class="brush: js notranslate">let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5);
snape.greeting(); // Hi! I'm Severus.
snape.farewell(); // Severus has left the building. Bye for now.
snape.age // 58
snape.subject; // Dark arts
</pre>

<p>Like we did with Teachers, we could create other subclasses of <code>Person</code> to make them more specialized without modifying the base class.</p>

<div class="note">
<p><strong>Note</strong>: You can find this example on GitHub as <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/es2015-class-inheritance.html">es2015-class-inheritance.html</a> (<a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/es2015-class-inheritance.html">see it live also</a>).</p>
</div>

<h2 id="Getters_and_Setters">Getters and Setters</h2>

<p>There may be times when we want to change the values of an attribute in the classes we create or we don't know what the final value of an attribute will be. Using the <code>Teacher</code> example, we may not know what subject the teacher will teach before we create them, or their subject may change between terms.</p>

<p>We can handle such situations with getters and setters.</p>

<p>Let's enhance the Teacher class with getters and setters. The class starts the same as it was the last time we looked at it.</p>

<p>Getters and setters work in pairs. A getter returns the current value of the variable and its corresponding setter changes the value of the variable to the one it defines.</p>

<p>The modified <code>Teacher</code> class looks like this:</p>

<pre class="brush: js notranslate">class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    super(first, last, age, gender, interests);
    // subject and grade are specific to Teacher
    this._subject = subject;
    this.grade = grade;
  }

  get subject() {
    return this._subject;
  }

  set subject(newSubject) {
    this._subject = newSubject;
  }
}
</pre>

<p>In our class above we have a getter and setter for the <code>subject</code> property. We use <strong><code>_</code> </strong> to create a separate value in which to store our name property. Without using this convention, we would get errors every time we called get or set. At this point:</p>

<ul>
 <li>To show the current value of the <code>_subject</code> property of the <code>snape</code> object we can use the <code>snape.subject</code> getter method.</li>
 <li>To assign a new value to the <code>_subject</code> property we can use the <code>snape.subject="new value"</code> setter method.</li>
</ul>

<p>The example below shows the two features in action:</p>

<pre class="brush: js notranslate">// Check the default value
console.log(snape.subject) // Returns "Dark arts"

// Change the value
snape.subject="Balloon animals" // Sets _subject to "Balloon animals"

// Check it again and see if it matches the new value
console.log(snape.subject) // Returns "Balloon animals"
</pre>

<div class="note">
<p><strong>Note</strong>: You can find this example on GitHub as <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/es2015-getters-setters.html">es2015-getters-setters.html</a> (<a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/es2015-getters-setters.html">see it live also</a>).</p>
</div>

<h2 id="When_would_you_use_inheritance_in_JavaScript">When would you use inheritance in JavaScript?</h2>

<p>Particularly after this last article, you might be thinking "woo, this is complicated". Well, you are right. Prototypes and inheritance represent some of the most complex aspects of JavaScript, but a lot of JavaScript's power and flexibility comes from its object structure and inheritance, and it is worth understanding how it works.</p>

<p>In a way, you use inheritance all the time. Whenever you use various features of a Web API , or methods/properties defined on a built-in browser object that you call on your strings, arrays, etc., you are implicitly using inheritance.</p>

<p>In terms of using inheritance in your own code, you probably won't use it often, especially to begin with, and in small projects. It is a waste of time to use objects and inheritance just for the sake of it when you don't need them. But as your code bases get larger, you are more likely to find a need for it. If you find yourself starting to create a number of objects that have similar features, then creating a generic object type to contain all the shared functionality and inheriting those features in more specialized object types can be convenient and useful.</p>

<div class="note">
<p><strong>Note</strong>: Because of the way JavaScript works, with the prototype chain, etc., the sharing of functionality between objects is often called <strong>delegation</strong>. Specialized objects delegate functionality to a generic object type.</p>
</div>

<p>When using inheritance, you are advised to not have too many levels of inheritance, and to keep careful track of where you define your methods and properties. It is possible to start writing code that temporarily modifies the prototypes of built-in browser objects, but you should not do this unless you have a really good reason. Too much inheritance can lead to endless confusion, and endless pain when you try to debug such code.</p>

<p>Ultimately, objects are just another form of code reuse, like functions or loops, with their own specific roles and advantages. If you find yourself creating a bunch of related variables and functions and want to track them all together and package them neatly, an object is a good idea. Objects are also very useful when you want to pass a collection of data from one place to another. Both of these things can be achieved without use of constructors or inheritance. If you only need a single instance of an object, then you are probably better off just using an object literal, and you certainly don't need inheritance.</p>

<h2 id="Alternativas_para_extender_la_cadena_del_prototipos">Alternativas para extender la cadena del prototipos</h2>

<p>En JavaScript, hay varias maneras diferentes de extender el prototipo de un objeto aparte de lo que hemos mostrado anteriormente. Para saber más sobre las otras formas, visite nuestro artículo <a href="/es/docs/Web/JavaScript/Herencia_y_la_cadena_de_protipos">Herencia y la cadena de prototipos</a>.</p>

<h2 id="Resumen">Resumen</h2>

<p>Este artículo ha cubierto el resto de la teoría y sintaxis central de OOJS que creemos que debería conocer ahora. En este punto debe entender los conceptos básicos de objetos JavaScript y POO, prototipos y herencia de prototipos, cómo crear clases (constructores) e instancias de objetos, añadir características a las clases y crear subclases que heredan de otras clases.</p>

<p>En el siguiente artículo veremos cómo trabajar con JavaScript Object Notation (JSON), un formato común de intercambio de datos escrito con objetos JavaScript.</p>

<h2 id="Véase_también">Véase también</h2>

<ul>
 <li><a href="http://www.objectplayground.com/">ObjectPlayground.com</a> — A really useful interactive learning site for learning about objects.</li>
 <li><a href="https://www.amazon.com/gp/product/193398869X/">Secrets of the JavaScript Ninja</a>, Chapter 6 — A good book on advanced JavaScript concepts and techniques, by John Resig and Bear Bibeault. Chapter 6 covers aspects of prototypes and inheritance really well; you can probably track down a print or online copy fairly easily.</li>
 <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&amp;%20object%20prototypes/README.md#you-dont-know-js-this--object-prototypes">You Don't Know JS: this &amp; Object Prototypes</a> — Part of Kyle Simpson's excellent series of JavaScript manuals, Chapter 5 in particular looks at prototypes in much more detail than we do here. We've presented a simplified view in this series of articles aimed at beginners, whereas Kyle goes into great depth and provides a more complex but more accurate picture.</li>
</ul>

<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</p>

<h2 id="En_éste_módulo">En éste módulo</h2>

<ul>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li>
</ul>