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