Каково истинное значение возвращаемого значения `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 */
}