Что именно является разрушаемым в JavaScript?

Оператор удаления, возможно, является старой языковой функцией JavaScript. Буквально это означает, что он хочет что-то разрушить, но что именно можно разрушить? Приходите и исследуйте вместе со мной!

удалить 0

Когда выполняется удаление 0, будет ли оно уничтожено из системы выполнения с 0?

Очевидно, что нет, его настоящая цель — удалить ссылку на свойство объекта.

delete object.property
delete object['property']

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

Собственная недвижимость

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

Object.prototype.name = 1;
const object = {
  name: 2,
};
// Only valid for its own properties.
console.log(delete object.name); // true
console.log(object.name); // 1
// But we can directly manipulate the prototype object.
console.log(delete Object.getPrototypeOf(object).name); // true
console.log(object.name); // undefined

Несуществующее имущество

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

const object = {};
delete object.name; // true

Ненастраиваемое свойство

Ненастраиваемые свойства нельзя удалить.

const object = {};
Reflect.defineProperty(object, 'name', {
  configurable: false,
});
// Built-in object properties
console.log(delete Math.PI); // false
// Non-configurable properties
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, но в строгом режиме выдается SyntaxError вместо TypeError.

'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);
}

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

Прежде всего, свойство длины массива не настраивается, поэтому его удаление в строгом режиме вызовет 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(), подробности см. в моей предыдущей статье.

Заключение

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

Кроме того, обратите внимание, что оператор удаления не имеет ничего общего с освобождением памяти напрямую (по сравнению с удалением в C++), это связано с тем, что среда выполнения JavaScript управляет памятью автоматически. Для получения дополнительной информации об управлении памятью языка программирования ознакомьтесь с моей предыдущей статьей:



Это все на сегодня. Меня зовут Закари, и я продолжу выкладывать истории, связанные с веб-разработкой, не забывайте подписываться на меня, если вам нравятся такие истории.