В прошлой статье мы выяснили, что не всё в JavaScript является объектом, и все данные разделяются на примитивы и объекты. В этой статье рассмотрим способы создания объектов, что такое методы, свойства, как их присваивать, способы итерации по всем свойствам объектов и использование ключевого слова this
.
Обычно создание объекта выглядит следующим образом:
const obj = {};
После создания объекта в него можно добавлять любые свойства и методы двумя способами:
const obj = {};
// Первый способ добавления свойств и методов к объекту
obj.prop = 'this is object property';
obj.method = function() {
return 'this is object method';
};
// Второй способ добавления свойств и методов к объекту
obj['prop2'] = 'this is second object property';
obj['method2'] = function() {
return 'this is second object method';
};
На самом деле, нет никаких причин разделять содержимое объекта на две разные категории (свойства и методы). Технически, всё, что содержится в объекте называется его свойствами. В этом можно убедиться создав объект, в который будут записаны уже существующие данные:
const log = function(message) { console.log(message); };
const nums = [10, 20, 30, 40, 50];
const obj = {};
obj.log = log;
obj.nums = nums;
Таким образом, каждое свойство объекта просто ссылается на определенные данные, в независимости от того, что они содержат: примитивы, другие объекты, массивы или функции. Тем не менее, свойства объектов, которые ссылаются на любую функцию, в том числе и анонимную, принято называть методами, хотя подобные свойства ничем не отличаются от всех остальных.
Добавлять методы и свойства в объекты можно прямо при их создании:
const obj = {
prop: 'this is property',
method: function() {
return 'this is method';
}
};
Получить записанные в объект методы и свойства можно также получить двумя способами:
const obj = {
prop: 'this is property',
method: function() {
return 'this is method';
}
};
obj.prop; // "this is property"
obj.method(); // "this is method"
obj['prop']; // "this is property"
obj['method'](); // "this is method"
Итак, вы создали объект, в котором есть несколько свойств. Теперь вы хотите последовательно выполнять с ними операции. Для подобных случаев есть цикл for .. in
:
const employee = {
name: 'John',
phone: '+7 (765) 000-98-34',
company: 'Opera Software',
email: '[email protected]',
duties: ['Frontend', 'Optimization', 'Testing']
};
for (let key in employee) {
console.log(key + ': ' + employee[key]);
}
// Выведет
// name: John
// phone: +7 (765) 000-98-34
// company: Opera Software
// email: [email protected]
// duties: Frontend, Optimization, Testing
Любой объект условно можно разделить на две части: ключи и значения. Для объекта employee
ключами будут: name
, phone
, company
, email
и duties
, а значениями: 'John'
, '+7 (765) 000-98-34'
, 'Opera Software'
, '[email protected]'
и ['Frontend', 'Optimization', 'Testing']
. При использовании цикла for .. in
задаётся переменная, которую обычно называют key
. С помощью этой переменной в теле цикла можно последовательно получить каждый ключ из итерируемого объекта. Чтобы получить соответствующее ключу значение в теле цикла всегда следует использовать форму записи obj[key]
.
Почему нельзя использовать форму obj.key
? Всё просто. Используя такую запись вы подразумеваете, что хотите получить значение свойства key
итерируемого объекта, а не значение соответствующее данному ключу.
const employee = {
name: 'John',
phone: '+7 (765) 000-98-34',
company: 'Opera Software',
email: '[email protected]',
key: 'this is key property in object'
};
for (let key in employee) {
console.log(key + ': ' + employee.key);
}
// Выведет
// name: this is key property in object
// phone: this is key property in object
// company: this is key property in object
// email: this is key property in object
// key: this is key property in object
Другой способ итерации по объекту — заранее получить все ключи объекта в виде массива и провести итерацию с помощью любого перебирающего метода массивов.
Для того, чтобы получить массив ключей из объекта, нужно воспользоваться функцией Object.keys
:
const employee = {
name: 'John',
phone: '+7 (765) 000-98-34',
company: 'Opera Software',
email: '[email protected]'
};
const keys = Object.keys(employee);
console.log(keys); // ["name","phone","company","email","key"]
После того, как желаемый массив был получен, его можно перебрать, например, с помощью метода forEach
:
keys.forEach(function(key) {
console.log(key + ': ' + employee[key]);
});
// Выведет
// name: John
// phone: +7 (765) 000-98-34
// company: Opera Software
// email: [email protected]
К сожалению подобным образом получить массив всех значений объекта не получится: функции Object.values()
не существует. Но её легко можно заменить методом map
в паре с Object.keys()
:
const values = keys.map(function(key) {
return employee[key];
});
console.log(values); // ["John","+7 (765) 000-98-34","Opera Software","[email protected]"]
При работе с объектами очень часто бывает необходимо получить ссылку на сам объект внутри метода. Для таких целей конечно можно использовать имя самого объекта:
const obj = {
a: 10,
b: function (num) {
console.log(obj.a + num);
}
};
obj.b(10); // 20
Тем не менее, подобный способ накладывает на себя очень неприятные ограничения, которые будут подробно рассмотрены в следующей статье. Например, нельзя задать контекст выполнения метода с помощью call
или apply
.
Более правильно для всех методов объекта использовать ключевое слово this
. Переписать пример, приведенный выше можно следующим образом:
const obj = {
a: 10,
b: function (num) {
console.log(this.a + num);
}
};
obj.b(100); // 110
this
всегда содержит ссылку на объект, в котором находится. В данном примере this
ссылается на объект obj
.