Dziedziczenie w JavaScript

Dzisiaj słów kilka o dziedziczeniu w JavaScript. Tym wpisem chciałbym zainaugurować serią artykułów na temat różnych smaczków tego języka. Mam nadzieje, że to mi się uda a i że wy odkryjecie w tym coś interesującego dla was samych.

JS posiada dziedziczenie oparte o prototypach, stanowi to odmienne podejście niż to znane nam z języków takich jak np. Java czy PHP. Główna różnica to na brak klas (chociaż standard ECMAScript 6 wprowadził je do języka to i tak „pod spodem” mamy do czynienia z prototypami. Co to takiego te prototypy? Upraszczając, to zdolność obiektu do posiadania referencji __proto__, która przechowuje właściwości i metody będące klonowane (skopiowane) do klasy potomnej. Każdy obiekt w JavaScipt zawiera taką referencje, jest to tak zwany obiekt nadrzędny. W momencie gdy “klasa” potomna nie posiada żądanej metody, to silnik JS sprawdza obiekt rodzica a następnie obiekt nadrzędny w celu uzyskania danej metody. Poniżej prosty przykład, który to obrazuje.

// konstruktor
function Book(name) {
this.name = name || 'Eloquent JavaScript';
};

//dodawanie do prototypu
Book.prototype.getName = function () {
  return this.name;
};

// utworzenie obiektu
var book = new Book();

// dziedziczenie
var technicalBook = Object.create(book); //Object.create istnieje od standardu ECMAScript 5

console.log(technicalBook.getName()); // Zwróci Eloquent JavaScript

Z kolei od ECMAScript 6 moglibyśmy to zapisać w taki sposób

class Book {
  setName(name) {
    this.name = name;
  }
  getName() {
    return this.name;
  }
}

class TechnicalBook extends Book {

}

let technicalBook = new TechnicalBook();
technicalBook.setName('Eloquent JavaScript');

console.log(technicalBook.getName()); // Zwróci Eloquent JavaScript
console.log(technicalBook.name); // Zwróci Eloquent JavaScript

Tyle na dzisiaj, a wy którą składnie bardziej preferujecie?