Объекты в JavaScript являются важным типом данных и представляют собой наборы пар ключ: значение. Значения могут быть представлены различными типами данных JavaScript. Чаще всего это строки, числа и логические данные true/fase
.
Все объекты JavaScript основаны на родительском конструкторе в виде класса Object
. Этот класс имеет множество полезных встроенных методов, позволяющих получать доступ к отдельным объектам и работать с ними напрямую. В отличие от методов массивов, которые работают с для экземплярами, т.е. с переменными класса Array, методы объекта используются при обращении к Object
, а в качестве параметра в методе указывается экземпляр объекта, например, Object.create(student)
, Object.keys(student)
. Такие методы называются статическими.
Давайте рассмотрим часть этих методов.
- Метод Object.create()
- Методы для преобразования свойств объекта в массив
- Метод Object.assign()
- Метод Object.freeze()
- Метод Object.seal()
Метод Object.create()
Метод Object.create()
предназначен для создания новых объектов и их привязки к прототипу существующего объекта. В случае создания пустого объекта используется выражение let obj = Object.create(null)
.
Однако намного удобнее создавать объект на основе уже существующего, меняя какие-либо его свойства или методы. Например, существует объект для описания некой вакансии. С помощью метода Object.create()
можно создать экземпляр объекта vacancy
и расширить его для описания разных объектов-вакансий.
Код примера.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | //Исходный объект const vacancy = { type: 'продавец', payment: 'почасовая', isAvailable: true, showInfo() { const available = this.isAvailable ? '<strong style="color: #20a010">доступна</strong> для подачи заявок' : 'в настоящее время <strong style="color: #d50d0d">не доступна</strong>'; document.write(`<p>Вакансия <strong>${this.type}</strong> подразумевает, что оплата будет ${this.payment}, и ${available}.</p>`); } }; // создаем объекты на основе существующего const mechanic = Object.create(vacancy); mechanic.type = "механик"; mechanic.showInfo(); const dancer = Object.create(vacancy); dancer.type = "танцовщица"; dancer.isAvailable = false; dancer.showInfo(); |
Вывод результата работы кода:
Для объекта mechanic
мы задали только одно свойство type
, но все остальные свойства и метод объекта vacancy
доступны через прототип. Во втором объекте мы уже изменили 2 свойства, и для обоих объектов вывели потом информацию методом showInfo()
.
Метод Object.create()
может быть полезен в случаях, когда нужно создать несколько однотипных объектов, причем он позволяет сократить код за счет минимального дублирования.
Методы для преобразования свойств объекта в массив
Свойства объекта можно перебрать и вывести с помощью цикла for ... in
, однако намного удобнее работать с методами массивов, которые помогут быстрее манипулировать данными в объекте.
Метод Object.keys()
Метод Object.keys()
создает массив, содержащий ключи объекта. Если нам необходимы именно ключи (наименование свойств объекта), то мы можем поместить их в массив ключей с помощью этого метода.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | let jobs = { 'Office Administrator': 'John Malik', Economist: 'Kayli Morton', 'Compliance and Governance Analyst': 'Luis Tempton', Translator: 'Julia Newton' } let jobNames = Object.keys(jobs); document.write(`<p>Массив ключей: ${jobNames.join(', ')}.</p>`); jobNames.forEach(key => document.write(`<p><i>${key}</i>: ${jobs[key]}.</p>`)); document.write(`<ol>`); for(let key of jobNames){ document.write(`<li><b>${key}</b>: ${jobs[key]}.</li>`); } document.write(`</ol>`); |
В том случае, когда нам надо вывести и ключи, и значения, мы можем использовать цикл for..of
или метод массива forEach()
, которые недоступны для объектов.
Результат:
Метод Object.values()
Метод Object.values()
создает массив, содержащий значения объекта. Например, с его помощью мы можем быстро подсчитать сумму, в которую нам обойдется список продуктов:
1 2 3 4 5 6 7 8 9 10 11 12 | const products = { potatoes: 3.39, milk: 1.09, grapes: 1.49, bread: 1.99, cheese: 2.49, }; let vals = Object.values(products); document.write(`<p>Массив значений: ${vals.join(', ')}.</p>`); let sum = vals.reduce((total, current) => total+current); document.write(`<p>Общая сумма: ${sum.toFixed(2)} €</p>`); |
В переменную vals
у нас попадают только цифры в виде массива. Затем с помощью метода массивов reduce
мы их можем быстро сложить.
Так сработает этот код:
Метод Object.entries()
Метод Object.entries()
создает вложенный массив пар ключ-значение для объекта.
Для предыдущего кода мы можем вызвать метод Object.entries()
и получим массив, внутри которого будет несколько элементов в виде двумерного массива
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | const products = { potatoes: 3.39, milk: 1.09, grapes: 1.49, bread: 1.99, cheese: 2.49, }; let entries = Object.entries(products); console.log(entries); //Вывод: /*[ ['potatoes', 3.39] ['milk', 1.09] ['grapes', 1.49] ['bread', 1.99] ['cheese', 2.49] ] */ for(let entry of entries){ document.write(`<p><i>${entry[0]}</i>: ${entry[1]} €.</p>`); } |
Здесь мы используем обращение entry[0]
для ключей объекта и entry[1]
для значений в цикле for ... of
.
Также мы можем использовать метод массивов forEach() для перебора элементов в полученном после использования метода Object.entries()
массиве, задавая параметры с помощью оператора деструктивного присваивания.
1 2 3 | document.write(`<ol>`); entries.forEach(([key, value]) => document.write(`<li><i>${key}</i>: ${value} €.</li>`)); document.write(`</ol>`); |
Результат:
Еще один пример касается вывода информации из массива объектов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | let countries = [ { name: 'Ukraine (Україна)', 'background-position': '-5175px 0', 'dial-code':"+380", code: 'ua' }, { name: 'Poland (Polska)', 'background-position': '-4031px 0', 'dial-code':"+48", code: 'pl' }, { name: 'Germany (Deutschland)', 'background-position': '-1269px 0', 'dial-code':"+49", code: 'de' }, { name: 'Czech Republic (Česká republika)', 'background-position': '-1247px 0', 'dial-code':"+420", code: 'cz' },{ name: 'Turkey (Türkiye)', 'background-position': '-5065px 0', 'dial-code':"+90", code: 'tr' }, { name: 'United States', 'background-position': '-5241px 0', 'dial-code':"+1", code: 'us' }, { name: 'Canada', 'background-position': '-834px 0', 'dial-code':"+1", code: 'ca' }, { name: 'United Kingdom', 'background-position': '-1775px 0', 'dial-code':"+44", code: 'gb' }, { name: 'France', 'background-position': '-1731px 0', 'dial-code':"+33", code: 'fr' }, { name: 'Italy (Italia)', 'background-position': '-2523px 0', 'dial-code':"+39", code: 'it' }, ] const dataTable = document.getElementById('dataTable'); let tableStr=""; countries.forEach(item => { let countryData = Object.entries(item); tableStr +=`<tr>`; countryData.forEach( ([key, value]) => { if(key === 'name') tableStr += `<td>${value}</td>`; else if(key === 'background-position') tableStr += `<td><div class="bg-flag" style="${key}: ${value}"></div></td>`; else tableStr +=`<td>${value}</td>` } ) tableStr +=`</tr>`; }) dataTable.lastElementChild.innerHTML = tableStr; |
Давайте посмотрим на работу кода:
See the Pen Object.keys() by Elen (@ambassador) on CodePen.
Object.entries()
возвращает только собственные свойства экземпляра объекта, а не свойства, унаследованные от прототипа. Однако в большинстве случаев этого достаточно.Метод Object.assign()
Метод Object.assign()
используется для копирования значений одного объекта в другой объект.
С помощью метода Object.assign()
мы можем объединить два объекта. Например, так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // 1-й объект const animal = { type: 'cat', name: 'Baddy' }; // 2-й объект const details = { age: 1.5, 'Favorite toy': 'mouse' }; // Объединяем объекты const pet = Object.assign(animal, details); console.log(pet); |
В результате получим один объект:
1 | {type: 'cat', name: 'Baddy', age: 1.5, Favorite toy: 'mouse'} |
То же самое можно получить, используя spread-оператор:
1 2 3 4 5 6 | const additional = { country: 'Canada', price: 300 } const petNew = {...pet, ...additional}; console.log(petNew); |
В консоли увидим такие данные:
1 2 3 4 5 6 7 8 | { "type": "cat", "name": "Baddy", "age": 1.5, "Favorite toy": "mouse", "country": "Canada", "price": 300 } |
Метод Object.freeze()
Метод Object.freeze()
предназначен для "замораживания" объекта, что предотвращает изменение свойств и значений объекта, а также добавление или удаление свойств объекта. То есть объект, созданный с помощью Object.freeze()
недоступен для изменений.
Например, таким образом можно защитить данные объекта-администратора от перезаписи.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | const admin = { email: 'admin@somesite.com', password: '$ecret_23Pass' }; // Замораживаем объект const adminNext = Object.freeze(admin); adminNext.password = 'add_Pass'; adminNext.IP = '196.27.54.12'; console.log(adminNext); //{email: 'admin@somesite.com', password: '$ecret_23Pass'} console.log(Object.isFrozen(admin)); //true console.log(Object.isFrozen(adminNext)); //true |
Как видно в консоли, к объекту не добавлено новое свойство, а пароль остался прежним.
Метод Object.isFrozen()
позволяет определить, "заморожен" ли объект, и возвращает логическое значение в виде true/false
.
Метод Object.seal()
Метод Object.seal()
предотвращает добавление новых свойств к объекту, но допускает изменение существующих свойств. Этот метод похож на метод Object.freeze()
с "половинной" функциональностью. В приведенном ниже коде мы опять пытаемся изменить пароль и добавить новое свойство. Однако мы можем только изменить уже существующее свойство.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | const user = { name: 'Vasiliy Pupkin', password: '12345' }; const user2 = Object.seal(user); user2.password = 'test-2_Test'; user2.online = true; console.log(user); //{name: 'Vasiliy Pupkin', password: 'test-2_Test'} console.log(Object.isFrozen(user)); //false console.log(Object.isFrozen(user2)); //false |
Как видно из консоли, пароль изменился, а новое свойство online
не было добавлено.