- PVSM.RU - https://www.pvsm.ru -

Стандарт ECMA-262 (JavaScript) в картинках, часть 3

Стандарт ECMA-262 (JavaScript) в картинках, часть 3 - 1
В предыдущих частях рассматривались структуры execution context, объекты Function [1] и указатель this [2]. В третьей части речь пойдет о прототипном наследовании.

Как реализуются классы

В JavaScript нет классов. Там, где в классическом ООП используются классы и объекты в JavaScript применяются объекты с функциями и объекты с данными.

Стандарт ECMA-262 (JavaScript) в картинках, часть 3 - 2

При поиске свойств [3] используется внутреннее поле [[Prototype]] (оно доступно снаружи как __proto__). Если свойство не найдено в объекте, то оно ищется в прототипе.

var a = {
  n: 1
};

var b = {
  __proto__: a,
  m: 2
};

console.log(b.n); // выведет 1

Для того, чтобы кажды раз при создании объекта не требовалось явно указывать __proto__ в JavaScript можно использовать функции в качестве конструкторов с помощью оператора new. При интерпретации ключевого слова function каждый раз создается не только объект Function, но и связанный с ним объект Prototype [4].

Стандарт ECMA-262 (JavaScript) в картинках, часть 3 - 3

Если вызвать функцию как new User(), а не просто User(), то будет создан новый объект. Свойство __proto__ нового объекта будет указывать на prototype функции.

Стандарт ECMA-262 (JavaScript) в картинках, часть 3 - 4

При вызове функции через new ThisBinding контекста будет указывать на созданный объект. Если в function User написать this.name = "Unknown", то в новом объекте появится поле name с указанным значением.
"Методы класса" логично размещать в прототипе, в этом случае все "объекты класса" будут иметь к ним доступ.

function User(name) {
  this.name = name;
}

User.prototype.getName = function _getName() {
   return this.name;
}

var user = new User("John");
console.log(user.getName());

Так как при вызове "методов" используется обращение через точку: user.getName(), то ThisBinding будет указывать на новый объект и return this.name вернет значение соответствующее значение name.

Стандарт ECMA-262 (JavaScript) в картинках, часть 3 - 5

Важно различать _proto_ и prototype. Свойство __proto__ ([[Prototype]]) есть у всех объектов и используется для поиска свойств. Свойство prototype есть только у объектов Function и используется при создании объектов через new.

Как реализуется наследование классов

Наследование в JavaScript реализуется с помощью цепочки прототипов.

Стандарт ECMA-262 (JavaScript) в картинках, часть 3 - 6

Допустим, от класса User необходимо отнаследовать класс Employee и добавить еще один "метод". Для этого нужно:

  • реализовать функцию Employee, которая будет использована в качестве конструктора,
  • добавить в её прототип необходимые функции,
  • указать в __proto__ прототипа Employee ссылку на прототип User.

В этом случае если функция не будет найдена в одном прототипе поиск будет продолжен в "родительском прототипе".

Стандарт ECMA-262 (JavaScript) в картинках, часть 3 - 7

Впрочем, длинные цепочки наследования в JavaScript не приветствуются.
Подробнее про прототипное наследование в стандарте:

Заключение

Читайте стандарт, ничего сложного там нет. Главное разобраться в основных понятиях и связях между ними. Рекомендую начать с чего-нибудь понятного, например, с вызова функции [7]. Затем – разобраться со встречающимися в тексте определениями. Рекурсивно повторить.

Также имеет смысл посмотреть на первые релизы стандартов [8]. Во-первых, интересно наблюдать за эволюцией. А во-вторых, некоторые фичи появились позже, поэтому сами стандарты были проще. Например, нет разделения на LexicalEnvironment и VariableEnvironment, которое несколько сбивает с толку.

Если хотя бы один разработчик после прочтения статьи разберется со стандартом я смогу считать свою задачу выполненной.

Автор: alvin777

Источник [9]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/116077

Ссылки в тексте:

[1] структуры execution context, объекты Function: https://habrahabr.ru/post/279421/

[2] указатель this: https://habrahabr.ru/post/279733/

[3] При поиске свойств: http://www.ecma-international.org/ecma-262/5.1/#sec-8.12.2

[4] создается не только объект Function, но и связанный с ним объект Prototype: http://www.ecma-international.org/ecma-262/5.1/#sec-13.2

[5] 11.2.2 The new Operator: http://www.ecma-international.org/ecma-262/5.1/#sec-11.2.2

[6] 13.2.2 [[Construct]]: http://www.ecma-international.org/ecma-262/5.1/#sec-13.2.2

[7] с вызова функции: http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.3

[8] на первые релизы стандартов: http://www-archive.mozilla.org/js/language/E262.pdf

[9] Источник: https://habrahabr.ru/post/280137/