Оператор delete

Оператор JavaScript delete видаляє властивість об'єкта. Якщо на цю властивість більше немає посилань, пам'ять під неї зрештою звільняється автоматично.

Синтаксис

delete вираз 

де вираз має вертати посилання на властивість, наприклад:

delete object.property
delete object['property']

Параметри

object
Ім'я об'єкта, чи вираз, що повертає цей об'єкт.
property
Властивість, яку треба видалити.

Значення, що повертається

Завжди true, окрім випадків, коли властивість є особистою властивістю, недоступною для налаштування, в цьому випадку у нестрогому режимі повертається false.

Винятки

Викидає TypeError у строгому режимі, якщо властивість є особистою властивістю, недоступною для налаштування.

Опис

Попри розповсюджену думку, оператор delete не має нічого спільного з прямим вивільненням пам'яті. Керування пам'яттю відбувається опосередковано через розривання посилань. Більше інформації дивіться у статті Керування пам'яттю.

Оператор delete видаляє задану властивість з об'єкта. В разі успішного видалення, він поверне true, інакше поверне false. Однак, важливо враховувати наступні сценарії:

  • Якщо властивість, яку ви намагаєтесь видалити, не існує, delete не матиме жодного ефекту та поверне true
  • Якщо властивість з таким самим ім'ям існує у ланцюзі прототипів об'єкта, тоді, після видалення, об'єкт використовуватиме властивість з ланцюжка прототипів (іншими словами, delete має ефект лише для особистих властивостей).
  • Будь-яка властивість, оголошена через var, не може бути видалена з глобальної області видимості чи з області видимості функції.
    • Таким чином, delete не може видаляти функції у глобальній області видимості (незалежно від того, чи є вони оголошеннями функції, чи функціональними виразами).
    • Функції, які є частиною об'єкта (не є частиною глобальної області видимості), можуть бути видалені оператором delete.
  • Будь-яка властивість, оголошена через let або const, не може бути видалена з області видимості, всередині якої вона була оголошена.
  • Властивості, недоступні для налаштування, не можуть бути видалені. Це також стосується властивостей вбудованих об'єктів, таких як Math, Array, Object, та властивостей, які були створені як недоступні для налаштування за допомогою методів на кшталт Object.defineProperty().

Наступний фрагмент надає простий приклад:

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

Властивості, недоступні для налаштування

Коли властивість позначена як недоступна для налаштування, delete не матиме жодного ефекту та поверне false. У строгому режимі це спричинить помилку TypeError.

var Employee = {};
Object.defineProperty(Employee, 'name', {configurable: false});

console.log(delete Employee.name);  // вертає false

var, let та const створюють властивості, недоступні для налаштування, які не можуть бути видалені оператором delete:

var nameOther = 'XYZ';

// Ми можемо звернутися до цієї глобальної властивості так:
Object.getOwnPropertyDescriptor(window, 'nameOther');  

// виведе: Object {value: "XYZ", 
//                  writable: true, 
//                  enumerable: true,
//                  configurable: false}

// Оскільки "nameOther" додана за допомогою ключового
// слова var, вона позначена як недоступна для налаштування

delete nameOther;   // вертає false

У строгому режимі це спричинило б виняток.

Строгий режим проти нестрогого режиму

У строгому режимі, якщо delete використовується на прямому посиланні на змінну, аргумент функції чи ім'я функції, це викине SyntaxError.

Будь-яка змінна, оголошена через var, позначається як недоступна для налаштування. У наступному прикладі змінна salary недоступна для налаштування та не може бути видалена. У нестрогому режимі ця операція delete поверне false.

function Employee() { 
  delete salary;
  var salary;
}

Employee();

Подивимось, як той самий код поводиться у строгому режимі. Замість того, щоб повернути false, код викидає SyntaxError.

"use strict";

function Employee() {
  delete salary;  // SyntaxError
  var salary;        
}

// Схожим чином, пряме звернення до фукнції
// оператором delete викине SyntaxError

function DemoFunction() {
  //якийсь код
}

delete DemoFunction; // SyntaxError

Приклади

// Створює властивість 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 

// Навіть якщо властивість не існує, 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
}

delete та ланцюжок прототипів

У наступному прикладі ми видаляємо особисту властивість об'єкта, в той час, як однойменна властивість доступна через ланцюжок прототипів:

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

Видалення елементів масиву

Коли ви видаляєте елемент масиву, довжина масиву не змінюється. Це зберігається, навіть якщо ви видалите останній елемент масиву.

Коли оператор delete видаляє елемент масиву, цей елемент більше не існує у масиві. У наступному прикладі trees[3] видаляється за допомогою delete.

var trees = ['секвоя', 'лавр', 'кедр', 'дуб', 'клен'];
delete trees[3];
if (3 in trees) {
    // це не виконається
}

Якщо ви бажаєте, щоб елемент масиву існував, але мав значення undefined, скористайтесь значенням undefined замість оператора delete. У наступному прикладі елементу trees[3] присвоюється значення undefined, але елемент масиву досі існує:

var trees = ['секвоя', 'лавр', 'кедр', 'дуб', 'клен'];
trees[3] = undefined;
if (3 in trees) {
    // це виконається
}

Якщо замість цього ви хочете видалити елемент масиву, змінивши вміст масиву, скористайтесь методом splice. У наступному прикладі елемент trees[3] повністю видаляється з масиву за допомогою методу splice:

var trees = ['секвоя', 'лавр', 'кедр', 'дуб', 'клен'];
trees.splice(3,1);
console.log(trees); // ["секвоя", "лавр", "кедр", "клен"]

Специфікації

Специфікація Статус Коментар
ECMAScript Latest Draft (ECMA-262)
The definition of 'The delete Operator' in that specification.
Draft
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'The delete Operator' in that specification.
Standard
ECMAScript 5.1 (ECMA-262)
The definition of 'The delete Operator' in that specification.
Standard
ECMAScript 1st Edition (ECMA-262)
The definition of 'The delete Operator' in that specification.
Standard Початкове визначення. Реалізоване у JavaScript 1.2.

Сумісність з веб-переглядачами

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
deleteChrome Full support 1Edge Full support 12Firefox Full support 1IE Full support 4Opera Full support YesSafari Full support YesWebView Android Full support 1Chrome Android Full support 18Firefox Android Full support 4Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support 1.0nodejs Full support Yes

Legend

Full support  
Full support

Примітки щодо кросбраузерності

Хоча ECMAScript робить порядок перебору об'єктів залежним від реалізації, може здаватись, що усі основні веб-переглядачі підтримують порядок перебору, в якому властивість, додана першою, йде першою (принаймні, для не прототипних властивостей). Однак, у Internet Explorer при використанні delete з властивістю, виникає дивна поведінка, яка заважає іншим переглядачам використовувати прості об'єкти, такі як об'єктні літерали, як впорядковані асоціативні масиви. У Explorer, хоча значення властивості дійсно стає undefined, але, якщо пізніше користувач знову додає властивість з таким самим ім'ям, властивість буде перебиратися на своїй старій позиції, а не в кінці перебору, як можна було б очікувати після видалення властивості та повторного її додавання.

Якщо ви хочете використовувати впорядкований асоціативний масив у кросбраузерному середовищі, використовуйте об'єкт Map, якщо він доступний, або імітуйте цю структуру двома окремими масивами (один для ключів, а інший для значень), або створіть масив об'єктів з однією властивістю, і т. д.

Див. також