Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

Глобальный объект

Лекция



Привет, сегодня поговорим про глобальный объект, обещаю рассказать все что знаю. Для того чтобы лучше понимать что такое глобальный объект , настоятельно рекомендую прочитать все из категории Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend).


  1. глобальный объект
  2. Порядок инициализации
  3. Итого

Механизм работы функций и переменных в JavaScript очень отличается от большинства языков.

Чтобы его понять, мы в этой главе рассмотрим переменные и функции в глобальной области. А в следующей — пойдем дальше.

Глобальный объект

Глобальными называют переменные и функции, которые не находятся внутри какой-то функции. То есть, иными словами, если переменная или функция не находятся внутри конструкции function, то они — «глобальные».

В JavaScript все глобальные переменные и функции являются свойствами специального объекта, который называется «глобальный объект» (global object).

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

В других окружениях, например Node.JS, глобальный объект может быть недоступен в явном виде, но суть происходящего от этого не изменяется, поэтому далее для обозначения глобального объекта мы будем использовать "window".

Присваивая или читая глобальную переменную, мы, фактически, работаем со свойствамиwindow.

Например:

   
1 var a = 5;   // объявление var создает свойство window.a
2 alert(window.a); // 5

 

Создать переменную можно и явным присваиванием в window:

 

   
1 window.a = 5;
2 alert(a); // 5

 

Порядок инициализации

Выполнение скрипта происходит в две фазы:

  1. На первой фазе происходит инициализация, подготовка к запуску.

    Во время инициализации скрипт сканируется на предмет объявления функций вида Function Declaration, а затем — на предмет объявления переменных var. Каждое такое объявление добавляется в window.

    Функции, объявленные как Function Declaration, создаются сразу работающими, а переменные — равными undefined.

  2. На второй фазе — собственно, выполнение.

    Присваивание (=) значений переменных происходит на второй фазе, когда поток выполнения доходит до соответствующей строчки кода.

В начале кода ниже указано содержание глобального объекта на момент окончания инициализации:

 

1 // По окончании инициализации, до выполнения кода:
2 // window = { f: function, a: undefined, g: undefined }
3  
4 var a = 5; // при инициализации дает: window.a=undefined
5  
6 function f(arg) { /*...*/ }  // при инициализации дает: window.f = function
7  
8 var g = function(arg) { /*...*/ }; // при инициализации дает: window.g = undefined

 

Кстати, тот факт, что к началу выполнения кода переменные и функции уже содержатся в window, можно легко проверить:

 

   
1 alert("a" in window); // true,  т.к. есть свойство window.a
2 alert(a); // равно undefined,  присваивание будет выполнено далее
3 alert(f); // function ...,  готовая к выполнению функция
4 alert(g); // undefined, т.к. это переменная, а не Function Declaration
5  
6 var a = 5; 
7 function f() { /*...*/ }
8 var g = function() { /*...*/ };

 

 

Присвоение переменной без объявления

В старом стандарте JavaScript переменную можно было создать и без объявленияvar:

   
1 a = 5;
2  
3 alert(a); // 5

 

Такое присвоение, как и var a = 5, создает свойство window.a = 5. Отличие отvar a = 5 — в том, что переменная будет создана не на этапе входа в область видимости, а в момент присвоения.

Сравните два кода ниже.

Первый выведет undefined, так как переменная была добавлена в window на фазе инициализации:

   
1 alert(a); // undefined
2  
3 var a = 5;

 

Второй код выведет ошибку, так как переменной еще не существует:

 

   
1 alert(a); // error, a is not defined
2  
3 a = 5;

 

Вообще, рекомендуется всегда объявлять переменные через var.

В современном стандарте присваивание без var вызовет ошибку:

   
1 'use strict';
2 a = 5; // error, a is not defined

 

 

 

Конструкции for, if... не влияют на видимость переменных

Фигурные скобки, которые используются в for, while, if, в отличие от объявлений функции, имеют «декоративный» характер.

В JavaScript нет разницы между объявлением вне блока:

 

1 var i;
2 {
3   i = 5;
4 }
…И внутри него:
1 i = 5;
2 {
3   var i;
4 }

 

Также нет разницы между объявлением в цикле и вне его:

   
1 for (var i=0; i<5; i++) { }
Идентичный по функциональности код:
   
1 var i;
2 for (i=0; i<5; i++) { }

 

В обоих случаях переменная будет создана до выполнения цикла, на стадии инициализации, и ее значение будет сохранено после окончания цикла.

 

 

Не важно, где и сколько раз объявлена переменная

Объявлений var может быть сколько угодно:

1 var i = 10;
2  
3 for (var i=0; i<20; i++) {
4   ...
5 }
6  
7 var i = 5;

 

