УпÑавление памÑÑÑÑ Ð² JavaScript обÑÑно пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð½ÐµÐ·Ð°Ð¼ÐµÑно. ÐÑ ÑоздаÑм пÑимиÑивÑ, обÑекÑÑ, ÑÑнкÑии⦠ÐÑÑ ÑÑо Ð·Ð°Ð½Ð¸Ð¼Ð°ÐµÑ Ð¿Ð°Ð¼ÑÑÑ.
ЧÑо пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ñ Ð¾Ð±ÑекÑом, когда он ÑÑановиÑÑÑ Â«Ð½Ðµ нÑжен»? Ðозможно ли «пеÑеполнение» памÑÑи? ÐÐ»Ñ Ð¾ÑвеÑа на ÑÑи вопÑоÑÑ â залезем «под капоÑ» инÑеÑпÑеÑаÑоÑа.
УпÑавление памÑÑÑÑ Ð² JavaScript
Ðлавной конÑепÑией ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°Ð¼ÑÑÑÑ Ð² JavaScript ÑвлÑеÑÑÑ Ð¿ÑинÑип доÑÑижимоÑÑи (англ. reachability).
- ÐпÑеделÑнное множеÑÑво знаÑений ÑÑиÑаеÑÑÑ Ð´Ð¾ÑÑижимÑм изнаÑалÑно, в ÑаÑÑноÑÑи:
-
ÐнаÑениÑ, ÑÑÑлки на коÑоÑÑе ÑодеÑжаÑÑÑ Ð² ÑÑеке вÑзова, Ñо еÑÑÑ â вÑе локалÑнÑе пеÑеменнÑе и паÑамеÑÑÑ ÑÑнкÑий, коÑоÑÑе в наÑÑоÑÑий Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð²ÑполнÑÑÑÑÑ Ð¸Ð»Ð¸ Ð½Ð°Ñ Ð¾Ð´ÑÑÑÑ Ð² ожидании оконÑÐ°Ð½Ð¸Ñ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ð¾Ð³Ð¾ вÑзова.
-
ÐÑе глобалÑнÑе пеÑеменнÑе.
ÐÑи знаÑÐµÐ½Ð¸Ñ Ð³Ð°ÑанÑиÑованно Ñ ÑанÑÑÑÑ Ð² памÑÑи. ÐÑ Ð±Ñдем назÑваÑÑ Ð¸Ñ ÐºÐ¾ÑнÑми.
- ÐÑбое дÑÑгое знаÑение ÑÐ¾Ñ ÑанÑеÑÑÑ Ð² памÑÑи лиÑÑ Ð´Ð¾ ÑÐµÑ Ð¿Ð¾Ñ, пока доÑÑÑпно из коÑÐ½Ñ Ð¿Ð¾ ÑÑÑлке или ÑепоÑке ÑÑÑлок.
ÐÐ»Ñ Ð¾ÑиÑÑки памÑÑи Ð¾Ñ Ð½ÐµÐ´Ð¾ÑÑижимÑÑ Ð·Ð½Ð°Ñений в бÑаÑзеÑÐ°Ñ Ð¸ÑполÑзÑеÑÑÑ Ð°Ð²ÑомаÑиÑеÑкий СбоÑÑик мÑÑоÑа (англ. Garbage collection, GC), вÑÑÑоеннÑй в инÑеÑпÑеÑаÑоÑ, коÑоÑÑй наблÑÐ´Ð°ÐµÑ Ð·Ð° обÑекÑами и вÑÐµÐ¼Ñ Ð¾Ñ Ð²Ñемени ÑдалÑÐµÑ Ð½ÐµÐ´Ð¾ÑÑижимÑе.
Ð¡Ð°Ð¼Ð°Ñ Ð¿ÑоÑÑÐ°Ñ ÑиÑÑаÑÐ¸Ñ Ð·Ð´ÐµÑÑ Ñ Ð¿ÑимиÑивами. ÐÑи пÑиÑвоении они копиÑÑÑÑÑÑ Ñеликом, ÑÑÑлок на Ð½Ð¸Ñ Ð½Ðµ ÑоздаÑÑÑÑ, Ñак ÑÑо еÑли в пеÑеменной бÑла одна ÑÑÑока, а ÐµÑ Ð·Ð°Ð¼ÐµÐ½Ð¸Ð»Ð¸ на дÑÑгÑÑ, Ñо пÑедÑдÑÑÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ Ñмело вÑбÑоÑиÑÑ.
Ðменно обÑекÑÑ ÑÑебÑÑÑ ÑпеÑиалÑного «ÑбоÑÑика мÑÑоÑа», коÑоÑÑй наблÑÐ´Ð°ÐµÑ Ð·Ð° ÑÑÑлками, Ñак как на один обÑÐµÐºÑ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¼Ð½Ð¾Ð³Ð¾ ÑÑÑлок из ÑазнÑÑ Ð¿ÐµÑеменнÑÑ Ð¸, пÑи пеÑезапиÑи одной из Ð½Ð¸Ñ , обÑÐµÐºÑ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²ÑÑ ÐµÑÑ Ð´Ð¾ÑÑÑпен из дÑÑгой.
Ðалее Ð¼Ñ Ð¿Ð¾ÑмоÑÑим ÑÑд пÑимеÑов, коÑоÑÑе помогÑÑ Ð² ÑÑом ÑазобÑаÑÑÑÑ.
ÐоÑÑижимоÑÑÑ Ð¸ налиÑие ÑÑÑлок
ÐÑÑÑ Ð¾Ð´Ð½Ð¾ ÑпÑоÑение Ð´Ð»Ñ ÑабоÑÑ Ñ Ð¿Ð°Ð¼ÑÑÑÑ: «знаÑение оÑÑаÑÑÑÑ Ð² памÑÑи, пока на него еÑÑÑ Ñ Ð¾ÑÑ Ð±Ñ Ð¾Ð´Ð½Ð° ÑÑÑлка».
Ðо Ñакое ÑпÑоÑение бÑÐ´ÐµÑ Ð²ÐµÑнÑм лиÑÑ Ð² Ð¾Ð´Ð½Ñ ÑÑоÑонÑ.
-
ÐеÑно â в Ñом плане, ÑÑо еÑли ÑÑÑлок на знаÑение неÑ, Ñо памÑÑÑ Ð¸Ð·-под него оÑиÑаеÑÑÑ.
ÐапÑимеÑ, бÑла Ñоздана ÑÑÑлка в пеÑеменной, и ÑÑÑ Ð¿ÐµÑеменнÑÑ ÑÑÑ Ð¶Ðµ пеÑезапиÑали:
var user = { name: "ÐаÑÑ" }; user = null;ТепеÑÑ Ð¾Ð±ÑекÑ
{ name: "ÐаÑÑ" }более недоÑÑÑпен. ÐамÑÑÑ Ð±ÑÐ´ÐµÑ Ð¾Ñвобождена. -
ÐевеÑно â в дÑÑгÑÑ ÑÑоÑонÑ: налиÑие ÑÑÑлки не гаÑанÑиÑÑеÑ, ÑÑо знаÑение оÑÑанеÑÑÑ Ð² памÑÑи.
Ð¢Ð°ÐºÐ°Ñ ÑиÑÑаÑÐ¸Ñ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ Ñ Ð¾Ð±ÑекÑами, коÑоÑÑе ÑÑÑлаÑÑÑÑ Ð´ÑÑг на дÑÑга:
var vasya = {}; var petya = {}; vasya.friend = petya; petya.friend = vasya; vasya = petya = null;ÐеÑмоÑÑÑ Ð½Ð° Ñо, ÑÑо обÑекÑÑ
vasyaиpetyaÑÑÑлаÑÑÑÑ Ð´ÑÑг на дÑÑга ÑеÑез ÑÑÑлкÑfriend, Ñо еÑÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ ÑказаÑÑ, ÑÑо на каждÑй из Ð½Ð¸Ñ ÐµÑÑÑ ÑÑÑлка, поÑледнÑÑ ÑÑÑока Ð´ÐµÐ»Ð°ÐµÑ ÑÑи обÑекÑÑ Ð² ÑовокÑпноÑÑи недоÑÑижимÑми.ÐоÑÑÐ¾Ð¼Ñ Ð¾Ð½Ð¸ бÑдÑÑ ÑÐ´Ð°Ð»ÐµÐ½Ñ Ð¸Ð· памÑÑи.
ÐдеÑÑ ÐºÐ°Ðº Ñаз и игÑÐ°ÐµÑ ÑÐ¾Ð»Ñ Â«Ð´Ð¾ÑÑижимоÑÑÑ» â оба ÑÑÐ¸Ñ Ð¾Ð±ÑекÑа ÑÑановÑÑÑÑ Ð½ÐµÐ´Ð¾ÑÑÐ¸Ð¶Ð¸Ð¼Ñ Ð¸Ð· коÑней, в пеÑвÑÑ Ð¾ÑеÑедÑ, из глобалÑной облаÑÑи, ÑÑека.
СбоÑÑик мÑÑоÑа оÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°ÐµÑ Ñакие ÑиÑÑаÑии и оÑиÑÐ°ÐµÑ Ð¿Ð°Ð¼ÑÑÑ.
ÐлгоÑиÑм ÑбоÑки мÑÑоÑа
СбоÑÑик мÑÑоÑа идÑÑ Ð¾Ñ ÐºÐ¾ÑÐ½Ñ Ð¿Ð¾ ÑÑÑлкам и Ð·Ð°Ð¿Ð¾Ð¼Ð¸Ð½Ð°ÐµÑ Ð²Ñе найденнÑе обÑекÑÑ. Ðо оконÑÐ°Ð½Ð¸Ñ â он ÑмоÑÑиÑ, какие обÑекÑÑ Ð² нÑм оÑÑÑÑÑÑвÑÑÑ Ð¸ ÑдалÑÐµÑ Ð¸Ñ .
ÐапÑимеÑ, ÑаÑÑмоÑÑим пÑÐ¸Ð¼ÐµÑ Ð¾Ð±ÑекÑа «ÑемÑÑ»:
function marry(man, woman) {
woman.husband = man;
man.wife = woman;
return {
father: man,
mother: woman
}
}
var family = marry({
name: "ÐаÑилий"
}, {
name: "ÐаÑиÑ"
});
ФÑнкÑÐ¸Ñ marry пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð´Ð²Ð° обÑекÑа, даÑÑ Ð¸Ð¼ ÑÑÑлки дÑÑг на дÑÑга и возвÑаÑÐ°ÐµÑ ÑÑеÑий, ÑодеÑжаÑий ÑÑÑлки на оба.
ÐолÑÑивÑийÑÑ Ð¾Ð±ÑÐµÐºÑ family можно изобÑазиÑÑ Ñак:
ÐдеÑÑ ÑÑÑелоÑками Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ñ ÑÑÑлки, а Ð²Ð¾Ñ ÑвойÑÑво name ÑÑÑлкой не ÑвлÑеÑÑÑ, Ñам Ñ
ÑаниÑÑÑ Ð¿ÑимиÑив, поÑÑÐ¾Ð¼Ñ Ð¾Ð½Ð¾ внÑÑÑи Ñамого обÑекÑа.
ЧÑÐ¾Ð±Ñ Ð·Ð°Ð¿ÑÑÑиÑÑ ÑбоÑÑик мÑÑоÑа, Ñдалим две ÑÑÑлки:
delete family.father;
delete family.mother.husband;
ÐбÑаÑим внимание, Ñдаление ÑолÑко одной из ÑÑиÑ
ÑÑÑлок ни к ÑÐµÐ¼Ñ Ð±Ñ Ð½Ðµ пÑивело. Ðока до обÑекÑа можно добÑаÑÑÑÑ Ð¸Ð· коÑÐ½Ñ window, обÑÐµÐºÑ Ð¾ÑÑаÑÑÑÑ Ð¶Ð¸Ð².
РеÑли две, Ñо полÑÑаеÑÑÑ, ÑÑо Ð¾Ñ Ð±ÑвÑего family.father ÑÑÑлки вÑÑ
одÑÑ, но в него â ни одна не идÑÑ:
СовеÑÑенно неважно, ÑÑо из обÑекÑа вÑÑ Ð¾Ð´ÑÑ ÐºÐ°ÐºÐ¸Ðµ-Ñо ÑÑÑлки, они не влиÑÑÑ Ð½Ð° доÑÑижимоÑÑÑ ÑÑого обÑекÑа.
ÐÑвÑий family.father ÑÑал недоÑÑижимÑм и бÑÐ´ÐµÑ ÑдалÑн вмеÑÑе Ñо Ñвоими даннÑми, коÑоÑÑе Ñакже более недоÑÑÑÐ¿Ð½Ñ Ð¸Ð· пÑогÑаммÑ.
Ð ÑепеÑÑ â ÑаÑÑмоÑÑим более ÑложнÑй ÑлÑÑай. ЧÑо бÑдеÑ, еÑли ÑдалиÑÑ Ð³Ð»Ð°Ð²Ð½ÑÑ ÑÑÑÐ»ÐºÑ family?
ÐÑÑ Ð¾Ð´Ð½Ñй обÑÐµÐºÑ â ÑÐ¾Ñ Ð¶Ðµ, ÑÑо и в наÑале, а заÑем:
window.family = null;
РезÑлÑÑаÑ:
Ðак видим, обÑекÑÑ Ð² конÑÑÑÑкÑии вÑÑ ÐµÑÑ ÑвÑÐ·Ð°Ð½Ñ Ð¼ÐµÐ¶Ð´Ñ Ñобой. Ðднако, поиÑк Ð¾Ñ ÐºÐ¾ÑÐ½Ñ Ð¸Ñ Ð½Ðµ Ð½Ð°Ñ Ð¾Ð´Ð¸Ñ, они не доÑÑижимÑ, и знаÑÐ¸Ñ ÑбоÑÑик мÑÑоÑа ÑÐ´Ð°Ð»Ð¸Ñ Ð¸Ñ Ð¸Ð· памÑÑи.
ÐÑоблема опиÑанного алгоÑиÑма â в болÑÑÐ¸Ñ Ð·Ð°Ð´ÐµÑÐ¶ÐºÐ°Ñ . ÐÑли обÑекÑов много, Ñо на поиÑк вÑÐµÑ Ð´Ð¾ÑÑижимÑÑ ÑйдÑÑ Ð´Ð¾Ð²Ð¾Ð»Ñно много вÑемени. Ð Ð²ÐµÐ´Ñ Ð²Ñполнение ÑкÑипÑа пÑи ÑÑом должно бÑÑÑ Ð¾ÑÑановлено, Ñже пÑоÑканиÑованнÑе обÑекÑÑ Ð½Ðµ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿Ð¾Ð¼ÐµÐ½ÑÑÑÑÑ Ð´Ð¾ оконÑÐ°Ð½Ð¸Ñ Ð¿ÑоÑеÑÑа. ÐолÑÑаÑÑÑÑ Ð½ÐµÐ±Ð¾Ð»ÑÑие, но непÑиÑÑнÑе паÑзÑ-завиÑÐ°Ð½Ð¸Ñ Ð² ÑабоÑе ÑкÑипÑа.
ÐоÑÑÐ¾Ð¼Ñ ÑовÑеменнÑе инÑеÑпÑеÑаÑоÑÑ Ð¿ÑименÑÑÑ ÑазлиÑнÑе опÑимизаÑии.
Ð¡Ð°Ð¼Ð°Ñ ÑаÑÑÐ°Ñ â ÑÑо деление обÑекÑов на два вида «ÑÑаÑÑе» и «новÑе». ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñипа вÑделÑеÑÑÑ ÑÐ²Ð¾Ñ Ð¾Ð±Ð»Ð°ÑÑÑ Ð¿Ð°Ð¼ÑÑи. ÐаждÑй обÑÐµÐºÑ ÑоздаÑÑÑÑ Ð² «новой» облаÑÑи и, еÑли пÑожил доÑÑаÑоÑно долго, мигÑиÑÑÐµÑ Ð² ÑÑаÑÑÑ. «ÐоваÑ» облаÑÑÑ Ð¾Ð±ÑÑно неболÑÑаÑ. Ðна оÑиÑаеÑÑÑ ÑаÑÑо. «СÑаÑаÑ» â Ñедко.
Ðа пÑакÑике полÑÑаеÑÑÑ ÑÑÑекÑивно, обÑÑно болÑÑинÑÑво обÑекÑов ÑоздаÑÑÑÑ Ð¸ ÑмиÑаÑÑ Ð¿Ð¾ÑÑи ÑÑазÑ, к пÑимеÑÑ, ÑлÑжа локалÑнÑми пеÑеменнÑми ÑÑнкÑии:
function showTime() {
alert( new Date() ); // ÑÑÐ¾Ñ Ð¾Ð±ÑÐµÐºÑ Ð±ÑÐ´ÐµÑ Ñоздан и ÑмÑÑÑ ÑÑазÑ
}
ÐÑли Ð²Ñ Ð·Ð½Ð°ÐµÑе низкоÑÑовневÑе ÑзÑки пÑогÑаммиÑованиÑ, Ñо более подÑобно об оÑганизаÑии ÑбоÑки мÑÑоÑа в V8 можно поÑиÑаÑÑ, напÑимеÑ, в ÑÑаÑÑе A tour of V8: Garbage Collection.
ÐамÑканиÑ
ÐбÑекÑÑ Ð¿ÐµÑеменнÑÑ , о коÑоÑÑÑ Ñла ÑеÑÑ Ñанее, в главе пÑо замÑканиÑ, Ñакже подвеÑÐ¶ÐµÐ½Ñ ÑбоÑке мÑÑоÑа. Ðни ÑледÑÑÑ Ñем же пÑавилам, ÑÑо и обÑÑнÑе обÑекÑÑ.
ÐбÑÐµÐºÑ Ð¿ÐµÑеменнÑÑ
внеÑней ÑÑнкÑии ÑÑÑеÑÑвÑÐµÑ Ð² памÑÑи до ÑеÑ
поÑ, пока ÑÑÑеÑÑвÑÐµÑ Ñ
оÑÑ Ð¾Ð´Ð½Ð° внÑÑÑеннÑÑ ÑÑнкÑиÑ, ÑÑÑлаÑÑаÑÑÑ Ð½Ð° него ÑеÑез ÑвойÑÑво [[Scope]].
ÐапÑимеÑ:
-
ÐбÑÑно обÑÐµÐºÑ Ð¿ÐµÑеменнÑÑ ÑдалÑеÑÑÑ Ð¿Ð¾ завеÑÑении ÑабоÑÑ ÑÑнкÑии. Ðаже еÑли в нÑм еÑÑÑ Ð¾Ð±ÑÑвление внÑÑÑенней ÑÑнкÑии:
function f() { var value = 123; function g() {} // g видна ÑолÑко изнÑÑÑи } f();Ркоде вÑÑе
valueиgÑвлÑÑÑÑÑ ÑвойÑÑвами обÑекÑа пеÑеменнÑÑ . Ðо вÑÐµÐ¼Ñ Ð²ÑполнениÑf()ÐµÑ Ð¾Ð±ÑÐµÐºÑ Ð¿ÐµÑеменнÑÑ Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð² ÑекÑÑем ÑÑеке вÑполнениÑ, поÑÑÐ¾Ð¼Ñ Ð¶Ð¸Ð². Ðо оконÑаниÑ, он ÑÑÐ°Ð½ÐµÑ Ð½ÐµÐ´Ð¾ÑÑижимÑм и бÑÐ´ÐµÑ ÑбÑан из памÑÑи вмеÑÑе Ñ Ð¾ÑÑалÑнÑми локалÑнÑми пеÑеменнÑми. -
â¦Ð Ð²Ð¾Ñ Ð² ÑÑом ÑлÑÑае лекÑиÑеÑкое окÑÑжение, вклÑÑÐ°Ñ Ð¿ÐµÑеменнÑÑ
value, бÑÐ´ÐµÑ ÑÐ¾Ñ Ñанено:function f() { var value = 123; function g() {} return g; } var g = f(); // ÑÑнкÑÐ¸Ñ g бÑÐ´ÐµÑ Ð¶Ð¸ÑÑ Ð¸ ÑÐ¾Ñ ÑÐ°Ð½Ð¸Ñ ÑÑÑÐ»ÐºÑ Ð½Ð° обÑÐµÐºÑ Ð¿ÐµÑеменнÑÑÐ ÑкÑÑÑом ÑвойÑÑве
g.[[Scope]]Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ ÑÑÑлка на обÑÐµÐºÑ Ð¿ÐµÑеменнÑÑ , в коÑоÑом бÑла Ñозданаg. ÐоÑÑÐ¾Ð¼Ñ ÑÑÐ¾Ñ Ð¾Ð±ÑÐµÐºÑ Ð¿ÐµÑеменнÑÑ Ð¾ÑÑанеÑÑÑ Ð² памÑÑи, а в нÑм â иvalue. -
ÐÑли
f()бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ Ð¼Ð½Ð¾Ð³Ð¾ Ñаз, а полÑÑеннÑе ÑÑнкÑии бÑдÑÑ ÑÐ¾Ñ ÑанÑÑÑÑÑ, напÑимеÑ, ÑкладÑваÑÑÑÑ Ð² маÑÑив, Ñо бÑдÑÑ ÑÐ¾Ñ ÑанÑÑÑÑÑ Ð¸ обÑекÑÑLexicalEnvironmentÑ ÑооÑвеÑÑÑвÑÑÑими знаÑениÑмиvalue:function f() { var value = Math.random(); return function() { return value; }; } // 3 ÑÑнкÑии, ÐºÐ°Ð¶Ð´Ð°Ñ ÑÑÑлаеÑÑÑ Ð½Ð° Ñвой обÑÐµÐºÑ Ð¿ÐµÑеменнÑÑ , // каждÑй Ñо Ñвоим знаÑением value var arr = [f(), f(), f()]; -
ÐбÑекÑ
LexicalEnvironmentживÑÑ Ñовно до ÑÐµÑ Ð¿Ð¾Ñ, пока на него ÑÑÑеÑÑвÑÑÑ ÑÑÑлки. Ркоде ниже поÑле ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÑÑÑлки наgÑмиÑаеÑ:function f() { var value = 123; function g() {} return g; } var g = f(); // ÑÑнкÑÐ¸Ñ g жива // а знаÑÐ¸Ñ Ð² памÑÑи оÑÑаÑÑÑÑ ÑооÑвеÑÑÑвÑÑÑий обÑÐµÐºÑ Ð¿ÐµÑеменнÑÑ f() g = null; // ..а Ð²Ð¾Ñ ÑепеÑÑ Ð¿Ð°Ð¼ÑÑÑ Ð±ÑÐ´ÐµÑ Ð¾ÑиÑена
ÐпÑимизаÑÐ¸Ñ Ð² V8 и ÐµÑ Ð¿Ð¾ÑледÑÑвиÑ
СовÑеменнÑе JS-движки делаÑÑ Ð¾Ð¿ÑимизаÑии замÑканий по памÑÑи. Ðни анализиÑÑÑÑ Ð¸ÑполÑзование пеÑеменнÑÑ Ð¸ в ÑлÑÑае, когда пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¸Ð· замÑÐºÐ°Ð½Ð¸Ñ Ð°Ð±ÑолÑÑно ÑоÑно не иÑполÑзÑеÑÑÑ, ÑдалÑÑÑ ÐµÑ.
Ркоде вÑÑе пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ value никак не иÑполÑзÑеÑÑÑ. ÐоÑÑÐ¾Ð¼Ñ Ð¾Ð½Ð° бÑÐ´ÐµÑ Ñдалена из памÑÑи.
ÐажнÑй побоÑнÑй ÑÑÑÐµÐºÑ Ð² V8 (Chrome, Opera) ÑоÑÑÐ¾Ð¸Ñ Ð² Ñом, ÑÑо ÑдалÑÐ½Ð½Ð°Ñ Ð¿ÐµÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ ÑÑÐ°Ð½ÐµÑ Ð½ÐµÐ´Ð¾ÑÑÑпна и пÑи оÑладке!
ÐопÑобÑйÑе запÑÑÑиÑÑ Ð¿ÑÐ¸Ð¼ÐµÑ Ð½Ð¸Ð¶Ðµ Ñ Ð¾ÑкÑÑÑой конÑолÑÑ Chrome. Ðогда он оÑÑановиÑÑÑ, в конÑоли набеÑиÑе alert(value).
function f() {
var value = Math.random();
function g() {
debugger; // вÑполниÑе в конÑоли alert( value ); ÐÐµÑ Ñакой пеÑеменной!
}
return g;
}
var g = f();
g();
Ðак Ð²Ñ Ð¼Ð¾Ð³Ð»Ð¸ ÑвидеÑÑ â Ð½ÐµÑ Ñакой пеÑеменной! ÐедоÑÑÑпна она изнÑÑÑи g. ÐнÑеÑпÑеÑаÑÐ¾Ñ ÑеÑил, ÑÑо она нам не понадобиÑÑÑ Ð¸ Ñдалил.
ÐÑо Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑивеÑÑи к забавнÑм казÑÑам пÑи оÑладке, вплоÑÑ Ð´Ð¾ Ñого ÑÑо вмеÑÑо ÑÑой пеÑеменной бÑÐ´ÐµÑ Ð´ÑÑгаÑ, внеÑнÑÑ:
var value = "СÑÑпÑиз";
function f() {
var value = "Ñамое близкое знаÑение";
function g() {
debugger; // вÑполниÑе в конÑоли alert( value ); СÑÑпÑиз!
}
return g;
}
var g = f();
g();
Ðб ÑÑой оÑобенноÑÑи важно знаÑÑ. ÐÑли Ð²Ñ Ð¾ÑлаживаеÑе под Chrome/Opera, Ñо навеÑнÑка Ñано или поздно Ñ Ð½ÐµÐ¹ вÑÑÑеÑиÑеÑÑ!
ÐÑо не глÑк оÑладÑика, а оÑобенноÑÑÑ ÑабоÑÑ V8, коÑоÑаÑ, возможно, бÑÐ´ÐµÑ ÐºÐ¾Ð³Ð´Ð°-нибÑÐ´Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð°. ÐÑ Ð²Ñегда ÑможеÑе пÑовеÑиÑÑ, не изменилоÑÑ Ð»Ð¸ Ñего, запÑÑÑив пÑимеÑÑ Ð½Ð° ÑÑой ÑÑÑаниÑе.
ÐлиÑние ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°Ð¼ÑÑÑÑ Ð½Ð° ÑкоÑоÑÑÑ
Ðа Ñоздание новÑÑ Ð¾Ð±ÑекÑов и Ð¸Ñ Ñдаление ÑÑаÑиÑÑÑ Ð²ÑемÑ. ÐÑо важно имеÑÑ Ð² Ð²Ð¸Ð´Ñ Ð² ÑлÑÑае, когда важна пÑоизводиÑелÑноÑÑÑ.
РкаÑеÑÑве пÑимеÑа ÑаÑÑмоÑÑим ÑекÑÑÑиÑ. ÐÑи вложеннÑÑ Ð²ÑÐ·Ð¾Ð²Ð°Ñ ÐºÐ°Ð¶Ð´Ñй Ñаз ÑоздаÑÑÑÑ Ð½Ð¾Ð²Ñй обÑÐµÐºÑ Ñ Ð¿ÐµÑеменнÑми и помеÑаеÑÑÑ Ð² ÑÑек. ÐоÑом памÑÑÑ Ð¸Ð·-под него нÑжно оÑиÑÑиÑÑ. ÐоÑÑÐ¾Ð¼Ñ ÑекÑÑÑивнÑй код бÑÐ´ÐµÑ Ð²Ñегда медленнее иÑполÑзÑÑÑего Ñикл, но наÑколÑко?
ÐÑÐ¸Ð¼ÐµÑ Ð½Ð¸Ð¶Ðµ ÑеÑÑиÑÑÐµÑ Ñложение ÑиÑел до данного ÑеÑез ÑекÑÑÑÐ¸Ñ Ð¿Ð¾ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ñ Ð¾Ð±ÑÑнÑм Ñиклом:
function sumTo(n) { // обÑÑнÑй Ñикл 1+2+...+n
var result = 0;
for (var i = 1; i <= n; i++) {
result += i;
}
return result;
}
function sumToRec(n) { // ÑекÑÑÑÐ¸Ñ sumToRec(n) = n+SumToRec(n-1)
return n == 1 ? 1 : n + sumToRec(n - 1);
}
var timeLoop = performance.now();
for (var i = 1; i < 1000; i++) sumTo(1000); // Ñикл
timeLoop = performance.now() - timeLoop;
var timeRecursion = performance.now();
for (var i = 1; i < 1000; i++) sumToRec(1000); // ÑекÑÑÑиÑ
timeRecursion = performance.now() - timeRecursion;
alert( "РазниÑа в " + (timeRecursion / timeLoop) + " Ñаз" );
РазлиÑие в ÑкоÑоÑÑи на Ñаком пÑимеÑе Ð¼Ð¾Ð¶ÐµÑ ÑоÑÑавлÑÑÑ, в завиÑимоÑÑи Ð¾Ñ Ð¸Ð½ÑеÑпÑеÑаÑоÑа, 2-10 Ñаз.
ÐообÑе, ÑÑÐ¾Ñ Ð¿ÑÐ¸Ð¼ÐµÑ â не показаÑелен. ÐÑÑ Ñаз обÑаÑÐ°Ñ Ð²Ð°Ñе внимание на Ñо, ÑÑо Ñакие иÑкÑÑÑÑвеннÑе «микÑоÑеÑÑÑ» ÑаÑÑо вÑÑÑ. ÐÑавилÑно Ð¸Ñ Ð´ÐµÐ»Ð°ÑÑ â оÑделÑÐ½Ð°Ñ Ð½Ð°Ñка, коÑоÑÐ°Ñ Ð²ÑÑ Ð¾Ð´Ð¸Ñ Ð·Ð° Ñамки ÑÑой главÑ. Ðо и на пÑакÑике ÑÑкоÑение в 2-10 Ñаз опÑимизаÑией по колиÑеÑÑÐ²Ñ Ð¾Ð±ÑекÑов (и вообÑе, лÑбÑÑ Ð·Ð½Ð°Ñений) â оÑнÑÐ´Ñ Ð½Ðµ миÑ, а вполне доÑÑижимо.
Ð ÑеалÑной жизни в болÑÑинÑÑве ÑиÑÑаÑий ÑÐ°ÐºÐ°Ñ Ð¾Ð¿ÑимизаÑÐ¸Ñ Ð½ÐµÑÑÑеÑÑвенна, пÑоÑÑо поÑÐ¾Ð¼Ñ ÑÑо «JavaScript и Ñак доÑÑаÑоÑно бÑÑÑÑ». Ðо она Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑÑÑекÑивной Ð´Ð»Ñ Â«ÑÐ·ÐºÐ¸Ñ Ð¼ÐµÑÑ» кода.
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)