Выразительный JavaScript (Хавербеке) - страница 58

Я предпочитаю рассматривать их с практической, а не идеологической точки зрения. Есть несколько полезных идей, в частности инкапсуляция (различие между внутренней сложностью и внешней простотой), которые были популяризованы объектно-ориентированной культурой. Их стоит изучать.

Эта глава описывает довольно эксцентричный подход JavaScript к объектам, и то, как они соотносятся с классическими объектно-ориентированными техниками.

Методы

Методы – свойства, содержащие функции. Простой метод:

>var rabbit = {};

>rabbit.speak = function(line) {

>  console.log("Кролик говорит '" + line + "'");

>};


>rabbit.speak("Я живой.");

>// → Кролик говорит 'Я живой.'

Обычно метод должен что-то сделать с объектом, через который он был вызван. Когда функцию вызывают в виде метода – как свойство объекта, например >object.method() – специальная переменная в её теле будет указывать на вызвавший её объект.

>function speak(line) {

>  console.log("А " + this.type + " кролик говорит '" + line + "'");

>}

>var whiteRabbit = {type: "белый", speak: speak};

>var fatRabbit = {type: "толстый", speak: speak};


>whiteRabbit.speak("Ушки мои и усики, я же наверняка опаздываю!");

>// → А белый кролик говорит 'Ушки мои и усики, я же наверняка опаздываю!'

>fatRabbit.speak("Мне бы сейчас морковочки.");

>// → А толстый кролик говорит 'Мне бы сейчас морковочки.'

Код использует ключевое слово >this для вывода типа говорящего кролика.

Вспомните, что методы >apply и >bind принимают первый аргумент, который можно использовать для эмуляции вызова методов. Этот первый аргумент как раз даёт значение переменной >this.

Есть метод, похожий на >apply, под названием >call. Он тоже вызывает функцию, методом которой является, только принимает аргументы как обычно, а не в виде массива. Как >apply и >bind, в >call можно передать значение >this.

>speak.apply(fatRabbit, ["Отрыжка!"]);

>// → А толстый кролик говорит 'Отрыжка!'

>speak.call({type: "старый"}, "О, господи.");

>// → А старый кролик говорит 'О, господи.'

Прототипы

Следите за руками.

>var empty = {};

>console.log(empty.toString);

>// → function toString(){…}

>console.log(empty.toString());

>// → [object Object]

Я достал свойство пустого объекта. Магия!

Ну, не магия, конечно. Я просто не всё рассказал про то, как работают объекты в JavaScript. В дополнение к набору свойств, почти у всех также есть прототип. Прототип – это ещё один объект, который используется как запасной источник свойств. Когда объект получает запрос на свойство, которого у него нет, это свойство ищется у его прототипа, затем у прототипа прототипа, и т. д.

Ну а кто же прототип пустого объекта? Это великий предок всех объектов,