Секреты оператора delete

delete 0

Когда выполняется delete 0, произойдет ли удаление 0 из системы выполнения? Очевидно, нет, истинная цель оператора — удалить ссылку на свойство объекта.

delete object.property
delete object['property']

Как правило, успешное удаление возвращает true, а неудачное — false, но есть некоторые исключения.

Собственные свойства

Оператор delete работает только с собственным свойством объекта. Если в цепочке прототипов окажется свойство с таким же именем, это свойство будет пропущено.

Object.prototype.name = 1;

const object = {
  name: 2,
};

// Действует только в отношении собственных свойств.
console.log(delete object.name); // true
console.log(object.name); // 1

// Но мы можем напрямую манипулировать объектом-прототипом.
console.log(delete Object.getPrototypeOf(object).name); // true
console.log(object.name); // undefined

Несуществующее свойство

Если удаляемое свойство не существует, delete не будет иметь никакого эффекта, но все равно вернет true.

const object = {};

delete object.name; // true

Неконфигурируемое свойство

Неконфигурируемые свойства не могут быть удалены.

const object = {};

Reflect.defineProperty(object, 'name', {
  configurable: false,
});

// Встроенные свойства объекта
console.log(delete Math.PI); // false
// Неконфигурируемые свойства
console.log(delete object.name); // false

В нестрогом режиме удаление неконфигурируемого свойства из самого себя вернет false, но в строгом режиме оно вызовет TypeError.

'use strict';

const object = {};

Reflect.defineProperty(object, 'name', {
  configurable: false,
});

// ❌ TypeError: Cannot delete property 'PI' of #<Object>
console.log(delete Math.PI);
// ❌ TypeError: Cannot delete property 'name' of #<Object>
console.log(delete object.name);

Свойства, объявленные с помощью var, let, const

В глобальной области видимости нельзя удалить ни свойства, объявленные с помощью var, ни функции, объявленные с помощью определения функций (нефункциональных выражений). Это связано с тем, что оба объявленных свойства закреплены за окном и не являются настраиваемыми, поэтому при удалении будет соблюдена логика предыдущего пункта.

Кроме того, свойства, объявленные с помощью var, let, const и этих функций, не могут быть удалены ни в глобальной области видимости, ни в области видимости функции.

{
  let object = {
    name: 1,
  };
  function getName(obj) {
    return obj.name;
  }
  console.log(delete object); // false
  console.log(delete getName); // false
}

В нестрогом режиме возвращается false, но в строгом режиме, вместо TypeError, выбрасывается SyntaxError.

'use strict';

{
  let object = {
    name: 1,
  };

  function getName(obj) {
    return obj.name;
  }

  // ❌ SyntaxError: Delete of an unqualified identifier in strict mode.
  console.log(delete object);
  // ❌ SyntaxError: Delete of an unqualified identifier in strict mode.
  console.log(delete getName);
}

Свойство массива

Во-первых, свойство length (длины) массива не является настраиваемым, поэтому его удаление в строгом режиме вызовет TypeError.

'use strict';

const arr = [1, 2, 3, 4, 5];

console.log(Reflect.getOwnPropertyDescriptor(arr, 'length'));
// ❌ TypeError: Cannot delete property 'length' of [object Array]
console.log(delete arr.length);

Во-вторых, при удалении элемента массива удаляемый элемент будет пустым.

Чтобы изменить исходный массив, можно использовать Array.prototype.splice().

Заключение

Истинное назначение оператора delete в JavaScript — это удаление ссылки на свойство объекта. В некоторых особых случаях он может вести себя странно, поэтому лучше использовать его только для удаления настраиваемых свойств, присущих самому объекту.

Обратите также внимание на то, что оператор delete не имеет ничего общего с освобождением памяти напрямую (в отличие от delete в C++). Это связано с тем, что среда выполнения JavaScript управляет памятью автоматически.

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Zachary Lee, “The Secret of the ‘delete operator’

Предыдущая статьяMLOps: как внедрить систему рекомендаций товаров на ecommerce-сайт
Следующая статьяКак создать аналитический сайт на Python с нуля