Я предпочитаю рассматривать их с практической, а не идеологической точки зрения. Есть несколько полезных идей, в частности инкапсуляция (различие между внутренней сложностью и внешней простотой), которые были популяризованы объектно-ориентированной культурой. Их стоит изучать.
Эта глава описывает довольно эксцентричный подход 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. В дополнение к набору свойств, почти у всех также есть прототип. Прототип – это ещё один объект, который используется как запасной источник свойств. Когда объект получает запрос на свойство, которого у него нет, это свойство ищется у его прототипа, затем у прототипа прототипа, и т. д.
Ну а кто же прототип пустого объекта? Это великий предок всех объектов,