Если вы пишете метод, не имеющий собственного возвращаемого значения, подумайте о возможности возвращать из него значение this. Если неуклонно следовать этому правилу при разработке своего API, появится возможность использовать стиль программирования, известный как составление цепочек из методов,[12]
когда обращение к имени метода выполняется один раз, а затем может следовать множество вызовов его методов:
<b>shape.setX(100).setY(100).setSize(50).setOutline("red").setFill("blue").draw();</b>
He путайте цепочки вызовов методов с цепочками конструкторов, которые описываются в разделе 9.7.2.
8.2.2. Вызов методов
Метод - это не что иное, как функция, которая хранится в виде свойства объекта. Если имеется функция f и объект о, то можно определить метод объекта о с именем m, как показано ниже:
<b>о.m = f;</b>
После этого можно вызвать метод m() объекта о:
<b>о.m();</b>
Или, если метод m() принимает два аргумента, его можно вызвать так:
<b>о.m(х, у);</b>
Строка выше является выражением вызова: она включает выражение обращения к функции о.m и два выражения-аргумента, х и у. Выражение обращения к функции в свою очередь является выражением обращения к свойству (раздел 4.4), а это означает, что функция вызывается как метод, а не как обычная функция.
Аргументы и возвращаемое значение при вызове метода обрабатываются точно так же, как при вызове обычной функции. Однако вызов метода имеет одно важное отличие: контекст вызова. Выражение обращения к свойству состоит из двух частей: объекта (в данном случае о) и имени свойства (m). В подобных выражениях вызова методов объект о становится контекстом вызова, и тело функции получает возможность ссылаться на этот объект с помощью ключевого слова
<b>this</b>
. Например:
<b>var calculator = { // Литерал объекта</b>
<b> ореrand1: 1, </b>
<b> operand2: 1, </b>
<b> add: function() {</b>
<b> // Обратите внимание, что для ссылки на этот объект используется</b>
<b> // ключевое слово this.</b>
<b> this.result = this.operandl + this.operand2:</b>
<b> }</b>
<b>};</b>
<b>calculator.add(); // Вызвать метод, чтобы вычислить 1+1. </b>
<b>calculator.result // => 2</b>
Чаще всего при вызове методов используется форма обращения к свойствам с помощью оператора точки, однако точно так же можно использовать форму обращения к свойствам с помощью квадратных скобок. Например, оба следующих выражения являются выражениями вызова методов:
<b>о["m’'](х,у); // Другой способ записать это выражение: о.m(х.у).</b>
<b>a[0](z) // Тоже вызов метода (предполагается, что а[0] - это функция).</b>
Выражения вызова методов могут включать более сложные выражения обращения к свойствам:
<b>customer.surname.toUpperCase(): // Вызвать метод объекта customer.surname </b>
<b>f().m(); // Вызвать метод m() возвращаемого значения функции f()</b>
Методы и ключевое слово
<b>this</b>
занимают центральное место в парадигме объектно-ориентированного программирования. Любая функция, используемая как метод, фактически получает неявный аргумент - объект, относительно которого она была вызвана. Как правило, методы выполняют некоторые действия с объектом, и синтаксис вызова метода наглядно отражает тот факт, что функция оперирует объектом. Сравните следующие две строки:
rect.setSize(width, height);
setRectSize(rect, width, height);
Гипотетически функции, вызывающиеся в этих двух строках, могут производить абсолютно идентичные действия над объектом rect (гипотетическим), но синтаксис вызова метода в первой строке более наглядно демонстрирует, что в центре внимания находится объект rect.
Обратите внимание:
<b>this</b>
- это именно ключевое слово, а не имя переменной или свойства. Синтаксис JavaScript не допускает возможность присваивания значений элементу
<b>this</b>
.
В отличие от переменных, ключевое слово
<b>this</b>
не имеет области видимости, и вложенные функции не наследуют значение
<b>this</b>
от вызывающей функции. Если вложенная функция вызывается как метод, значением
<b>this</b>
является объект, относительно которого был сделан вызов. Если вложенная функция вызывается как функция, то значением
<b>this</b>
будет либо глобальный объект (в нестрогом режиме), либо
<b>undefined</b>
(в строгом режиме). Распространенная ошибка полагать, что во вложенной функции, которая вызывается как функция, можно использовать
<b>this</b>
для получения доступа к контексту внешней функции. Если во вложенной функции необходимо иметь доступ к значению
<b>this</b>
внешней функции, это значение следует сохранить в переменной, находящейся в области видимости внутренней функции. Для этой цели часто используется переменная с именем self. Например:
<b>var о = { // Объект о.</b>
<b> m: function() { // Метод m объекта.</b>
<b> var self = this; // Сохранить значение this в переменной,</b>
<b> console.log(this === о); // Выведет "true": this - это объект о.</b>
<b> f(); // Вызвать вспомогательную ф-цию f().</b>
<b> function f() { // Вложенная функция f</b>
<b> console.log(this === о); // "false": this - глоб. об. или undefined</b>