СÑÑеÑÑвÑÐµÑ ÐµÑÑ Ð¾Ð´Ð¸Ð½ ваÑÐ¸Ð°Ð½Ñ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ÑÑнкÑии. Ðн иÑполÑзÑеÑÑÑ ÐºÑайне Ñедко, но иногда дÑÑгого ÑеÑÐµÐ½Ð¸Ñ Ð½Ðµ найÑи.
СинÑакÑиÑ
СинÑакÑÐ¸Ñ Ð´Ð»Ñ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ÑÑнкÑии:
let func = new Function([arg1, arg2, ...argN], functionBody);
ФÑнкÑÐ¸Ñ ÑоздаÑÑÑÑ Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ñми аÑгÑменÑами arg1...argN и Ñелом functionBody.
ÐÑо пÑоÑе понÑÑÑ Ð½Ð° конкÑеÑном пÑимеÑе. ÐдеÑÑ Ð¾Ð±ÑÑвлена ÑÑнкÑÐ¸Ñ Ñ Ð´Ð²ÑÐ¼Ñ Ð°ÑгÑменÑами:
let sum = new Function('a', 'b', 'return a + b');
alert( sum(1, 2) ); // 3
Ð Ð²Ð¾Ñ ÑÑнкÑÐ¸Ñ Ð±ÐµÐ· аÑгÑменÑов, в ÑÑом ÑлÑÑае доÑÑаÑоÑно ÑказаÑÑ ÑолÑко Ñело:
let sayHi = new Function('alert("Hello")');
sayHi(); // Hello
Ðлавное оÑлиÑие Ð¾Ñ Ð´ÑÑÐ³Ð¸Ñ ÑпоÑобов обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ÑÑнкÑии, коÑоÑÑе бÑли ÑаÑÑмоÑÑÐµÐ½Ñ Ñанее, заклÑÑаеÑÑÑ Ð² Ñом, ÑÑо ÑÑнкÑÐ¸Ñ ÑоздаÑÑÑÑ Ð¿Ð¾Ð»Ð½Ð¾ÑÑÑÑ Â«Ð½Ð° леÑÑ» из ÑÑÑоки, пеÑеданной во вÑÐµÐ¼Ñ Ð²ÑполнениÑ.
ÐÑе пÑедÑдÑÑие обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ÑÑебовали Ð¾Ñ Ð½Ð°Ñ, пÑогÑаммиÑÑов, пиÑаÑÑ Ð¾Ð±ÑÑвление ÑÑнкÑии в ÑкÑипÑе.
Ðо new Function позволÑÐµÑ Ð¿ÑевÑаÑиÑÑ Ð»ÑбÑÑ ÑÑÑÐ¾ÐºÑ Ð² ÑÑнкÑиÑ. ÐапÑимеÑ, можно полÑÑиÑÑ Ð½Ð¾Ð²ÑÑ ÑÑнкÑÐ¸Ñ Ñ ÑеÑвеÑа и заÑем вÑполниÑÑ ÐµÑ:
let str = ... код, полÑÑеннÑй Ñ ÑеÑвеÑа динамиÑеÑки ...
let func = new Function(str);
func();
ÐÑо иÑполÑзÑеÑÑÑ Ð² оÑÐµÐ½Ñ ÑпеÑиÑиÑеÑÐºÐ¸Ñ ÑлÑÑаÑÑ , напÑимеÑ, когда Ð¼Ñ Ð¿Ð¾Ð»ÑÑаем код Ñ ÑеÑвеÑа Ð´Ð»Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÑеÑкой компилÑÑии ÑÑнкÑии из Ñаблона, в ÑложнÑÑ Ð²ÐµÐ±-пÑиложениÑÑ .
ÐамÑкание
ÐбÑÑно ÑÑнкÑÐ¸Ñ Ð·Ð°Ð¿Ð¾Ð¼Ð¸Ð½Ð°ÐµÑ, где ÑодилаÑÑ, в ÑпеÑиалÑном ÑвойÑÑве [[Environment]]. ÐÑо ÑÑÑлка на лекÑиÑеÑкое окÑÑжение (Lexical Environment), в коÑоÑом она Ñоздана (Ð¼Ñ ÑазбиÑали ÑÑо в главе ÐблаÑÑÑ Ð²Ð¸Ð´Ð¸Ð¼Ð¾ÑÑи пеÑеменнÑÑ
, замÑкание).
Ðо когда ÑÑнкÑÐ¸Ñ ÑоздаÑÑÑÑ Ñ Ð¸ÑполÑзованием new Function, в ÐµÑ [[Environment]] запиÑÑваеÑÑÑ ÑÑÑлка не на внеÑнее лекÑиÑеÑкое окÑÑжение, в коÑоÑом она бÑла Ñоздана, а на глобалÑное. ÐоÑÑÐ¾Ð¼Ñ ÑÐ°ÐºÐ°Ñ ÑÑнкÑÐ¸Ñ Ð¸Ð¼ÐµÐµÑ Ð´Ð¾ÑÑÑп ÑолÑко к глобалÑнÑм пеÑеменнÑм.
function getFunc() {
let value = "test";
let func = new Function('alert(value)');
return func;
}
getFunc()(); // оÑибка: value не опÑеделено
СÑавним ÑÑо Ñ Ð¾Ð±ÑÑнÑм обÑÑвлением:
function getFunc() {
let value = "test";
let func = function() { alert(value); };
return func;
}
getFunc()(); // "test", из лекÑиÑеÑкого окÑÑÐ¶ÐµÐ½Ð¸Ñ ÑÑнкÑии getFunc
ÐÑа оÑобенноÑÑÑ new Function вÑглÑÐ´Ð¸Ñ ÑÑÑанно, но оказÑваеÑÑÑ Ð¾ÑÐµÐ½Ñ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð¾Ð¹ на пÑакÑике.
ÐÑедÑÑавÑÑе, ÑÑо нÑжно ÑоздаÑÑ ÑÑнкÑÐ¸Ñ Ð¸Ð· ÑÑÑоки. Ðод ÑÑой ÑÑнкÑии неизвеÑÑен во вÑÐµÐ¼Ñ Ð½Ð°Ð¿Ð¸ÑÐ°Ð½Ð¸Ñ ÑкÑипÑа (поÑÑÐ¾Ð¼Ñ Ð½Ðµ иÑполÑзÑем обÑÑнÑе ÑÑнкÑии), а бÑÐ´ÐµÑ Ð¾Ð¿ÑеделÑн ÑолÑко в пÑоÑеÑÑе вÑполнениÑ. ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ полÑÑиÑÑ ÐºÐ¾Ð´ Ñ ÑеÑвеÑа или Ñ Ð´ÑÑгого ÑеÑÑÑÑа.
ÐаÑа Ð½Ð¾Ð²Ð°Ñ ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° взаимодейÑÑвоваÑÑ Ñ Ð¾ÑновнÑм ÑкÑипÑом.
ЧÑо еÑли Ð±Ñ Ð¾Ð½Ð° имела доÑÑÑп к внеÑним пеÑеменнÑм?
ÐÑоблема в Ñом, ÑÑо пеÑед оÑпÑавкой JavaScript-кода на ÑеалÑнÑе ÑабоÑаÑÑие пÑоекÑÑ ÐºÐ¾Ð´ ÑжимаеÑÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð¼Ð¸Ð½Ð¸ÑикаÑоÑа â ÑпеÑиалÑной пÑогÑаммÑ, коÑоÑÐ°Ñ ÑменÑÑÐ°ÐµÑ ÑÐ°Ð·Ð¼ÐµÑ ÐºÐ¾Ð´Ð°, ÑдалÑÑ ÐºÐ¾Ð¼Ð¼ÐµÐ½ÑаÑии, лиÑние пÑобелÑ, и, ÑÑо Ñамое главное, локалÑнÑм пеÑеменнÑм даÑÑÑÑ ÑкоÑоÑеннÑе имена.
ÐапÑимеÑ, еÑли в ÑÑнкÑии обÑÑвлÑеÑÑÑ Ð¿ÐµÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ let userName, Ñо миниÑикаÑÐ¾Ñ Ð¸Ð·Ð¼ÐµÐ½ÑÐµÑ ÐµÑ Ð½Ð° let a (или дÑÑгÑÑ Ð±ÑквÑ, еÑли она не занÑÑа) и изменÑÐµÑ ÐµÑ Ð²ÐµÐ·Ð´Ðµ. ÐбÑÑно Ñак делаÑÑ Ð±ÐµÐ·Ð¾Ð¿Ð°Ñно, поÑÐ¾Ð¼Ñ ÑÑо пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ ÑвлÑеÑÑÑ Ð»Ð¾ÐºÐ°Ð»Ñной, и никÑо ÑнаÑÑжи не Ð¸Ð¼ÐµÐµÑ Ðº ней доÑÑÑп. РвнÑÑÑи ÑÑнкÑии миниÑикаÑÐ¾Ñ Ð·Ð°Ð¼ÐµÐ½ÑÐµÑ ÐºÐ°Ð¶Ð´Ð¾Ðµ ÐµÑ Ñпоминание. ÐиниÑикаÑоÑÑ Ð´Ð¾ÑÑаÑоÑно ÑмнÑе. Ðни не пÑоÑÑо оÑÑÑеÑÑвлÑÑÑ Â«ÑÑпой» поиÑк-заменÑ, они анализиÑÑÑÑ ÑÑÑÑкÑÑÑÑ ÐºÐ¾Ð´Ð°, и поÑÑÐ¾Ð¼Ñ Ð½Ð¸Ñего не ломаеÑÑÑ.
Так ÑÑо еÑли Ð±Ñ Ð´Ð°Ð¶Ðµ new Function и имела доÑÑÑп к внеÑним пеÑеменнÑм, она не Ñмогла Ð±Ñ Ð½Ð°Ð¹Ñи пеÑеименованнÑÑ userName.
ÐÑли Ð±Ñ new Function имела доÑÑÑп к внеÑним пеÑеменнÑм, пÑи ÑÑом бÑли Ð±Ñ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ñ Ð¼Ð¸Ð½Ð¸ÑикаÑоÑами.
ÐÑоме Ñого, Ñакой код бÑл Ð±Ñ Ð°ÑÑ Ð¸ÑекÑÑÑно Ñ Ñже и более подвеÑжен оÑибкам.
ЧÑÐ¾Ð±Ñ Ð¿ÐµÑедаÑÑ ÑÑо-Ñо в ÑÑнкÑиÑ, ÑозданнÑÑ ÐºÐ°Ðº new Function, можно иÑполÑзоваÑÑ ÐµÑ Ð°ÑгÑменÑÑ.
ÐÑого
СинÑакÑиÑ:
let func = new Function ([arg1, arg2, ...argN], functionBody);
Ðо иÑÑоÑиÑеÑким пÑиÑинам аÑгÑменÑÑ Ñакже могÑÑ Ð±ÑÑÑ Ð¾Ð±ÑÑÐ²Ð»ÐµÐ½Ñ ÑеÑез запÑÑÑÑ Ð² одной ÑÑÑоке.
ÐÑи 3 обÑÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¸Ð¶Ðµ ÑквиваленÑнÑ:
new Function('a', 'b', 'return a + b'); // ÑÑандаÑÑнÑй ÑинÑакÑиÑ
new Function('a,b', 'return a + b'); // ÑеÑез запÑÑÑÑ Ð² одной ÑÑÑоке
new Function('a , b', 'return a + b'); // ÑеÑез запÑÑÑÑ Ñ Ð¿Ñобелами в одной ÑÑÑоке
ФÑнкÑии, обÑÑвленнÑе ÑеÑез new Function, имеÑÑ [[Environment]], ÑÑÑлаÑÑийÑÑ Ð½Ð° глобалÑное лекÑиÑеÑкое окÑÑжение, а не на ÑодиÑелÑÑкое. ÐоÑÑÐ¾Ð¼Ñ Ð¾Ð½Ð¸ не могÑÑ Ð¸ÑполÑзоваÑÑ Ð²Ð½ÐµÑние локалÑнÑе пеÑеменнÑе. Ðо ÑÑо оÑÐµÐ½Ñ Ñ
оÑоÑо, поÑÐ¾Ð¼Ñ ÑÑо ÑÑÑаÑ
ÑÐµÑ Ð½Ð°Ñ Ð¾Ñ Ð¾Ñибок. ÐеÑеданнÑе Ñвно паÑамеÑÑÑ â гоÑаздо лÑÑÑее аÑÑ
иÑекÑÑÑное ÑеÑение, коÑоÑое не вÑзÑÐ²Ð°ÐµÑ Ð¿Ñоблем Ñ Ð¼Ð¸Ð½Ð¸ÑикаÑоÑов.
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)