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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
|
---
title: Оператор delete
slug: Web/JavaScript/Reference/Operators/delete
tags:
- JavaScript
- Object
- delete
- Властивість
- Оператор
- керування пам'яттю
translation_of: Web/JavaScript/Reference/Operators/delete
---
<div>{{jsSidebar("Operators")}}</div>
<p><span class="seoSummary">Оператор JavaScript <strong><code>delete</code></strong> видаляє властивість об'єкта. Якщо на цю властивість більше немає посилань, пам'ять під неї зрештою звільняється автоматично.</span></p>
<div>{{EmbedInteractiveExample("pages/js/expressions-deleteoperator.html")}}</div>
<h2 id="Синтаксис">Синтаксис</h2>
<pre class="syntaxbox">delete <em>вираз</em> </pre>
<p>де <em>вираз</em> має вертати посилання на <a href="/uk/docs/Glossary/property/JavaScript">властивість</a>, наприклад:</p>
<pre class="syntaxbox">delete <em>object.property</em>
delete <em>object</em>['<em>property</em>']
</pre>
<h3 id="Параметри">Параметри</h3>
<dl>
<dt><code>object</code></dt>
<dd>Ім'я об'єкта, чи вираз, що повертає цей об'єкт.</dd>
<dt><code>property</code></dt>
<dd>Властивість, яку треба видалити.</dd>
</dl>
<h3 id="Значення_що_повертається">Значення, що повертається</h3>
<p>Завжди <code>true</code>, окрім випадків, коли властивість є <a href="/uk/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty">особистою</a> властивістю, <a href="/uk/docs/Web/JavaScript/Reference/Errors/Cant_delete">недоступною для налаштування</a>, в цьому випадку у нестрогому режимі повертається <code>false</code>.</p>
<h3 id="Винятки">Винятки</h3>
<p>Викидає {{jsxref("TypeError")}} у <a href="/uk/docs/Web/JavaScript/Reference/Strict_mode">строгому режимі</a>, якщо властивість є особистою властивістю, недоступною для налаштування.</p>
<h2 id="Опис">Опис</h2>
<p>Попри розповсюджену думку, оператор <code>delete</code> не має <strong>нічого</strong> спільного з прямим вивільненням пам'яті. Керування пам'яттю відбувається опосередковано через розривання посилань. Більше інформації дивіться у статті <a href="/uk/docs/Web/JavaScript/Memory_Management">Керування пам'яттю</a>.</p>
<p>Оператор <code><strong>delete</strong></code> видаляє задану властивість з об'єкта. В разі успішного видалення, він поверне <code>true</code>, інакше поверне <code>false</code>. Однак, важливо враховувати наступні сценарії:</p>
<ul>
<li>Якщо властивість, яку ви намагаєтесь видалити, не існує, <code>delete</code> не матиме жодного ефекту та поверне <code>true</code></li>
<li>Якщо властивість з таким самим ім'ям існує у ланцюзі прототипів об'єкта, тоді, після видалення, об'єкт використовуватиме властивість з ланцюжка прототипів (іншими словами, <code>delete</code> має ефект лише для особистих властивостей).</li>
<li>Будь-яка властивість, оголошена через {{jsxref("Statements/var","var")}}, не може бути видалена з глобальної області видимості чи з області видимості функції.
<ul>
<li>Таким чином, <code>delete</code> не може видаляти функції у глобальній області видимості (незалежно від того, чи є вони оголошеннями функції, чи функціональними виразами).</li>
<li>Функції, які є частиною об'єкта (не є частиною глобальної області видимості), можуть бути видалені оператором <code>delete</code>.</li>
</ul>
</li>
<li>Будь-яка властивість, оголошена через {{jsxref("Statements/let","let")}} або {{jsxref("Statements/const","const")}}, не може бути видалена з області видимості, всередині якої вона була оголошена.</li>
<li>Властивості, недоступні для налаштування, не можуть бути видалені. Це також стосується властивостей вбудованих об'єктів, таких як {{jsxref("Math")}}, {{jsxref("Array")}}, {{jsxref("Object")}}, та властивостей, які були створені як недоступні для налаштування за допомогою методів на кшталт {{jsxref("Object.defineProperty()")}}.</li>
</ul>
<p>Наступний фрагмент надає простий приклад:</p>
<pre class="brush: js">var Employee = {
age: 28,
name: 'абв',
designation: 'розробник'
}
console.log(delete Employee.name); // вертає true
console.log(delete Employee.age); // вертає true
// При спробі видалити властивість, яка не існує,
// повертається true
console.log(delete Employee.salary); // вертає true
</pre>
<h3 id="Властивості_недоступні_для_налаштування">Властивості, недоступні для налаштування</h3>
<p>Коли властивість позначена як недоступна для налаштування, <code>delete</code> не матиме жодного ефекту та поверне <code>false</code>. У строгому режимі це спричинить помилку <code>TypeError</code>.</p>
<pre class="brush: js">var Employee = {};
Object.defineProperty(Employee, 'name', {configurable: false});
console.log(delete Employee.name); // вертає false
</pre>
<p>{{jsxref("Statements/var","var")}}, {{jsxref("Statements/let","let")}} та {{jsxref("Statements/const","const")}} створюють властивості, недоступні для налаштування, які не можуть бути видалені оператором <code>delete</code>:</p>
<pre class="brush: js">var nameOther = 'XYZ';
// Ми можемо звернутися до цієї глобальної властивості так:
Object.getOwnPropertyDescriptor(window, 'nameOther');
// виведе: Object {value: "XYZ",
// writable: true,
// enumerable: true,
// <strong>configurable: false</strong>}
// Оскільки "nameOther" додана за допомогою ключового
// слова var, вона позначена як недоступна для налаштування
delete nameOther; // вертає false</pre>
<p>У строгому режимі це спричинило б виняток.</p>
<h3 id="Строгий_режим_проти_нестрогого_режиму">Строгий режим проти нестрогого режиму</h3>
<p>У строгому режимі, якщо <code>delete</code> використовується на прямому посиланні на змінну, аргумент функції чи ім'я функції, це викине {{jsxref("SyntaxError")}}<strong>.</strong></p>
<p>Будь-яка змінна, оголошена через <code>var</code>, позначається як недоступна для налаштування. У наступному прикладі змінна <code>salary</code> недоступна для налаштування та не може бути видалена. У нестрогому режимі ця операція <code>delete</code> поверне <code>false</code>.</p>
<pre class="brush: js">function Employee() {
delete salary;
var salary;
}
Employee();
</pre>
<p>Подивимось, як той самий код поводиться у строгому режимі. Замість того, щоб повернути <code>false</code>, код викидає <code>SyntaxError</code>.</p>
<pre class="brush: js">"use strict";
function Employee() {
delete salary; // SyntaxError
var salary;
}
// Схожим чином, пряме звернення до фукнції
// оператором delete викине SyntaxError
function DemoFunction() {
//якийсь код
}
delete DemoFunction; // SyntaxError
</pre>
<h2 id="Приклади">Приклади</h2>
<pre class="brush: js">// Створює властивість adminName у глобальній області видимості.
adminName = 'абв';
// Створює властивість empCount у глобальній області видимості.
// Оскільки ми використовуємо var, вона недоступна для налаштування. Так само як з let та const.
var empCount = 43;
EmployeeDetails = {
name: 'абв',
age: 5,
designation: 'Розробник'
};
// adminName - властивість у глобальній області видимості.
// Вона може бути видалена, оскільки була створена без var,
// і тому доступна для налаштування.
delete adminName; // вертає true
// З іншого боку, empCount недоступна для налаштування,
// оскільки використовувався оператор var.
delete empCount; // вертає false
// delete можна використовувати, щоб видаляти властивості об'єктів.
delete EmployeeDetails.name; // вертає true
<strong>// </strong>Навіть якщо властивість не існує, delete поверне "true".
delete EmployeeDetails.salary; // вертає true
// delete не діє на вбудовані статичні властивості.
delete Math.PI; // вертає false
// EmployeeDetails - властивість у глобальній області видимості.
// Оскільки вона була визначена без "var", вона доступна для налаштування.
delete EmployeeDetails; // вертає true
function f() {
var z = 44;
// delete не діє на локальні змінні
delete z; // вертає false
}
</pre>
<h3 id="delete_та_ланцюжок_прототипів"><code>delete</code> та ланцюжок прототипів</h3>
<p>У наступному прикладі ми видаляємо особисту властивість об'єкта, в той час, як однойменна властивість доступна через ланцюжок прототипів:</p>
<pre class="brush: js">function Foo() {
this.bar = 10;
}
Foo.prototype.bar = 42;
var foo = new Foo();
// foo.bar є особистою властивістю
console.log(foo.bar); // 10
// Видаляємо особисту властивість
// у об'єкті foo.
delete foo.bar; // вертає true
// Властивість foo.bar досі доступна
// у ланцюжку прототипів.
console.log(foo.bar); // 42
// Видаляємо властивість прототипу.
delete Foo.prototype.bar; // вертає true
// Властивість "bar" більше не може
// наслідуватись від Foo, оскільки була
// видалена.
console.log(foo.bar); // undefined</pre>
<h3 id="Видалення_елементів_масиву">Видалення елементів масиву</h3>
<p>Коли ви видаляєте елемент масиву, довжина масиву не змінюється. Це зберігається, навіть якщо ви видалите останній елемент масиву.</p>
<p>Коли оператор <code>delete</code> видаляє елемент масиву, цей елемент більше не існує у масиві. У наступному прикладі <code>trees[3]</code> видаляється за допомогою <code>delete</code>.</p>
<pre class="brush: js">var trees = ['секвоя', 'лавр', 'кедр', 'дуб', 'клен'];
delete trees[3];
if (3 in trees) {
// це не виконається
}</pre>
<p>Якщо ви бажаєте, щоб елемент масиву існував, але мав значення undefined, скористайтесь значенням <code>undefined</code> замість оператора <code>delete</code>. У наступному прикладі елементу <code>trees[3]</code> присвоюється значення undefined, але елемент масиву досі існує:</p>
<pre class="brush: js">var trees = ['секвоя', 'лавр', 'кедр', 'дуб', 'клен'];
trees[3] = undefined;
if (3 in trees) {
// це виконається
}</pre>
<p>Якщо замість цього ви хочете видалити елемент масиву, змінивши вміст масиву, скористайтесь методом <code>{{jsxref("Array.splice", "splice")}}</code>. У наступному прикладі елемент <code>trees[3]</code> повністю видаляється з масиву за допомогою методу <code>{{jsxref("Array.splice", "splice")}}</code>:</p>
<pre class="brush: js">var trees = ['секвоя', 'лавр', 'кедр', 'дуб', 'клен'];
trees.splice(3,1);
console.log(trees); // ["секвоя", "лавр", "кедр", "клен"]
</pre>
<h2 id="Специфікації">Специфікації</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Специфікація</th>
<th scope="col">Статус</th>
<th scope="col">Коментар</th>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-delete-operator', 'The delete Operator')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td></td>
</tr>
<tr>
<td>{{SpecName('ES6', '#sec-delete-operator', 'The delete Operator')}}</td>
<td>{{Spec2('ES6')}}</td>
<td></td>
</tr>
<tr>
<td>{{SpecName('ES5.1', '#sec-11.4.1', 'The delete Operator')}}</td>
<td>{{Spec2('ES5.1')}}</td>
<td></td>
</tr>
<tr>
<td>{{SpecName('ES1', '#sec-11.4.1', 'The delete Operator')}}</td>
<td>{{Spec2('ES1')}}</td>
<td>Початкове визначення. Реалізоване у JavaScript 1.2.</td>
</tr>
</tbody>
</table>
<h2 id="Сумісність_з_веб-переглядачами">Сумісність з веб-переглядачами</h2>
<p>{{Compat("javascript.operators.delete")}}</p>
<h2 id="Примітки_щодо_кросбраузерності">Примітки щодо кросбраузерності</h2>
<p>Хоча ECMAScript робить порядок перебору об'єктів залежним від реалізації, може здаватись, що усі основні веб-переглядачі підтримують порядок перебору, в якому властивість, додана першою, йде першою (принаймні, для не прототипних властивостей). Однак, у Internet Explorer при використанні <code>delete</code> з властивістю, виникає дивна поведінка, яка заважає іншим переглядачам використовувати прості об'єкти, такі як об'єктні літерали, як впорядковані асоціативні масиви. У Explorer, хоча <em>значення </em>властивості дійсно стає undefined, але, якщо пізніше користувач знову додає властивість з таким самим ім'ям, властивість буде перебиратися на своїй <em>старій</em> позиції, а не в кінці перебору, як можна було б очікувати після видалення властивості та повторного її додавання.</p>
<p>Якщо ви хочете використовувати впорядкований асоціативний масив у кросбраузерному середовищі, використовуйте об'єкт {{jsxref("Map")}}, якщо він доступний, або імітуйте цю структуру двома окремими масивами (один для ключів, а інший для значень), або створіть масив об'єктів з однією властивістю, і т. д.</p>
<h2 id="Див._також">Див. також</h2>
<ul>
<li><a href="http://perfectionkills.com/understanding-delete/">In depth analysis on delete</a></li>
<li>{{jsxref("Reflect.deleteProperty()")}}</li>
<li>{{jsxref("Map.prototype.delete()")}}</li>
</ul>
|