diff options
Diffstat (limited to 'files/uk/web/javascript/reference/global_objects/object/freeze/index.html')
| -rw-r--r-- | files/uk/web/javascript/reference/global_objects/object/freeze/index.html | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/files/uk/web/javascript/reference/global_objects/object/freeze/index.html b/files/uk/web/javascript/reference/global_objects/object/freeze/index.html new file mode 100644 index 0000000000..86269bfda1 --- /dev/null +++ b/files/uk/web/javascript/reference/global_objects/object/freeze/index.html @@ -0,0 +1,256 @@ +--- +title: Object.freeze() +slug: Web/JavaScript/Reference/Global_Objects/Object/freeze +tags: + - ECMAScript 5 + - JavaScript + - Object + - freeze + - Об'єкт + - заморожування + - метод +translation_of: Web/JavaScript/Reference/Global_Objects/Object/freeze +--- +<div>{{JSRef}}</div> + +<p>Метод <code><strong>Object.freeze()</strong></code> <strong>заморожує</strong> об'єкт. Заморожений об'єкт не може бути змінений; заморожування запобігає додаванню нових властивостей, видаленню існуючих властивостей, зміні доступності існуючих властивостей для переліку, налаштування та запису, а також зміні значень існуючих властивостей. Також, заморожування об'єкта не дає змінювати його прототип. Метод <code>freeze()</code> повертає той самий об'єкт, що був переданий.</p> + +<div>{{EmbedInteractiveExample("pages/js/object-freeze.html")}}</div> + + + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox"><code>Object.freeze(<var>obj</var>)</code></pre> + +<h3 id="Параметри">Параметри</h3> + +<dl> + <dt><code>obj</code></dt> + <dd>Об'єкт, який потрібно заморозити.</dd> +</dl> + +<h3 id="Значення_що_повертається">Значення, що повертається</h3> + +<p>Об'єкт, переданий у функцію.</p> + +<h2 id="Опис">Опис</h2> + +<p>Ніщо не може бути додане чи видалене з набору властивостей замороженого об'єкта. Будь-яка спроба це зробити зазнає невдачі, або непомітно, або з викиданням винятку {{jsxref("TypeError")}} (найчастіше, але не винятково, у {{jsxref("Strict_mode", "строгому режимі", "", 1)}}).</p> + +<p>Для властивостей-значень замороженого об'єкта не можна змінювати значення, атрибутам writable та configurable встановлено значення false. Властивості-аксесори (гетери та сетери) працюють, як і раніше (і так само створюють ілюзію, що ви міняєте значення). Зауважте, що значення, які є об'єктами, можна змінювати, якщо тільки вони теж не заморожені. Масив, як об'єкт, може бути заморожений; після цього його елементи не можуть бути змінені, і жоден елемент не може бути доданий чи видалений з масиву.</p> + +<p><code>freeze()</code> повертає той самий об'єкт, який був переданий у функцію. Він <em>не створює</em> заморожену копію.</p> + +<h2 id="Приклади">Приклади</h2> + +<h3 id="Заморожування_обєктів">Заморожування об'єктів</h3> + +<pre class="brush: js">var obj = { + prop: function() {}, + foo: 'ква' +}; + +// До заморожування: можна додавати нові властивості, +// а також змінювати чи видаляти існуючі властивості +obj.foo = 'мяв'; +obj.lumpy = 'гав'; +delete obj.prop; + +// Заморожуємо. +var o = Object.freeze(obj); + +// Повертається той самий об'єкт, який ми передали. +o === obj; // true + +// Об'єкт заморожено. +Object.isFrozen(obj); // === true + +// Тепер будь-які зміни не працюють +obj.foo = 'му'; // нічого не робить +// непомітно не додає властивість +obj.quaxxor = 'весела качка'; + +// У строгому режимі такі спроби викинуть винятки TypeError +function fail(){ + 'use strict'; + obj.foo = 'бум'; // викидає TypeError + delete obj.foo; // викидає TypeError + delete obj.quaxxor; // повертає true, бо атрибут 'quaxxor' не був доданий + obj.sparky = 'фух'; // викидає TypeError +} + +fail(); + +// Спроба внести зміни через Object.defineProperty; +// обидві інструкції викинуть TypeError. +Object.defineProperty(obj, 'ohai', { value: 17 }); +Object.defineProperty(obj, 'foo', { value: 'уф' }); + +// Також неможливо змінити прототип +// обидві наведені інструкції викинуть TypeError. +Object.setPrototypeOf(obj, { x: 20 }) +obj.__proto__ = { x: 20 } +</pre> + +<h3 id="Заморожування_масивів">Заморожування масивів</h3> + +<pre class="brush: js">let a = [0]; +Object.freeze(a); // Тепер масив не можна змінювати. + +a[0]=1; // непомітно не спрацьовує +a.push(2); // непомітно не спрацьовує + +// У строгому режимі такі спроби викидатимуть TypeError +function fail() { + "use strict" + a[0] = 1; + a.push(2); +} + +fail();</pre> + +<p>Заморожений об'єкт є <em>незмінним</em>. Однак, він не обов'язково є <em>константою</em>. Наступний приклад демонструє, що заморожений об'єкт не є константою (неглибока заморозка).</p> + +<pre class="brush: js">obj1 = { + internal: {} +}; + +Object.freeze(obj1); +obj1.internal.a = 'значенняА'; + +obj1.internal.a // 'значенняА'</pre> + +<p>Щоб об'єкт був константою, все дерево посилань (прямі та непрямі посилання на інші об'єкти) має посилатися тільки на незмінні заморожені об'єкти. Заморожений об'єкт називається незмінним, бо <em>стан </em>об'єкта (значення та посилання на інші об'єкти) всередині всього об'єкта є зафіксованим. Зауважте, що рядки, числа та булеві значення завжди незмінні, і що функції та масиви є об'єктами.</p> + +<h4 id="Що_таке_неглибока_заморозка">Що таке "неглибока заморозка"?</h4> + +<p>Результат виклику <code>Object.freeze(<var>object</var>)</code> стосується лише безпосередніх властивостей об'єкта <code>object</code>, і запобігає додаванню, видаленню чи переприсвоєнню значень властивостей у майбутньому <em>тільки</em> на об'єкті <code>object</code>. Якщо ж значеннями цих властивостей є інші об'єкти, ці об'єкти не заморожуються, і на них можуть здійснюватись операції додавання, видалення чи переприсвоєння значень властивостей.</p> + +<pre class="brush: js">var employee = { + name: "Дмитро", + designation: "Розробник", + address: { + street: "Городоцька", + city: "Львів" + } +}; + +Object.freeze(employee); + +employee.name = "Вова"; // непомітно не спрацює у нестрогому режимі +employee.address.city = "Винники"; // атрибути дочірнього об'єкта можна змінювати + +console.log(employee.address.city) // Виведе: "Винники" +</pre> + +<p>Щоб зробити об'єкт незмінним, рекурсивно заморозьте кожну властивість типу object (глибока заморозка). Застосовуйте свій шаблон для кожного конкретного елементу, коли знаєте, що об'єкт не містить {{interwiki("wikipedia", "Цикл_(теорія_графів)", "циклів")}} у дереві посилань, інакше запуститься нескінченний цикл. Покращенням функції <code>deepFreeze()</code> була б внутрішня функція, яка отримує аргументом шлях (наприклад, масив), щоб можна було заборонити рекурсивний виклик <code>deepFreeze()</code>, коли об'єкт знаходиться у процесі перетворення на незмінний об'єкт. Ви все одно ризикуєте заморозити об'єкт, який не треба заморожувати, наприклад, [window].</p> + +<pre class="brush: js">function deepFreeze(object) { + + // Отримати імена властивостей, визначених на об'єкті + var propNames = Object.getOwnPropertyNames(object); + + // Заморозити властивості перед тим, як заморожувати себе + + for (let name of propNames) { + let value = object[name]; + + object[name] = value && typeof value === "object" ? + deepFreeze(value) : value; + } + + return Object.freeze(object); +} + +var obj2 = { + internal: { + a: null + } +}; + +deepFreeze(obj2); + +obj2.internal.a = 'новеЗначення'; // непомітно не спрацює у нестрогому режимі +obj2.internal.a; // null +</pre> + +<h2 id="Примітки_щодо_використання">Примітки щодо використання</h2> + +<p>У ES5, якщо аргументом цього методу є не об'єкт (примітив), він спричинить помилку {{jsxref("TypeError")}}. У ES2015 аргумент, який не є об'єктом, сприйматиметься як звичайний заморожений об'єкт, і буде просто повернений.</p> + +<pre class="brush: js">> Object.freeze(1) +TypeError: 1 is not an object // код ES5 + +> Object.freeze(1) +1 // код ES2015 +</pre> + +<p>Об'єкти {{domxref("ArrayBufferView")}} з елементами спричинять помилку {{jsxref("TypeError")}}, оскільки вони є представленнями ділянок пам'яті, і неодмінно спричинять інші можливі проблеми:</p> + +<pre class="brush: js">> Object.freeze(new Uint8Array(0)) // Немає елементів +Uint8Array [] + +> Object.freeze(new Uint8Array(1)) // Має елементи +TypeError: Cannot freeze array buffer views with elements + +> Object.freeze(new DataView(new ArrayBuffer(32))) // Немає елементів +DataView {} + +> Object.freeze(new Float64Array(new ArrayBuffer(64), 63, 0)) // Немає елементів +Float64Array [] + +> Object.freeze(new Float64Array(new ArrayBuffer(64), 32, 2)) // Має елементи +TypeError: Cannot freeze array buffer views with elements +</pre> + +<p>Зауважте наступне; оскільки три стандартні властивості (<code>buf.byteLength</code>, <code>buf.byteOffset</code> та <code>buf.buffer</code>) є доступними лише для читання (так само, як у {{jsxref("ArrayBuffer")}} чи у {{jsxref("SharedArrayBuffer")}}), немає причини намагатися заморожувати ці властивості.</p> + +<h3 id="Порівняння_з_Object.seal">Порівняння з <code>Object.seal()</code></h3> + +<p>Об'єкти, запечатані через {{jsxref("Object.seal()")}}, дозволяють змінювати свої існуючі властивості. Властивості об'єктів, заморожених через <code>Object.freeze()</code>, стають незмінними.</p> + +<h2 id="Специфікації">Специфікації</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Специфікація</th> + <th scope="col">Статус</th> + <th scope="col">Коментар</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ES5.1', '#sec-15.2.3.9', 'Object.freeze')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td>Початкове визначення. Реалізоване у JavaScript 1.8.5.</td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-object.freeze', 'Object.freeze')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-object.freeze', 'Object.freeze')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Сумісність_з_веб-переглядачами">Сумісність з веб-переглядачами</h2> + + + +<p>{{Compat("javascript.builtins.Object.freeze")}}</p> + +<h2 id="Див._також">Див. також</h2> + +<ul> + <li>{{jsxref("Object.isFrozen()")}}</li> + <li>{{jsxref("Object.preventExtensions()")}}</li> + <li>{{jsxref("Object.isExtensible()")}}</li> + <li>{{jsxref("Object.seal()")}}</li> + <li>{{jsxref("Object.isSealed()")}}</li> +</ul> |
