Конспект JS-course

Задачи

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

if ("a" in window) {
    var a = 1;
}

alert(a);

Ответ:

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

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

// window = {a:undefined}

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

alert(a);

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

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

if ("a" in window) {
    a = 1;
}

alert(a);

Ответ:

Ошибка.

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

if ("a" in window) {
    a = 1;
}

alert(a);  // <-- error!

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

if ("a" in window) {
    a = 1;
}
var a;

alert(a);

Ответ:

Одному.

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

if ("a" in window) {
    a = 1;
}
var a;

alert(a); // 1

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

var a = 5;
function a() { }

alert(a);

Ответ:

5.

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

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

5. Каков будет результат выполнения этого кода?

var value = 0;

function f() {
  if (1) {
    value = true;
  } else {
    var value = false;
  }
  alert(value);
}

f();

Изменится ли внешняя переменная value ?

P.S. Какими будут ответы, если из строки var value = false убрать var ?

Ответ:

Результатом будет true, т.к. var обработается и переменная будет создана до выполнения кода.

Соответственно, присвоение value = true сработает на локальной переменной, и alert выведет true.

Внешняя переменная не изменится.

P.S. Если var нет, то в функции переменная не будет найдена. Интерпретатор обратится за ней в window и изменит её там.

Так что без var результат будет также true, но внешняя переменная изменится.

6. Каков будет результат выполнения этого кода? Почему?

function test() {
  alert(window);
  var window = 5;
  alert(window);
}

test();

Ответ:

Результатом будет undefined, затем 5.

Директива var обработается до начала выполнения кода функции. Будет создана локальная переменная, т.е. свойство LexicalEnvironment:

LexicalEnvironment = {
  window: undefined
}

Когда выполнение кода начнется и сработает alert , он выведет локальную переменную. Затем сработает присваивание, и второй alert выведет уже 5.

7. Каков будет результат выполнения кода? Почему?

var a = 5

(function() {
  alert(a)
})()

P.S. Подумайте хорошо! Здесь все ошибаются! P.P.S. Внимание, здесь подводный камень! Ок, вы предупреждены.

Ответ:

Результат - ошибка.

Дело в том, что после var a = 5 нет точки с запятой.

JavaScript воспринимает этот код как если бы перевода строки не было:

var a = 5(function() {
  alert(a)
})()

То есть, он пытается вызвать функцию 5, что и приводит к ошибке.

Если точку с запятой поставить, все будет хорошо. Это один из наиболее частых и опасных подводных камней, приводящих к ошибкам тех, кто не ставит точки с запятой.

8. Еще задача на понятие замыканий

  1. Будет ли работать доступ к переменной name через замыкание в примере ниже?
  2. Удалится ли переменная name из памяти при выполнении delete donkey.sayHi ? Если нет — можно ли к name как-то обратиться после удаления donkey.sayHi ?
  3. А если присвоить donkey.sayHi = donkey.yell = null — останется ли name в памяти?
var makeDonkey = function() {
   var name = "Ослик Иа";

   return {
       sayHi: function() {
         alert(name);
       },
       yell: function() {
         alert('И-а, и-а!');
       }
   };
}
var donkey = makeDonkey();
donkey.sayHi();

Решение:

  1. Да, будет работать, благодаря ссылке [[Scope]] на внешний объект переменных, которая будет присвоена функциям sayHi и yell при создании объекта.
  2. Нет, name не удалится из памяти, поскольку несмотря на то, что sayHi больше нет, есть ещё функция yell , которая также ссылается на внешний объект переменных. Этот объект хранится целиком, вместе со всеми свойствами. При этом, так как функция sayHi удалена из объекта и ссылок на нее нет, то больше к переменной name обращаться некому. Получилось, что она «застряла» в памяти, хотя, по сути, никому не нужна.
  3. Если и sayHi и yell удалить, тогда, так как больше внутренних функций не останется, удалится и объект переменных вместе с name .

Дополнительно

  1. Напишите функцию sum, которая работает так: sum(a)(b) = a + b. READ
  2. Функция filter(arr, func). READ