Каково истинное значение возвращаемого значения `delete`?

Согласно этой странице MDN, ключевое слово delete

Возвращает false, только если свойство существует и не может быть удалено. Это возвращает true во всех других случаях.

Однако я вижу случаи, когда delete возвращает true, несмотря на то, что свойство не удаляется:

delete Window
delete alert
delete dir
delete console
delete 2
delete null
delete {}.x
...

Фактически, почти все свойства window возвращают true с помощью delete, что видно из запуска следующего script в about:blank:

for(a in window) { if(delete window[a]) { console.log(a); } }

Однако большинство свойств window фактически не удаляются. Каков истинный смысл возвращаемого значения delete? Почему он возвращает true для свойств, которые он не удаляет?

(Примечание: меня интересовали бы ссылки на код Chromium, объясняющие поведение delete.)

Ответ 1

Окно представляет собой объект хоста , один из которых семантики определяется средой хоста, например. браузера. delete при применении к свойствам объектов хоста более сложно, чем при применении к нативным объектам.

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

Раздел 11.4.1 - Оператор delete говорит

If IsUnresolvableReference(ref) then,
  If IsStrictReference(ref) is true, throw a SyntaxError exception.
  Else, return true.

поэтому, когда объект-хост не поддерживает удаление или изменение свойства, он возвращает неразрешимую ссылку или ссылку, которая притворяется удаленной. Любой из подходов приводит к возврату true в нестрогий режим.

Ответ 2

Реализация javascript, используемая браузерами, всегда искажала правила. Часть javascript DOM API даже не возможна в чистом javascript, например dom innerHTML= "something", который запускает событие. Это было исправлено в EcmaScript5, но вы не можете полагаться на объектную модель браузера, которая является 100% законным javascript. AFAIK, если вы не вносите ногу в DOM и спецификацию, вы можете полностью полагаться на стандарт ecmascript.

Ответ 3

Учитывая, что вы действуете на объектах низкого уровня в своей программе, атрибуты могут быть фактически удалены, а затем немедленно добавлены, хотя я понятия не имею, как вы можете проверить это поведение.

Ответ 4

На этой странице MDN он указывает синтаксис, который не включает delete object в качестве первого набора примеров. Он указывает синтаксис delete object[property], как показывает ваш второй пример. Однако то, что происходит с объектами DOM (host), не указывается. Подробнее см. в этой статье.

Ответ 5

В основном, браузеры защищают среду выполнения браузера в вашем тесте.

Когда-то это могло быть не так, но по мере прохождения тестов это похоже на вопрос, почему Windows не позволяет вам открыть командную оболочку и запустить:

> cd /
> deltree *.*

больше.

Потому что нет действительно веских оснований для того, чтобы иметь возможность делать такие вещи, когда вы ожидаете, что среда действительно продолжит работать, а потом, а не удалит весь ваш браузер, а также потенциально экземпляр вашей ОС. в настоящее время выполняется или какие-либо другие забавные ошибки могут возникать, когда вы в основном просите программу стирать себя в режиме реального времени, в то время как в настоящее время он имеет низкоуровневый доступ к вашим устройствам графической/звуковой карты/ввода.

Удалить возвращает отказ в случае, если вы пытаетесь удалить var. С точки зрения глобальных свойств браузер должен функционировать, большинство из них определяются как свойство (т.е. window.location), но выполняются на низкоуровневом уровне (т.е. У вас нет доступа). Поэтому теоретически это объекты, которые можно удалить. Но они защищены, поэтому вы не можете, но это не изменит оператор return delete, потому что это изменит ожидаемое поведение delete.

Итак:

function () {
    var obj = { prop : true };
    delete obj; /* fail */
    delete object.prop; /* succeed */
}