Почему вы можете удалить переопределенное свойство окна?
Оператор delete
удаляет свойство из объекта. Если я устанавливаю свойство на window
, я могу его удалить:
window.myProp = 10;
delete window.myProp;
Как статья, я так часто ссылаюсь на другие, когда дело доходит до поведения состояний оператора delete
, это связано с тем, что присвоение свойств не устанавливает атрибут DontDelete
(в отличие от объявления переменной).
В этой статье также указано следующее (выделено мной):
Обратите внимание, что во время создания свойства атрибуты (т.е. нет). Поздние задания не изменяют атрибуты существующего свойства. Важно понять это различие.
Помня об этом, почему я могу переопределить существующее свойство окна, alert
, а затем удалить его, чтобы вернуться к исходному значению? Мне что-то не хватает? Я редко использую оператор delete
, чтобы это могло случиться.
Например:
window.alert = function() {};
alert("Hi!"); //Nothing happens
delete window.alert;
alert("Hello?"); //Alerts 'Hello?'
Здесь fiddle, чтобы продемонстрировать это (только проверенный в Chome, довольно уверен, что IE не будет вести себя таким образом, но не имеет доступа на все, кроме Chrome, прямо сейчас).
Ответы
Ответ 1
В Chrome функция window.alert
является частью прототипа класса DOMWindow
, это не свойство самого window
.
Следовательно, при перезаписывании window.alert
вы добавляете новое свойство в window
, но версия в прототипе продолжает существовать, но скрыта.
Когда вы delete window.alert
, функция в прототипе повторно отображается.
Здесь вывод консоли, показывающий, что функция находится в прототипе:
> window.constructor.prototype
DOMWindow
> window.constructor.prototype.alert
function alert() { [native code] }
Firefox ведет себя аналогично, хотя и с разными именами классов.
Ответ 2
Это предполагаемое поведение, которое называется затенением. Это позволяет вам предоставлять пользовательские функции, не уничтожая функциональность суперклассов. Когда вы удаляете метод, ваш собственный метод удаляется, показывая оригинальный метод из прототипа.
Чем глубже вы входите в наследование и понимаете, как работает прототип, тем больше вы увидите, как люди делают это.
Отличный вопрос. Это не область, часто изучаемая большинством разработчиков JavaScript в моем опыте. Если бы это было не так, многие полиполки, которые расширяют или переопределяют основные функциональные возможности базовых объектов JavaScript, не будут возможны.