Объекты в JavaScript
05.01.2016

Объекты в 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);  // true

Если нужно проверить только собственные свойства объекта, можно использовать метод hasOwnProperty():


console.log(cat.hasOwnProperty('color'));  // true
console.log(cat.hasOwnProperty('toString')); //false, т.к. свойство 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 возвращает истину, если удаление прошло успешно. И, как ни удивительно, что она также возвращает истину, если свойство не существует или не может быть удалено.