2012-04-25 3 views
15

Оператор delete удаляет свойство объекта. Если установить свойство на window, я могу удалить его:Почему вы можете удалить переопределенное свойство окна?

window.myProp = 10; 
delete window.myProp; 

Как the article я так часто ссылаются другие, когда речь идет о поведении delete оператора состояний, это потому, что присвоение собственности не устанавливает DontDelete атрибут (в отличие от объявления переменной, который делает).

В этой статье также говорится следующее (курсив добавлен):

Обратите внимание, что при создании имущества, что атрибуты являются определены (то есть ни один не установлены). Более поздние присвоения не изменяют атрибуты существующего имущества. Важно понимать это различие .

Имея это в виду, почему я могу переопределить существующее свойство окна, alert, а затем удалить его вернуться к исходному значению? Мне что-то не хватает? Я редко использую оператор delete, так что это может быть так.

Например:

window.alert = function() {}; 
alert("Hi!"); //Nothing happens 

delete window.alert; 
alert("Hello?"); //Alerts 'Hello?' 

Вот fiddle, чтобы продемонстрировать, что (проверяется только в темэ, уверен, что IE не будет вести себя подобным образом, но не имеют доступа ни к чему, кроме Chrome прямо сейчас).

+0

'delete' на объектах хоста не следует полагаться и не работает в IE. – Esailija

+0

Возможный дубликат [alert() не работает в Chrome] (http://stackoverflow.com/questions/6184169/alert-not-working-in-chrome) –

+0

Я не знаю, но мне нравится ваш вопрос. Я предполагаю, что это что-то вроде стиля CSS для элемента, переопределяющего его унаследованный стиль, и если этот стили стилей удаляются через JS, он возвращается к унаследованному стилю ... вы можете только переопределить его, он никогда не удаляется - просто теория. Кроме того, что произойдет, если вы попытаетесь удалить window.alert, не указав сначала что-то еще? – squarephoenix

ответ

9

В Chrome, функция window.alert является частью прототипа из DOMWindow класса, это не свойство самого window.

Поэтому, когда вы перезаписать window.alert вы добавляете свойство нового в window, но версия в прототипе продолжает существовать, но скрыто.

Когда вы delete window.alert, функция в прототипе повторно отображается.

Вот некоторые консоли вывода, показывая, что функция в прототипе:

> window.constructor.prototype 
DOMWindow 

> window.constructor.prototype.alert 
function alert() { [native code] } 

Firefox ведет себя так же, хотя и с разными именами классов.

+0

Ahhh Я знал, что это будет что-то очевидное, что я спускаюсь! Благодарю. –

+0

@ Alnitak Great Answer .. @ James мы также можем удалить свойство alert на объекте прототипа, но я бы строго возражал против этого. Мы не должны изменять объекты, которые у нас нет. Поэтому в идеале мы не должны удалять свойство alert из окно также – sachinjain024

+0

Спасибо за это. У нас есть некоторая некомпетентность: мы можем только добавить наш код на сайт клиента в определенном элементе, не можем касаться скриптов ранее на странице или помещать любой код перед их запуском. И ранее на странице запускался скрипт, который выдает языковые строки в глобальном пространстве имен, включая 'open =" Open ";'. Неожиданно SDK для Google не может открывать диалоги на мобильных устройствах. Ваш ответ помог нам спасти окно. – tremby

2

Это предполагаемое поведение, это называется затенением. Это позволяет вам предоставлять пользовательские функции, не уничтожая функциональность суперклассов. Когда вы удаляете метод, ваш пользовательский метод удаляется, показывая оригинальный метод из прототипа.

Чем глубже вы переходите к наследованию и понимаете, как работает прототип, тем больше вы увидите, как люди делают это.

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

Смежные вопросы