05. Переменные

Контрольные вопросы

  1. Испытательный стенд Какое значение получит переменная y? Ответ объясните.

    
    function f()
    {
      x = 2; 
    }
    y = x; 
    
    Ответ

    Ошибка времени исполнения: вызова функции f не было, глобальная переменная x не создана, обращение к этой переменной приводит к ошибке.

  2. Испытательный стенд Какое значение получит переменная y. Ответ объясните.

    
    function f()
    {
      x = 2; 
    }
    f();
    y = x; 
    
    Ответ

    Ответ: 2. Пояснение: неописанная в функции f переменная x становится глобальной в момент вызова функции.

  3. Испытательный стенд Какое значение получит переменная x? Ответ объясните.

    
    var z; 
    var x = "1" + z; 
    
    Ответ

    Ответ: строка "1undefined". При создании переменная автоматически получает значение undefined.

  4. Испытательный стенд Какое значение получит переменная y? Ответ объясните.

    
    01 var x = 2;   
    02 function f(t)
    03 {
    04   return ++t+window.x;
    05 }
    06 var y = f(x); 
    
    Ответ

    Ответ: 5.

    В строке 01 объявляется глобальная переменная x, и ей присваивается значение 2.

    В строках 02–05 записано определение функции f. По этому определению создается глобальная переменная f, и в нее записывается ссылка на определение функции, а сама функция сохраняется где-то в памяти.

    В строке 06 объявляется глобальная переменная у и ей присваивается значение выражения f(x). f — это ссылка на функцию, а () — оператор вызова функции. Аргумент вызова один — в функцию передается значение переменной x, то есть число 2.

    Функция вычисляется следующим образом. По заголовку в строке 02 создается локальная переменная t, и ей присваивается значение переданного аргумента, то есть число 2.

    Приоритет оператора ++ выше приоритета оператора +, поэтому он выполняется первым и переменная t получает значение 3. Затем выполняется оператор +. Число 3 складывается со значением переменной window.x, то есть просто с глобальной переменной x. Получается 3+2, то есть 5. Значение 5 возвращается как результат выполнения функции, значит, y получает значение 5. Заметим, что при выходе из функции локальная переменная t уничтожается.

  5. Испытательный стенд Какие значения получат переменные y и z? Ответ объясните.

    
    01 function f(t)
    02 {
    03   var r = t;
    04   r.p++;
    05   return r;
    06 }
    07 var ob = {p:1};
    08 var x = f(ob);
    09 var y = x.p;
    10 var z = ob.p; 
    
    Ответ

    Ответ: переменные y и z получат одинаковое значение — число 2.

    В строках 01–06 записано определение функции f. По этому определению создается глобальная переменная f, и в нее записывается ссылка на определение функции, а сама функция сохраняется где-то в памяти.

    В строке 07 создается (где-то в памяти) объект {p:1} и ссылка на него записывается в глобальную переменную ob.

    В строке 08 глобальной переменной x присваивается значение, возвращаемое из функции f.

    Посмотрим, как будет работать функция.

    1. Создаётся локальная переменная t.
    2. Переменной t присваивается ссылка на глобальный объект ob.
    3. Создается локальная переменная r, и ей присваивается значение, записанное в переменной t, то есть ссылка на глобальный объект ob. Теперь обе локальные переменные t и r содержат одно и тоже значение — ссылку на глобальный объект ob.
    4. Инструкция r.p++; выполняется так. На 1 увеличивается значение свойства p объекта, на который ссылается переменная r. То есть на 1 будет увеличено значение свойства p объекта ob.
    5. Возвращается значение переменной r, то есть ссылка на глобальный объект ob.
    6. Локальные переменные t и r уничтожаются.

    Получается, что в строке 08 переменной x присваивается ссылка на глобальный объект ob. Переменные ob и x содержат теперь ссылку на один и тот же объект (который расположен где-то в памяти).

    В строке 09 переменная y получает значение свойства p объекта, то есть число 2 (вспомним, что значение этого свойства было увеличено на 1 внутри функции).

    В строке 10 переменной z также присвоено значение свойства p этого объекта (то есть число 2).

    Заметим, что в приведенном коде объект создается всего лишь один раз. Код в строках 01–10 эквивалентен следующему коду:

    
    function f(t) { t.p++; }
    var ob = {p:1};
    f(ob);
    var y = ob.p;
    var z = ob.p; 
    

    Переменные y и p получат одно и тоже значение свойства p объекта ob, то есть число 2.

  6. Испытательный стенд Какие значения получат переменные y и z? Ответ объясните и поясните разницу этого кода с кодом вопроса 5.

    
    01 function f (t)
    02 {
    03   var r = {};
    04   r.p = t.p;
    05   r.p++;
    06   return r;
    07 }
    08 var ob = {p:1};
    09 var x = f(ob);
    10 var y = x.p;
    11 var z = ob.p; 
    
    Ответ

    Ответ: y равно 2, а z равно 1.

    В строках 01–07 записано определение функции f. По этому определению создается глобальная переменная f, и в нее записывается ссылка на определение функции, а сама функция сохраняется где-то в памяти.

    В строке 08 создается (где-то в памяти) объект {p:1}, и ссылка на него записывается в глобальную переменную ob.

    В строке 09 глобальной переменной x присваивается значение, возвращаемое из функции f.

    Посмотрим, как будет работать функция.

    1. В строке 01 создаётся локальная переменная t, и ей присваивается ссылка на глобальный объект ob.
    2. В строке 03 создаётся локальная переменная r, и ей присваивается ссылка на пустой объект, который сохраняется где-то в памяти (вне функции).
    3. В строке 04 создаётся свойство p пустого объекта, и этому свойству присваивается значение свойства ob.p (то есть число 1). Теперь где-то в памяти расположены два идентичных объекта {p:1}. На первый объект ссылается глобальная переменная ob и локальная переменная t. На второй — только локальная переменная r.
    4. В строке 05 значение свойства p объекта r увеличивается на 1 (стало {p:2}). Объект ob при этом не меняется (остается {p:1}).
    5. Из функции возвращается ссылка на объект r (который расположен где-то в памяти за пределами функции).
    6. Локальные переменные t и r уничтожаются (но сам объект, на который ссылалось r, хранится где-то в памяти).

    Таким образом, в строке 09 переменная x получает ссылку на объект {p:2} (который не есть ob).

    В строке 10 переменная y получает значение 2 (обращение к объекту {p:2}).

    В строке 11 переменная z получает значение 1 (обращение к объекту {p:1}).

    Отличие от кода вопроса 5 в том, что в данном коде реально создается в функции новый объект, а в коде вопроса 5 — нет.

  7. Испытательный стенд Какие значения получат переменные y и z? Ответ объясните.

    
    01 function Point(x, y)
    02 {
    03   this.x = x;
    04   this.y = y;
    05 } 
    06 var p1 = new Point(1,2);
    07 var p2 = p1;
    08 var x = (p1 == p2);
    09 var p3 = new Point(1,2);
    10 var y = (p1 == p3);
    11 var z = (p1.x == p3.x);
    
    Ответ

    Ответ: y равно false, а z равно true.

    В строках 01–05 записано определение функции Point. По этому определению создается глобальная переменная Point, и в нее записывается ссылка на определение функции, а сама функция сохраняется где-то в памяти.

    В строке 06 функция Point используется как конструктор совместно с оператором new. Оператор new создаёт пустой объект {} (где-то в памяти) и передает ссылку на него в виде неявного аргумента this в функцию Pоint. По инструкциям в строках 03 и 04 в этом пустом объекте создаются свойства x и y, и им присваиваются значения 1 и 2 (значения явных аргументов). Ссылка на созданный объект {x:1,y:2} записывается в переменную p1.

    В строке 07 ссылка на созданный объект копируется из p1 в p2. Теперь и p1 и p2 ссылаются на один и тот же объект.

    Выражение (p1 == p2) в строке 08 равно true, так как значения переменных p1 и p2 содержат ссылку на один и тот же объект. То есть переменная x получает значение true.

    В строке 09 создается новый объект {x:1,y:2} (где-то в памяти), и ссылка на него записывается в переменную p3.

    Выражение (p1 == p3) в строке 10 равно false, так как значения переменных p1 и p3 содержат разные ссылки (на разные места в памяти). То есть переменная y получает значение false.

    Выражение (p1.x == p3.x) в строке 11 равно true, так как значения свойств x разных объектов p1 и p3 совпадают и равны числу 1. То есть переменная z получает значение true.

  8. Испытательный стенд Какое значение получит переменная x? Ответ объясните.

    
    01 function Point(x, y)
    02 {
    03   this.x = x;
    04   this.y = y;
    05 } 
    06 function addPoint(p1, p2)
    07 {
    08   var ob = p1;
    09   ob.x += p2.x;
    10   ob.y += p2.y;
    11   return ob;
    12 } 
    13 var t1 = new Point(1,2);
    14 var t2 = new Point(3,4);
    15 var t3 = addPoint(t1, t2);
    16 var x  = (t1.x == t3.x);
    
    Ответ

    Ответ: x равно true.

    В строках 13 и 14 создаются два объекта t1 и t2 при помощи конструктора Point: {x:1,y:2} и {x:3,y:4}.

    В строке 15 переменной t3 присваивается значение, возвращаемое из функции addPoint. Посмотрим, как будет работать эта функция.

    Строка 06. Создаются локальные переменные p1, p2 и им присваиваются ссылки на объекты t1 и t2.

    Строка 08. Теперь на t1 указывает и ob (копия объекта не создается).

    Строки 09 и 10. Меняется объект t1: значения его свойств увеличиваются на значения аналогичных свойств объекта t2, то есть становятся равными {x:4,y:6}.

    Строка 11. Функция возвращает ссылку на объект t1.

    Таким образом, t3 в строке 15 получает ссылку на объект t1 (свойства которого были изменены в функции addPoint).

    Так как t1 и t3 указывают на один и тот же объект, то выражение (t1.x == t3.x) в строке 16 равно true.

    То есть переменная x получает значение true.

    Заметим, что true есть значение и следующих выражений:

    
    t1.y == t3.y;  // true
    t1 == t3;      // true
    
  9. Испытательный стенд Какое значение получит переменная x? Ответ объясните.

    
    01 function Point(x, y)
    02 {
    03   this.x = x;
    04   this.y = y;
    05 } 
    06 function addPoint(p1, p2)
    07 {
    08   var ob = new Point(p1.x, p2.y);
    09   ob.x += p2.x;
    10   ob.y += p2.y;
    11   return ob;
    12 } 
    13 var t1 = new Point(1,2);
    14 var t2 = new Point(3,4);
    15 var t3 = addPoint(t1, t2);
    16 var x  = (t1.x == t3.x);
    
    Ответ

    Ответ: x равно false.

    В строках 13 и 14 создаются два объекта t1 и t2 при помощи конструктора Point: {x:1,y:2} и {x:3,y:4}.

    В строке 15 переменной t3 присваивается значение, возвращаемое из функции addPoint. Посмотрим, как будет работать эта функция.

    Строка 06. Создаются локальные переменные p1, p2 и им присваиваются ссылки на объекты t1 и t2.

    Строка 08. Создается новый объект {x:1,y:4}, и ссылка на него записывается в локальную переменную ob.

    Строки 09 и 10. Меняется объект ob: значения его свойств увеличиваются на значения аналогичных свойств объекта t2, то есть становятся равными {x:4,y:8}.

    Строка 11. Функция возвращает ссылку на объект ob. Заметим, что объекты t1 и t2 функция не изменила.

    Таким образом, t3 в строке 15 получает ссылку на объект {x:4,y:8}.

    Выражение (t1.x == t3.x) в строке 16 эквивалентно (1 == 4), то есть равно false.

    Переменная x в строке 16 получает значение false.

  10. Испытательный стенд Какие значения получат переменные x и y? Ответ объясните.

    
    01 function addStr(s)
    02 {
    03  s = "эта" +s;
    04  return s;
    05 }
    06 var t = "жерка";
    07 var x = addStr(t);
    08 var y = (t == x);
    
    Ответ

    Ответ: x равно строке "этажерка", y равно false,

    В строке 07 переменная x получает значение, возвращаемое функцией addStr. Посмотрим, как будет работать эта функция.

    В строке 01 создается локальная переменная s, и этой переменной присваивается строка "жерка".

    В строке 03 переменная s получает значение "этажерка".

    В строке 04 строка "этажерка" возвращается, как результат работы функции. Следовательно, переменная x в строке 07 получает значение "этажерка".

    Так как значение переменной t не изменилось в функции (строки передаются по значению), то выражение (t == x) в строке 08 эквивалентно выражению ("жерка" == "этажерка"), то есть равно false. Именно это значение получает переменная y.