СпеÑиалÑно Ð´Ð»Ñ ÑабоÑÑ Ñ ÑекÑÑÑией в JavaScript ÑÑÑеÑÑвÑÐµÑ Ð¾Ñобое ÑаÑÑиÑение ÑÑнкÑионалÑнÑÑ Ð²ÑÑажений, коÑоÑое назÑваеÑÑÑ Â«Named Function Expression» (ÑокÑаÑÑнно NFE) или, по-ÑÑÑÑки, «именованное ÑÑнкÑионалÑное вÑÑажение».
Named Function Expression
ÐбÑÑное ÑÑнкÑионалÑное вÑÑажение:
var f = function(...) { /* Ñело ÑÑнкÑии */ };
Ðменованное Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ sayHi:
var f = function sayHi(...) { /* Ñело ÑÑнкÑии */ };
ЧÑо же ÑÑо за имÑ, коÑоÑое идÑÑ Ð² дополнение к f, и заÑем оно?
ÐÐ¼Ñ ÑÑнкÑионалÑного вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ (sayHi) Ð¸Ð¼ÐµÐµÑ Ð¾ÑобÑй ÑмÑÑл. Ðно доÑÑÑпно ÑолÑко изнÑÑÑи Ñамой ÑÑнкÑии (f).
ÐÑо огÑаниÑение видимоÑÑи Ð²Ñ Ð¾Ð´Ð¸Ñ Ð² ÑÑандаÑÑ JavaScript и поддеÑживаеÑÑÑ Ð²Ñеми бÑаÑзеÑами, кÑоме IE8-.
ÐапÑимеÑ:
var f = function sayHi(name) {
alert( sayHi ); // изнÑÑÑи ÑÑнкÑии - видно (вÑÐ²ÐµÐ´ÐµÑ ÐºÐ¾Ð´ ÑÑнкÑии)
};
alert( sayHi ); // ÑнаÑÑжи - не видно (оÑибка: undefined variable 'sayHi')
ÐÑоме Ñого, Ð¸Ð¼Ñ NFE нелÑÐ·Ñ Ð¿ÐµÑезапиÑаÑÑ:
var test = function sayHi(name) {
sayHi = "ÑеÑÑ"; // попÑÑка пеÑезапиÑи
alert( sayHi ); // function... (пеÑезапиÑÑ Ð½Ðµ ÑдалаÑÑ)
};
test();
Ð Ñежиме use strict код вÑÑе вÑдал Ð±Ñ Ð¾ÑибкÑ.
Ðак пÑавило, Ð¸Ð¼Ñ NFE иÑполÑзÑеÑÑÑ Ð´Ð»Ñ ÐµÐ´Ð¸Ð½ÑÑвенной Ñели â позволиÑÑ Ð¸Ð·Ð½ÑÑÑи ÑÑнкÑии вÑзваÑÑ ÑÐ°Ð¼Ñ ÑебÑ.
ÐÑÐ¸Ð¼ÐµÑ Ð¸ÑполÑзованиÑ
NFE иÑполÑзÑеÑÑÑ Ð² пеÑвÑÑ Ð¾ÑеÑÐµÐ´Ñ Ð² ÑÐµÑ ÑиÑÑаÑиÑÑ , когда ÑÑнкÑÐ¸Ñ Ð½Ñжно пеÑедаваÑÑ Ð² дÑÑгое меÑÑо кода или пеÑемеÑаÑÑ Ð¸Ð· одной пеÑеменной в дÑÑгÑÑ.
ÐнÑÑÑеннее Ð¸Ð¼Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÐµÑ ÑÑнкÑии надÑжно обÑаÑаÑÑÑÑ Ðº Ñамой Ñебе, где Ð±Ñ Ð¾Ð½Ð° ни Ð½Ð°Ñ Ð¾Ð´Ð¸Ð»Ð°ÑÑ.
ÐÑпомним, к пÑимеÑÑ, ÑÑнкÑиÑ-ÑакÑоÑиал из задаÑи ÐÑÑиÑлиÑÑ ÑакÑоÑиал:
function f(n) {
return n ? n * f(n - 1) : 1;
};
alert( f(5) ); // 120
ÐопÑобÑем пеÑенеÑÑи ÐµÑ Ð² дÑÑгÑÑ Ð¿ÐµÑеменнÑÑ g:
function f(n) {
return n ? n * f(n - 1) : 1;
};
var g = f;
f = null;
alert( g(5) ); // запÑÑк ÑÑнкÑии Ñ Ð½Ð¾Ð²Ñм именем - оÑибка пÑи вÑполнении!
ÐÑибка возникла поÑÐ¾Ð¼Ñ ÑÑо ÑÑнкÑÐ¸Ñ Ð¸Ð· Ñвоего кода обÑаÑаеÑÑÑ Ðº ÑÐ²Ð¾ÐµÐ¼Ñ ÑÑаÑÐ¾Ð¼Ñ Ð¸Ð¼ÐµÐ½Ð¸ f. Ð ÑÑой ÑÑнкÑии Ñже неÑ, f = null.
ÐÐ»Ñ Ñого, ÑÑÐ¾Ð±Ñ ÑÑнкÑÐ¸Ñ Ð²Ñегда надÑжно ÑабоÑала, обÑÑвим ÐµÑ ÐºÐ°Ðº Named Function Expression:
var f = function factorial(n) {
return n ? n*factorial(n-1) : 1;
};
var g = f; // ÑкопиÑовали ÑÑÑÐ»ÐºÑ Ð½Ð° ÑÑнкÑиÑ-ÑакÑоÑиал в g
f = null;
alert( g(5) ); // 120, ÑабоÑаеÑ!
Ðак Ð¼Ñ Ð³Ð¾Ð²Ð¾Ñили вÑÑе, в бÑаÑзеÑе IE до 9 веÑÑии Ð¸Ð¼Ñ NFE видно везде, ÑÑо ÑвлÑеÑÑÑ Ð¾Ñибкой Ñ ÑоÑки зÑÐµÐ½Ð¸Ñ ÑÑандаÑÑа.
â¦Ðо на Ñамом деле ÑиÑÑаÑÐ¸Ñ ÐµÑÑ Ð·Ð°Ð±Ð°Ð²Ð½ÐµÐµ. СÑаÑÑй IE ÑоздаÑÑ Ð² ÑакиÑ
ÑлÑÑаÑÑ
ÑелÑÑ
две ÑÑнкÑии: одна запиÑÑваеÑÑÑ Ð² пеÑеменнÑÑ f, а вÑоÑÐ°Ñ â в пеÑеменнÑÑ factorial.
ÐапÑимеÑ:
var f = function factorial(n) { /*...*/ };
// в IE8- false
// в оÑÑалÑнÑÑ
бÑаÑзеÑаÑ
оÑибка, Ñ.к. Ð¸Ð¼Ñ factorial не видно
alert( f === factorial );
ÐÑе оÑÑалÑнÑе бÑаÑзеÑÑ Ð¿Ð¾Ð»Ð½Ð¾ÑÑÑÑ Ð¿Ð¾Ð´Ð´ÐµÑживаÑÑ Ð¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð½Ñе ÑÑнкÑионалÑнÑе вÑÑажениÑ.
arguments.calleeÐÑли Ð²Ñ Ð´Ð°Ð²Ð½Ð¾ ÑабоÑаеÑе Ñ JavaScript, Ñо, возможно, знаеÑе, ÑÑо ÑанÑÑе Ð´Ð»Ñ ÑÑой Ñели Ñакже ÑлÑжило ÑпеÑиалÑное знаÑение arguments.callee.
ÐÑли ÑÑо название вам ни о ÑÑм не говоÑÐ¸Ñ â вÑÑ Ð² поÑÑдке, ÑиÑайÑе далÑÑе, Ð¼Ñ Ð¾Ð±ÑзаÑелÑно обÑÑдим его в оÑделÑной главе.
ÐÑли же Ð²Ñ Ð² кÑÑÑе, Ñо ÑÑÐ¾Ð¸Ñ Ð¸Ð¼ÐµÑÑ Ð² видÑ, ÑÑо оно оÑиÑиалÑно иÑклÑÑено из ÑовÑеменного ÑÑандаÑÑа. Ð NFE â ÑÑо наÑе наÑÑоÑÑее.
ÐÑого
ÐÑли ÑÑнкÑÐ¸Ñ Ð·Ð°Ð´Ð°Ð½Ð° как Function Expression, ей можно даÑÑ Ð¸Ð¼Ñ.
Ðно бÑÐ´ÐµÑ Ð´Ð¾ÑÑÑпно ÑолÑко внÑÑÑи ÑÑнкÑии (кÑоме IE8-).
ÐÑо Ð¸Ð¼Ñ Ð¿ÑедназнаÑено Ð´Ð»Ñ Ð½Ð°Ð´Ñжного ÑекÑÑÑивного вÑзова ÑÑнкÑии, даже еÑли она запиÑана в дÑÑгÑÑ Ð¿ÐµÑеменнÑÑ.
ÐбÑаÑим внимание, ÑÑо Ñ Function Declaration Ñак поÑÑÑпиÑÑ Ð½ÐµÐ»ÑзÑ. Такое «ÑпеÑиалÑное» внÑÑÑеннее Ð¸Ð¼Ñ ÑÑнкÑии задаÑÑÑÑ ÑолÑко в ÑинÑакÑиÑе Function Expression.
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)