04. Объекты
Плюсы и минусы JavaScript
![]() |
В JavaScript работает практически все, что не напишешь! В этом плюс языка — его гибкость, базирующаяся на контекстно зависимой семантике. Но в этом и минус, особенно для новичков: часто код работает совсем не так, как предполагает начинающий писатель. |
Пример 1
var x = "0";
if (x) x++; // x равен 1
Пример 2
var x = "0";
if (-x) x++; // x равен "0"
В объектно-ориентированных языках в понятии объекта есть «магическое» начало, в языке C++ — это ключевое слово class, при помощи которого создается «документация» на объекты.
В функции-конструкторе JavaScript нет никакой магии — это обычная функция, как и все остальные. Особый смысл функция получает только в сочетания с оператором new, который создаёт пустой объект и передаёт ссылку на него в качестве неявного аргумента this:
var rect = new Rectangle(2,3); // Создан объект rect класса Rectangle
Этот код работает следующим образом:
- Оператор new создает пустой объект {} и передает ссылку на него в функцию Rectangle.
- Функция Rectangle создает в пустом объекте свойства width и height и присваивает этим свойствам соответственно значения 2 и 3.
А что будет, если мы опустим оператор new?:
var rect = Rectangle(2,3);
Функция Rectangle не возвращает никакого значения, поэтому переменная rect после такого присваивания сохранит значение undefined (как при простом описании var rect), но возникнут другие интересные последствия.
Ключевое слово this в Rectangle теперь относится к глобальному объекту window. Значит, функция Rectangle создаёт в этом объекте свойства width и height и присваивает этим свойствам соответственно значения 2 и 3. В этом легко убедиться, запустив следующий код:
function Rectangle(width,height) // Функция-конструктор
{
this.width = width;
this.height = height;
}
var rect = Rectangle(2,3);
alert(rect); // undefined
alert(window.width); // 2
alert(window.height); // 3
При работе с глобальным объектом window ссылку на него можно опускать, поэтому:
- window.width — это то же самое, что просто width;
- window.height — это то же самое, что просто height.
Функция-конструктор, как правило, не возвращает никакого значения. Но это обычная функция. Ничто не мешает в ней записать инструкцию return:
function Rectangle(width,height)
{
this.width = width;
this.height = height;
return width + height;
}
var rect = Rectangle(2,3);
alert(rect); // 5
alert(width); // 2
alert(height); // 3
Если конструктор возвращает значение элементарного типа и используется в контексте оператора new, возвращаемое значение просто теряется.
function Rectangle(width,height)
{
this.width = width;
this.height = height;
return width + height;
}
var rect = new Rectangle(2,3);
alert(rect.width); // 2
alert(rect.height); // 3
alert(window.width); // undefined
alert(window.height); // undefined
А если конструктор возвращает объект, то этот объект становится значением выражения new конструктор.
function Rectangle(width,height) // Функция-конструктор
{
this.width = width;
this.height = height;
return {x:20,y:30};
}
var rect = new Rectangle(2,3);
alert(rect.width); // undefined
alert(rect.height); // undefined
alert(rect.x); // 20
alert(rect.y); // 30
alert(window.width); // undefined
alert(window.height); // undefined