Статьи

Простое наследование с помощью JavaScript

Многие мои друзья разработчики на C # или C ++. Они используются для использования наследования в своих проектах, и когда они хотят изучать или открывать JavaScript , один из первых вопросов, который они задают: «Но как я могу сделать наследование с помощью JavaScript?».

На самом деле JavaScript использует иной подход, чем C # или C ++, для создания объектно-ориентированного языка. Это язык на основе прототипов . Концепция прототипирования подразумевает, что поведение может быть повторно использовано путем клонирования существующих объектов, которые служат прототипами. Каждый объект в JavaScript зависит от прототипа, который определяет набор функций и членов, которые объект может использовать. Там нет класса. Просто объекты. Каждый объект может быть использован в качестве прототипа для другого объекта.

Эта концепция чрезвычайно гибкая, и мы можем использовать ее для моделирования некоторых концепций из ООП, таких как наследование.

Реализация наследства

Давайте представим, что мы хотим создать эту иерархию, используя JavaScript:

образ

Прежде всего, мы можем легко создать ClassA. Поскольку явных классов нет, мы можем определить набор поведения (класс так …), просто создав такую ​​функцию:

var ClassA = function() {
    this.name = "class A";
}

Этот «класс» может быть создан с использованием нового ключевого слова:

var a = new ClassA();
ClassA.prototype.print = function() {
    console.log(this.name);
}

И использовать его, используя наш объект:

a.print();

Довольно просто , правда?

Полный образец длиной всего 8 строк:

var ClassA = function() {
    this.name = "class A";
}

ClassA.prototype.print = function() {
    console.log(this.name);
}

var a = new ClassA();

a.print();

Теперь давайте добавим инструмент для создания «наследования» между классами. Этот инструмент просто должен сделать одну вещь: клонирование прототипа:

var inheritsFrom = function (child, parent) {
    child.prototype = Object.create(parent.prototype);
};

Именно здесь происходит волшебство ! Клонируя прототип, мы переносим все члены и функции в новый класс.

Поэтому, если мы хотим добавить второй класс, который будет дочерним по отношению к первому, мы просто должны использовать этот код:

var ClassB = function() {
    this.name = "class B";
    this.surname = "I'm the child";
}

inheritsFrom(ClassB, ClassA);

Затем, поскольку ClassB унаследовал функцию печати от ClassA , работает следующий код:

var b = new ClassB();
b.print();

И выдает следующий вывод:

class B

Мы даже можем переопределить функцию печати для ClassB :

ClassB.prototype.print = function() {
    ClassA.prototype.print.call(this);
    console.log(this.surname);
}

В этом случае полученный результат будет выглядеть так:

class B
I’m the child

Хитрость заключается в том, чтобы вызвать ClassA.prototype, чтобы получить базовую функцию печати . Затем, благодаря функции вызова, мы можем вызвать базовую функцию для текущего объекта ( this ).

Создание ClassC теперь очевидно:

var ClassC = function () {
    this.name = "class C";
    this.surname = "I'm the grandchild";
}

inheritsFrom(ClassC, ClassB);

ClassC.prototype.foo = function() {
    // Do some funky stuff here...
}

ClassC.prototype.print = function () {
    ClassB.prototype.print.call(this);
    console.log("Sounds like this is working!");
}

var c = new ClassC();
c.print();

И вывод:

 class C
 I’m the grandchild
 Sounds like this is working!

Философия …

В заключение я просто хочу четко заявить, что JavaScript не является C # или C ++. У него своя философия . Если вы являетесь разработчиком C ++ или C # и действительно хотите использовать всю мощь JavaScript, лучший совет, который я могу вам дать: не пытайтесь копировать свой язык в JavaScript. Нет лучшего или худшего языка. Просто разные философии!