четверг, 25 сентября 2014 г.

Функции JavaScript. Часть 1: function declaration and function expression

Объявление (function declaration):

function имя(параметры, через, запятую) {
 код функции;
 [return [значение];]
}

Внутри функции можно объявить переменную с локальной областью видимости. При совпадении имен с внешними переменными они переопределяются.

Функция, выполняющаяся без return или с return без значения возвращает undefined
Если параметр не передан при вызове, он считается undefined. Таким параметрам можно присваивать “значение по умолчанию”:

if (param === undefined) { param = value; }
или
param = param || value;

Фактически при подобном объявлении создается переменная (объект типа function) с которой связывается некоторый набор команд, составляющий функцию. Данный объект имеет свойство name, содержащее в себе имя функции. Функцию можно присвоить новой переменной, обнулив старую:

function f() { return 10; }
g = f;
f = null;
g();    // > 10
g.name; // > f
f();    // > TypeError - object is not function

Функции, объявленные как function declaration, создаются интерпретатором до выполнения основного кода, следовательно невозможно, например. их условное определение.

Существует иной формат объявления - функциональное выражение (function expression).  В этом случае объявление входит в состав какого-либо выражения:

var n = function() {};
(function m(){});
+function() {};

Из контекста интерпретатору должно быть очевидно, что это не function declaration. Функциональные выражения могут быть именованными или анонимными:

x = function() {};   // Anonymous function expression
x.name;              // > 
f = function g() {}; // Named function expression
f.name;              // > g
g();                 // > ReferenceError 
                     // До IE9 создавался дополнительный объект g

Во втором случае переменной f типа function присваивается ссылка на некоторый код (в данном случае пустой), f.name присваивается значение ‘g’. Имя функционального выражения становится доступным только внутри функции (при обращении к нему будет получен код функции или [Function: name] для js.node).

Имя g() доступно из самой функции, это применяется в рекурсивных вызовах и при отладке..

Функция может быть выполнена сразу же в момент объявления с некоторыми аргументами:

(function (arg) { return arg * arg; })(4); // > 16
+function (arg) { return arg * arg; }(4);  // > 16
!function (arg) { return arg * arg; }(4);  // > false

В последнем случае оператор ! способствует тому, чтобы объявление функции воспринималось как function expression, но одновременно производит действия над результатом функции (!16 === 0).

Возможны также вариант с по сути анонимным конструктором:

new function(arg) { console.log ( arg * arg ) }(4);

и даже эзотерический

new function() { 
return function (arg2) { return arg2 * arg2 } 
}()(4); // > 16

Первый вариант пригоден только в качестве процедуры, т.к. возвращает объект не пригодный к использованию, второй возвращает значение.

Создание функционального выражения происходит в момент объявления, поэтому переменной можно присвоить различные функциональные выражения в зависимости от условий.


Комментариев нет :

Отправить комментарий