Все var будут обработаны один раз, на фазе инициализации.

На фазе исполнения объявления var будут проигнорированы: они уже были обработаны. Об этом говорит сайт https://intellect.icu . Зато будут выполнены присваивания.

 

 

Ошибки при работе с window в IE8-

В старых IE есть две забавные ошибки при работе с переменными в window:

  1. Переопределение переменной, у которой такое же имя, как и id элемента, приведет к ошибке:
       
    1 <div id="a">...</div>
    2 <script>
    3   a = 5;    // ошибка в IE<9! Правильно будет "var a = 5"
    4   alert(a); // никогда не сработает
    5 </script>

    А если сделать через var, то все будет хорошо.

    Это была реклама того, что надо везде ставить var.

  2. Ошибка при рекурсии через функцию-свойство window. Следующий код «умрет» в IE<9:
       
    1 <script>
    2 // рекурсия через функцию, явно записанную в window
    3 window.recurse = function(times) {
    4   if (times !== 0) recurse(times-1);
    5 }
    6  
    7 recurse(13);
    8 </script>

    Проблема здесь возникает из-за того, что функция напрямую присвоена вwindow.recurse = .... Ее не будет при обычном объявлении функции.

    Этот пример выдаст ошибку только в настоящем IE8! Не IE9 в режиме эмуляции. Вообще, режим эмуляции позволяет отлавливать где-то 95% несовместимостей и проблем, а для оставшихся 5% вам нужен будет настоящий IE8 в виртуальной машине.

 

Итого

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

  1. Функции, объявленные как Function Declaration, создаются полностью и готовы к использованию.
  2. Переменные объявлены, но равны undefined. Присваивания выполнятся позже, когда выполнение дойдет до них.

 

Важность: 5

Каков будет результат кода?

1 if ("a" in window) {
2     var a = 1;
3 }
4 alert(a);

 

Решение

Ответ: 1.

 

   
1 if ("a" in window) {
2     var a = 1;
3 }
4 alert(a);

 

Посмотрим, почему.

На стадии подготовки к выполнению, из var a создается window.a:

1 // window = {a:undefined}
2  
3 if ("a" in window) { // в if видно что window.a уже есть
4     var a = 1; // поэтому эта строка сработает
5 }
6 alert(a);

 

В результате a становится 1.

[Открыть задачу в новом окне]

Важность: 5

Каков будет результат (перед a нет var)?

1 if ("a" in window) {
2     a = 1;
3 }
4 alert(a);

 

Решение

Ответ: ошибка.

Переменной a нет, так что условие "a" in window не выполнится. В результате на последней строчке - обращение к неопределенной переменной.

 

   
1 if ("a" in window) {
2     a = 1;
3 }
4 alert(a);  // <-- error!

 

[Открыть задачу в новом окне]

 

 

Важность: 5

Каков будет результат (перед a нет var, а ниже есть)?

1 if ("a" in window) {
2     a = 1;
3 }
4 var a;
5  
6 alert(a);

 

Решение

Ответ: 1.

Переменная a создается до начала выполнения кода, так что условие "a" in windowвыполнится и сработает a = 1.

 

   
1 if ("a" in window) {
2     a = 1;
3 }
4 var a;
5  
6 alert(a); // 1

 

[Открыть задачу в новом окне]

Важность: 3

Каков будет результат кода? Почему?

1 var a = 5;
2   
3 function a() { }
4  
5 alert(a);

 

P.S. Это задание — учебное, на понимание процесса инициализации и выполнения. В реальной жизни мы, конечно же, не будем называть переменную и функцию одинаково.

Решение

Ответ: 5.

 

   
1 var a = 5;
2   
3 function a() { }
4  
5 alert(a);

 

Чтобы понять, почему — разберем внимательно как работает этот код.

  1. До начала выполнения создается переменная a и функция a. Стандарт написан так, что функция создается первой и переменная ее не перезаписывает. То есть, функция имеет приоритет. Но в данном случае это совершенно неважно, потому что…
  2. …После инициализации, когда код начинает выполняться — срабатывает присваивание a = 5, перезаписывая a, и уже не важно, что там лежало.
  3. Объявление Function Declaration на стадии выполнения игнорируется (уже обработано).
  4. В результате alert(a) выводит 5.

К сожалению, в одной статье не просто дать все знания про глобальный объект. Но я - старался. Если ты проявишь интерес к раскрытию подробностей,я обязательно напишу продолжение! Надеюсь, что теперь ты понял что такое глобальный объект и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)

создано: 2014-10-07
обновлено: 2021-03-13
132585



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей



Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)

Термины: Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)