Выразительный JavaScript | страница 27



JavaScript очень лоялен по поводу количества аргументов, передаваемых функции. Если вы передадите слишком много, лишние будут проигнорированы. Слишком мало – отсутствующим будет назначено значение >undefined.

Минус этого подхода в том, что возможно – и даже вероятно – передать функции неправильное количество аргументов, и вам никто на это не пожалуется.

Плюс в том, что вы можете создавать функции, принимающие необязательные аргументы. К примеру, в следующей версии функции power её можно вызывать как с двумя, так и с одним аргументом. В последнем случае экспонента будет равна двум, и функция работает как квадрат.

>function power(base, exponent) {

>  if (exponent == undefined)

>    exponent = 2;

>  var result = 1;

>  for (var count = 0; count < exponent; count++)

>    result *= base;

>  return result;

>}


>console.log(power(4));

>// → 16

>console.log(power(4, 3));

>// → 64

В следующей главе мы увидим, как в теле функции можно узнать точное число переданных ей аргументов. Это полезно, т. к. позволяет создавать функцию, принимающую любое количество аргументов. К примеру, >console.log использует это свойство, и выводит все переданные ей аргументы:

>console.log("R", 2, "D", 2);

>// → R 2 D 2

Замыкания

Возможность использовать вызовы функций как переменные вкупе с тем фактом, что локальные переменные каждый раз при вызове функции создаются заново, приводит нас к интересному вопросу. Что происходит с локальными переменными, когда функция перестаёт работать?

Следующий пример иллюстрирует этот вопрос. В нём объявляется функция >wrapValue, которая создаёт локальную переменную. Затем она возвращает функцию, которая читает эту локальную переменную и возвращает её значение.

>function wrapValue(n) {

>  var localVariable = n;

>  return function() { return localVariable; };

>}


>var wrap1 = wrapValue(1);

>var wrap2 = wrapValue(2);

>console.log(wrap1());

>// → 1

>console.log(wrap2());

>// → 2

Это допустимо и работает так, как должно – доступ к переменной остаётся. Более того, в одно и то же время могут существовать несколько экземпляров одной и той же переменной, что ещё раз подтверждает тот факт, что с каждым вызовом функции локальные переменные пересоздаются.

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