Если говорить кратко — в JavaScript невозможно удалить глобальную переменную или функцию или любую другую сущность, у которой установлен атрибут DontDelete.
Когда переменная или функция определена в глобальной области видимости или в области видимости функции, её судьба предопределена: (прим. перев. — внутри движка JavaScript) она является свойством (property) либо объекта Activation, либо объекта Global. Подобные сущности имеют набор внутренних атрибутов, одним из которых и является упомянутый ранее DontDelete. Переменные и объявления функций, замеченные движком в глобальной области или в коде функций, создаются с атрибутом DontDelete и поэтому не могут быть удалены.
// глобальная переменная:
var a = 1; // установлен DontDelete
delete a; // false
a; // 1
// обычная функция:
function f() {} // установлен DontDelete
delete f; // false
typeof f; // "function"
// переопределение не помогает:
f = 1;
delete f; // false
f; // 1
Свойства, установленные явно, могут быть безпрепятственно удалены:
// явно установим свойства:
var obj = {x: 1};
obj.y = 2;
delete obj.x; // true
delete obj.y; // true
obj.x; // undefined
obj.y; // undefined
В приведённом примере свойства obj.x и obj.y могут быть удалены, поскольку у них отсутствует атрибут DontDelete. По этой же причине работает и пример ниже:
// работает нормально, но не в IE
var GLOBAL_OBJECT = this;
GLOBAL_OBJECT.a = 1;
a === GLOBAL_OBJECT.a; // true - просто глобальная переменная
delete GLOBAL_OBJECT.a; // true
GLOBAL_OBJECT.a; // undefined
Здесь, чтобы удалить a, мы используем один трюк. В этом коде this ссылается на объект Global и мы явно описываем переменную a под видом его свойства, что и позволяет нам её успешно удалить.
Internet Explorer (по крайней мере, с 6-го по 8-й) содержит баги, из-за которых такой код не сработает.
Обычные аргументы функций, объект arguments, а также встроенные свойства, объединены общей особенностью: у всех у них установен атрибут DontDelete.
// аргументы функций и свойства:
(function (x) {
delete arguments; // false
typeof arguments; // "object"
delete x; // false
x; // 1
function f(){}
delete f.length; // false
typeof f.length; // "number"
})(1);
(прим. перев. — Хост-объекты — это объекты, которые, в неком окружении, дополняют функциональность языка JavaScript, не являясь частью его спецификации. В случае браузера это объекты window, document, setTimeout и т.п.)
Поведение оператора delete может быть полностью непредсказуемым, когда вы примененяете его к таким хост-объектам. С позволения спецификации, хост-объекты вольны вести себя как им только вздумается.
Оператор delete часто ведёт себя непредсказуемо и может использоваться относительно безопасно только для удаления пользовательских свойств у обычных объектов.