Одной из целей создания объекта triangle было создание связи между данными треугольника и действиями, которые можно выполнить с данными. Однако пока это еще не реализовано. Вы сразу заметите, что метод triangle.getArea по прежнему требует, чтобы ему передавались данные о длине сторон, когда он выполняется, что приводит к коду следующего вида:
Я думаю, что это лучше, чем код, который был в начале лекции, так как он ясно выражает отношения между данными и действием. Это отношение, однако, означает, что мы не должны сообщать методу, с какими значениями работать. Он должен сам собирать данные об объекте, в котором находится, и использовать эти данные, не требуя ввода вручную.
Секрет находится в ключевом слове this, которое можно использовать внутри определения метода, чтобы ссылаться на другие свойства и методы этого же объекта. Переписывая метод getArea соответствующим образом, мы получаем следующий код:
triangle.getArea = function () {
// Возвращает площадь треугольника, используя формулу Герона
var semiperimeter = (this.sideA + this.sideB + this.sideC) / 2;
}; // Обратите внимание здесь на точку с запятой, она обязательна.
Как можно видеть, это работает в некоторой степени как зеркало. Когда выполняется метод getArea, он посмотрит на свое отражение, чтобы считать свои свойства sideA, sideB, и sideC. Он может использовать это в вычислениях, вместо использования внешнего ввода.
Примечание: Это немного сверхупрощенное изложение. this не всегда ссылается на объект, в котором определен метод, но наоборот может изменяться на основе определенных контекстов. Прошу прощения за некоторую неясность здесь, но это немного за пределами данной лекции. Зная об этом, вы в остальном можете быть уверены, что в использованном здесь контексте this всегда будет указывать на объект triangle.
Оператор точки является не единственным способом доступа к свойствам и методам объекта, они могут быть доступны вполне эффективно с помощью записи с индексом, которая может быть знакома из предыдущего обсуждения массивов. Вкратце, можно представлять себе объект как ассоциативный массив, который отображает строку в значение, таким же образом, как обычный массив отображает число в значение. Используя такую запись, можно переписать triangle другим способом:
var triangle = new Object();
triangle['sideA'] = 3;
triangle['sideB'] = 4;
triangle['sideC'] = 5;
triangle['getArea'] = function ( a, b, c ) {
// возвращает площадь треугольника, используя формулу Герона
var semiperimeter = (a + b + c) / 2;
var calculation = semiperimeter * (semiperimeter - a) * (semiperimeter - b) * (semiperimeter - c);
return Math.sqrt( calculation );
}; // Обратите внимание на точку с запятой, она здесь обязательна
На первый взгляд это может показаться избыточным. Почему не использовать просто запись с точкой? Преимущество этого нового синтаксиса в том, что имя свойства не является жестко закодированным в программе. Можно использовать переменные для определения имен свойств, что означает, что можно создавать по-настоящему гибкие команды, которые делают различные вещи в зависимости от контекста. Например, можно создать функцию, которая сравнивает два объекта, чтобы проверить, не используют ли они общее свойство:
function isPropertyShared( objectA, objectB, propertyName ) {
if (
typeof objectA[ propertyName ] !== undefined
&&
typeof objectB[ propertyName ] !== undefined
) {
alert("Оба объекта имеют свойство с именем " + propertyName + "!");
}
}
Такую функцию было бы просто невозможно написать при базовом способе использования записи с точкой, так как потребуется явно написать имена свойств для проверки в коде программы. Такой синтаксис используется очень часто.
Примечание: Ассоциативный массив называется "hash" в Perl, "hashtable" в C#, "map" в C++, "hashmap" в Java, "dictionary" в Python, и т.д. Это очень мощная и фундаментальная концепция в программировании, и вы вполне можете быть с ней знакомы под другим именем.