Объекты Javascript в примерах

Объекты (они же - ассоциативные массивы, хэши) и работа с ними в Javascript - реализованы не так, как в большинстве языков. С этим связано много ошибок и непоняток.

В этой статье описаны базовые свойства объектов javascript, создание и изменение, перечисление свойств и т.п.

Объект в javascript представляет собой обычный ассоциативный массив или, иначе говоря, "хэш". Он хранит любые соответствия "ключ => значение" и имеет несколько стандартных методов.

Метод объекта в javascript - это просто функция, которая добавлена в ассоциативный массив. Далее - подробнее.

Создание и работа со свойствами

Создание объекта

Следующие два варианта создания объекта эквивалентны:

// эквивалентные записи
var o = new Object()
var o = {}

Добавление свойств

Есть два синтаксиса добавления свойств в объект. Первый - точка, второй - квадратные скобки:

// эквивалентные записи
o.test = 5
o["test"] = 5

Квадратные скобки используются в основном, когда название свойства находится в переменной:

var name = 'test'
o[name] = 5

Здесь имя свойства "test" является ключом в ассоциативном массиве, по которому лежит значение 5.

Доступ к свойствам

Доступ к свойству осуществляется точно так же:

alert(o.test)
alert(o['test'])

Если у объекта нет такого свойства, то результат будет 'undefined'

var o = {}
alert(o.nosuchkey)   // => undefined

Никакой ошибки при обращении по несуществующему свойству не будет, просто вернется специальное значение undefined.

Проверка глобальной переменной

В javascript нельзя проверить существование глобальной переменной простым if:

if (x) { ... }

Если x не определен, то конструкция if (x) вызовет ошибку javascript.

Распространенное решение - использовать typeof:

if (typeof x != 'undefined') { ... }  // или typeof(x)

Однако зная, что глобальная переменная в javascript - всего лишь свойство объекта window - мы можем записать проще:

if (window.x) { ... }   // правильный аналог if(x)
// или 
if (window.x !== undefined) // аналог typeof x ..

Все свойства объектов - public, т.е при определении свойства никак нельзя ограничить доступ к свойству. В javascript есть специальные выверты для создания private свойств, связанные с замыканиями. Они рассмотрены вместе с наследованием объектов.

Удаление свойств

Удаляет свойство оператор delete:

o.test = 5
delete o.test
o['bla'] = true

Расширенное создание

Свойства можно указывать непосредственно при создании объекта, через список в фигурных скобках вида {..., ключ : значение, ...}:

var o = { 
    test: 5,  
    bla: true 
}

Получившийся объект можно изобразить так:

javascript object

Методы объектов

Добавление метода

Как и в других языках, у объектов javascript есть методы.

Например, создадим объект rabbit с методом run

var rabbit = {}
rabbit.run = function(n) {
    alert("Пробежал "+n+" метров!")
}

Добавление метода в объект - просто присвоение функции function(n) { ... } свойству rabbit.run.

Теперь можно запускать

var rabbit = {}
rabbit.run = function(n) {
    alert("Пробежал "+n+" метров!")
}
rabbit.run(5)  // Пробежал 5 метров
rabbit.run(7)  // Пробежал 7 метров

Здесь не идет речь о классах, создании экземпляров и тому подобном. Просто - в любой объект в любое время можно добавить новый метод или удалить существующий.

Javascript - очень динамический язык, не правда ли?

Доступ к объекту из метода

Обычно хочется, чтобы метод не просто вызывался из объекта, но имел доступ к самому объекту, мог менять находящиеся в нем данные.

Для этого используется ключевое слово this:

for(var key in obj) {
… obj[key] …
}
В отличие от многих языков, this никак не привязано к объекту, а обозначает просто объект, вызвавший функцию.

Например,

function this1() {
	var vasya = { name:'Вася' }
	var petya = { name:'Петя' }

	sayName  = function() {
		alert("Я - "+ (this.name ? this.name : 'безымянный') )
	}

	vasya.sayName = sayName
	
	// один и тот же метод в двух объектах
	petya.sayName = vasya.sayName
	
	// тут - this будет petya
	petya.sayName()  // Я - Петя
	
	// тут - this будет vasya
	vasya.sayName()  // Я - Вася
	
	// а тут - вызывается метод глобального объекта window, у которого нет имени
	sayName() // Я - безымянный
}

Запустить this1()

Более подробно о том, как работает this можно почитать в этой статье.

Перебор свойств объекта

Для перебора всех свойств объекта используется специальный вид конструкции for, for..in:

for(var key in object) {
  // key - название свойства
  // object[key] - значение свойства
  ...
}

Например,

var o = {a:5, b:true}
for (var key in o) {
    alert(key+':'+o[key])
}

Запустить

Это уже выходит за рамки текущей статьи, но вообще - существует еще одна форма перебора свойств, которая более надежна, особенно если используется библиотека типа prototype.

for(prop in object) {
    if (!object.hasOwnProperty(prop)) continue
    //...
}

Эта форма отфильтровывает свойства, которые принадлежат не самому объекту, а его прототипу. Поэтому она работает, даже если в прототип Object добавлены новые свойства.

Более элегантный вариант записи:

for(prop in object) if (object.hasOwnProperty(prop)) {
    //...
}