Объекты в JavaScript
Объекты — это единственный составной тип данных в JavaScript, кроме объектов существует еще пять примитивных типов данных: Number, String, Boolean, Undefined, и Null.
Определение объекта в JavaScript
Объект представляет собой неупорядоченный набор набор пар вида «ключ-значение». Каждая такая пара называется свойством объекта (функции называются методами), каждое свойство должно иметь уникальное имя, которое может быть строкой или числом. Значение свойства может быть любым: как значением простого типа, так и другим объектом.
Простой пример объекта в JavaScript:
var person = {
firstName: 'Frank',
lastName: 'Johnson'
};
Объект person имеет два свойства: firstName и lastName, которые, соответственно, имеют значения 'Frank' и 'Johnson'.
Главное отличие объектов от других типов данных заключается в том, что все операции с ними осуществляются по ссылке.
Сначала рассмотрим пример с примитивным типом данных:
// Операции по строками в JavaScript осуществляются по значению
var person1 = 'Nick';
// переменной person2 присваивается значение переменной person1
var person2 = person1;
person1 = 'John'; // изменяется значени е переменной person1
console.log(person2); // Nick
console.log(person1); // John
А теперь сравним его с аналогичным примером с объектами:
var person1 = { name: 'Nick' };
var person2 = person1;
person1.name = 'John';
console.log(person2.name); // John
console.log(person1.name); // John
В первом примере мы сначала присвоили переменной person1 значение переменной person2, а потом изменили person1. Мы убедились, что значение переменной person2 при этом не изменилось. Во втором же примере значение person2 также изменилось после того, как мы изменили person1. Это произошло из-за того, что присваивание объектов осуществляется по ссылке, т.е. person2 мы присвоили не значение person1, а ссылку на тот же объект, на который ссылается person1.
Каждое свойство объекта помимо имени и значения, имеет также три атрибута, каждый из которых имеет значение true по умолчанию:
- ?сonfigurable — данный атрибут определяет, доступно ли данное свойство для настройки: может ли оно быть изменено или удалено.
- enumerable — данный атрибут определяет, будет ли это свойство возвращено в циклах for/in.
- writable — данный атрибут определяет доступность свойства для записи.
Методы для работы (чтения и записи) с атрибутами свойств предусмотрены в стандарте ECMAScript 5, мы поговорим о них подробнее.
Создание объектов
В JavaScript существует три способа создания объектов: с помощью литерала объекта, с помощью конструктора Object и с помощью метода Object.create (последний способ предусмотрен только в стандарте ECMAScript 5).
Литералы объектов
Наиболее распространенный и, на самом деле, самый простой способ создания объекта — использование литерала объекта. Литерал объекта представляет собой фигурные скобки, внутри которых через запятую перечислены свойства:
// Пример пустого объекта
var emptyObject = {};
// Объект, имеющий свойства
var cat = {
color: 'gray',
age: 2,
say: function() {
console.log('Miu miu');
}
}
Конструктор Object
Второй способ создания объектов в JavaScript — использование конструктора Object:
var cat = new Object();
cat.color = 'gray';
cat.age = 2;
cat.say = function() {
console.log('Miu miu');
}
Кроме конструктора Object существует еще несколько встроенных конструкторов, например, Date, Array, RegExp и т.д.
Помимо встроенных конструкторов, JavaScript позволяет определять собственные функции-конструкторы и инициализировать объекты с помощью оператора new. Об этом мы поговорим в отдельной статье.
Метод Object.create()
В ECMAScript 5, кроме литералов объекта и конструктора Object, существует еще один способ создания объектов — с помощью метода Object.create(). Этот метод принимает один обязательный параметр — прототип создаваемого объекта, и второй необязательный — список свойств объекта.
Чтобы создать объект без прототипа, можно вызвать метод Object.create() c параметром null. Т.к. прототипом любого объекта при создании его с помощью литерала объекта или конструктора Object является Object.prototype, создать «обычный» объект можно с помощью Object.create(Object.prototype).
Рассмотрим примеры:
// Создание объекта, не имеющего прототипа
var emptyObject = Object.create(null);
console.log(emptyObject);
// Объект car наследует свойства wheels и speed
var car = Object.create({
wheels: 4,
speed: 100
});
console.log(car);
// Пустой объект с прототипом Object.prototype (аналог new Object() или {})
var myObject = Object.create(Object.prototype);
console.log(myObject);
Доступ к свойствам объекта
Получить значение свойства объекта можно, указав имя свойства через точку:
console.log(cat.color);
Или указав имя свойства в квадратных скобках:
console.log(cat[color]);
Второй способ является более гибким. Через точку можно указать только строковое имя свойства, в качестве имени свойства в квадратных скобках может быть число, вычисляемое значение или переменная.
Если мы пытаемся обратиться к свойству объекта, которого не существует — будет возвращено значение undefined. Однако попытка получить свойство значения null или undefined вызовет ошибку.
Объект имеет как собственные свойства (определенные в нем), так и унаследованные (определенные в цепочке прототипов). Проверить, имеет ли объект определенное свойство (собственное или унаследованное), можно с помощью оператора in:
// Создание объекта
var cat = { color: 'gray' };
// Проверяем, существует ли свойство 'color'
console.log('color' in cat); // true
// Проверяем, существует ли свойство 'name'
console.log('name' in cat); // false
// Проверяем, существует ли свойство toString (существует с прототипе Object.prototype)
console.log('toString' in cat); //
Если нужно проверить только собственные свойства объекта, можно использовать метод hasOwnProperty():
console.log(cat.hasOwnProperty('color')); // true
console.log(cat.hasOwnProperty('toString'));
Также получить свойства объекта можно в цикле:
var person = {
name: 'John',
lastName: 'Smith',
age: 32
};
for (var item in person) {
console.log(item);
}
/* Получим:
name
lastName
age
*/
Чтобы удалить свойство объекта, можно воспользоваться оператором delete. Нельзя удалить унаследованное свойство, а также свойство, имеющее атрибут configurable равное false. Наследуемое свойство необходимо удалять у объекта-прототипа. Кроме того, нельзя удалить свойства глобального объекта, которые были объявлены с ключевым словом var.
Оператор delete возвращает истину, если удаление прошло успешно. И, как ни удивительно, что она также возвращает истину, если свойство не существует или не может быть удалено.