На каком объекте хранятся глобальные переменные Javascript?
Сохраняются ли глобальные переменные в конкретном объекте? Например:
var test="stuff";
console.log(window.test);
console.log(document.test);
console.log(this.test);
Все три из этих тестов приводят к undefined
, так есть ли объект, который содержит эти переменные?
Мне кажется, что это что-то глупое, что я должен уже знать, но я даже не могу найти ответ в Интернете.
Ответы
Ответ 1
Я думаю, что вы найдете в большинстве браузеров, они хранятся в window
.
Надуманная попытка психической отладки: вы проверили это в jsFiddle? Или, может быть, в Firebug? Если это так, вы, вероятно, видите undefined
для всех трех, потому что в этом случае код выполняется в кадре; поэтому он имеет другой объект window
(я думаю) код фактически завернут:
window.addEvent('load', function() {
var test="stuff";
console.log(window.test);
console.log(document.test);
console.log(this.test);
});
Из приведенного выше фрагмента из jsFiddle вы можете видеть, что test
не является глобальной переменной, что объясняет, почему она не была привязана к window
.
Я не эксперт, но этот ответ кажется точным из того, что я могу сказать в Chrome, Firefox, Safari и Opera. Чтобы проверить, я создал файл HTML со следующим содержимым и загрузил его в каждом браузере:
<script type="text/javascript">
var test = "stuff";
alert(window.test);
</script>
Конечно, "материал" каждый раз.
Ответ 2
Вот последний, но технический ответ.
Вы спрашиваете
Сохраняются ли глобальные переменные в определенном объекте?
Ответ: да; они хранятся в так называемом, официально глобальном объекте. Этот объект описан в разделе 15.1 официальной спецификации ECMAScript 5 .
Глобальный объект не должен иметь имя; но вы можете ссылаться на его свойства, такие как String
, isNaN
и Date
, просто используя их имя. Ваша среда хоста JavaScript будет размещать другие свойства в глобальном объекте, кроме тех, которые требуются спецификацией ECMAScript, например alert
или console
. В браузере я могу написать script
alert("Hello world");
потому что alert
является свойством глобального объекта.
Обратите внимание, что не обязательно иметь доступ к этому глобальному объекту, верьте или нет. Однако классная вещь заключается в том, что многие среды хоста помещают свойство в глобальный объект, значение которого является ссылкой на сам глобальный объект. В большинстве веб-браузеров это свойство называется window
. Поэтому мы можем написать:
alert("Hello");
window.alert("Hello");
window.window.alert("Hello");
window.window.window.window.window.alert("Hello");
и вы также можете сказать:
var x = 5;
alert(this.x);
и получите сообщение 5
.
Ответ 3
Глобальная переменная "true" не имеет ключевого слова "var".
Попробуйте следующее:
test="stuff";
console.log(window.test);
console.log(document.test);
console.log(this.test);
При этом все области будут видеть это. Переменные с ключевым словом var являются локальными для области, которую они объявили.
Переменная будет "global to window" (свойство объекта window), только если вы объявите ее в области окна, как сказал Дэн, делая ее глобальной для браузеров, которые обычно используют окно в качестве глобальной области.
Ответ 4
Глобальные переменные сохраняются в глобальной переменной window
. Следующий код работает, если вы просто объявляете его вне чего-либо (например, функции):
var test="stuff";
console.log(window.test);
аналогичное доказательство состоит в том, что window.location.href
совпадает с location.href
Однако проблема может заключаться в том, где была объявлена переменная. Например, если вы указали эту переменную в функции, она будет существовать только в функции, а не глобально:
function foo(){
//declaring inside function
var test="stuff";
//undefined, since the variable exists in the function only
console.log(window.test);
//undefined, document refers to the document
//which is the top DOM object, not the global window
console.log(document.test);
//depends on what "this" refers to, especially
//when using call() or apply() to call the function
//For normal function calls, usually it points to window as well
console.log(this.test);
//none of the above refer to "test" that contains "stuff"
//because you are looking in the wrong place
}