සෑම විටම මම "වසා දැමීම්" සඳහන් කර ඇති බව දකිමි, මම එය සොයා බැලීමට උත්සාහ කළ නමුත් විකී මට තේරෙන පැහැදිලි කිරීමක් ලබා නොදේ. මට මෙතනින් උදව් කරන්න කාටහරි පුළුවන්ද?
සෑම විටම මම "වසා දැමීම්" සඳහන් කර ඇති බව දකිමි, මම එය සොයා බැලීමට උත්සාහ කළ නමුත් විකී මට තේරෙන පැහැදිලි කිරීමක් ලබා නොදේ. මට මෙතනින් උදව් කරන්න කාටහරි පුළුවන්ද?
Answers:
(වියාචනය: මෙය මූලික පැහැදිලි කිරීමකි; අර්ථ දැක්වීම අනුව, මම ටිකක් සරල කරමි)
වසා දැමීමක් ගැන සිතීමට ඇති සරලම ක්රමය නම් විචල්යයක් ලෙස ගබඩා කළ හැකි ශ්රිතයකි (“පළමු පන්තියේ ශ්රිතයක්” ලෙස හැඳින්වේ), එය නිර්මාණය කරන ලද විෂය පථයට දේශීයව වෙනත් විචල්යයන්ට ප්රවේශ වීමේ විශේෂ හැකියාවක් ඇත.
උදාහරණය (ජාවාස්ක්රිප්ට්):
var setKeyPress = function(callback) {
document.onkeypress = callback;
};
var initialize = function() {
var black = false;
document.onclick = function() {
black = !black;
document.body.style.backgroundColor = black ? "#000000" : "transparent";
}
var displayValOfBlack = function() {
alert(black);
}
setKeyPress(displayValOfBlack);
};
initialize();
කාර්යයන් 1 පවරා document.onclick
හා displayValOfBlack
වසා දැමීම් වේ. ඔවුන් දෙදෙනාම බූලියන් විචල්යය යොමු කරන බව ඔබට පෙනෙනු ඇත black
, නමුත් එම විචල්යය ශ්රිතයෙන් පිටත පවරා ඇත. නිසා black
ය ශ්රිතය අර්ථ සිටි විෂය පථය දේශීය , මෙම විචල්ය පෙන්නුම් කරන්නක්, කල් තබා ගන්නා ඇත.
ඔබ මෙය HTML පිටුවක තැබුවහොත්:
මෙයින් පෙන්නුම් කරන්නේ දෙදෙනාම එක black
හා සමාන ප්රවේශයක් ඇති අතර කිසිදු ආවරණයක් නොමැතිව වස්තුව ගබඩා කිරීම සඳහා භාවිතා කළ හැකි බවයි .
ඇමතුම setKeyPress
යනු ඕනෑම විචල්යයක් මෙන් ශ්රිතයක් සම්මත කළ හැකි ආකාරය නිරූපණය කිරීමයි. මෙම විෂය පථය වසා, කල් තබා ගන්නා තවමත් කාර්යයේ අර්ථ සිටි තැනැත්තා ය.
වසා දැමීම් සාමාන්යයෙන් සිදුවීම් හසුරුවන්නන් ලෙස භාවිතා කරයි, විශේෂයෙන් ජාවාස්ක්රිප්ට් සහ ඇක්ෂන් ස්ක්රිප්ට් වල. වසා දැමීම් හොඳින් භාවිතා කිරීම මඟින් වස්තු ආවරණයක් සෑදීමෙන් තොරව විචල්යයන් සිදුවීම් හසුරුවන්නන් සමඟ ව්යංගයෙන් බැඳීමට උපකාරී වේ. කෙසේ වෙතත්, නොසැලකිලිමත් ලෙස භාවිතා කිරීම මතක කාන්දුවීම් වලට තුඩු දෙනු ඇත (භාවිතයට නොගත් නමුත් සංරක්ෂිත සිදුවීම් හසුරුවන්නෙකු මතකයේ ඇති විශාල වස්තූන්, විශේෂයෙන් DOM වස්තූන් මත රඳවා තබා ගත හැකි එකම දෙය, කසළ එකතු කිරීම වැළැක්වීම වැනි).
1: ඇත්ත වශයෙන්ම, ජාවාස්ක්රිප්ට් හි සියලුම කාර්යයන් වසා දැමීම් වේ.
black
, විශාල උත්සවයක් තුළ ප්රකාශයට පත් කරන්නේ අඩුක්කුව unwinds ලෙස විනාශ කර ගැනීමට බව කළේ නැත ...?
black
ශ්රිතයක් තුළ ප්රකාශයට පත් කර ඇති බැවින් එය විනාශ නොවනු ඇත” යනුවෙනි. ඔබ ශ්රිතයක වස්තුවක් ප්රකාශයට පත් කර වෙනත් තැනක ජීවත්වන විචල්යයකට එය පවරන්නේ නම්, එම වස්තුව සංරක්ෂණය වන්නේ එයට වෙනත් යොමු කිරීම් ඇති බැවිනි.
වසා දැමීම මූලික වශයෙන් වස්තුවක් දෙස බැලීමේ වෙනස් ආකාරයකි. වස්තුවක් යනු එයට එකක් හෝ වැඩි ගණනක් බැඳී ඇති දත්ත ය. වසා දැමීම යනු විචල්යයන් එකක් හෝ වැඩි ගණනක් බැඳී ඇති ශ්රිතයකි. අවම වශයෙන් ක්රියාත්මක කිරීමේ මට්ටමින් මේ දෙක මූලික වශයෙන් සමාන වේ. සැබෑ වෙනස වන්නේ ඔවුන් පැමිණෙන්නේ කොතැනින්ද යන්නයි.
වස්තු-නැඹුරු වැඩසටහන්කරණයේදී, ඔබ වස්තු පන්තියක් ප්රකාශයට පත් කරන්නේ එහි සාමාජික විචල්යයන් සහ එහි ක්රම (සාමාජික ක්රියාකාරකම්) ඉහළට නිර්වචනය කරමිනි, ඉන්පසු ඔබ එම පන්තියේ අවස්ථා නිර්මාණය කරයි. සෑම අවස්ථාවක්ම සාමාජිකයාගේ දත්ත පිටපතක් සමඟ එන අතර එය ඉදිකිරීම්කරු විසින් ආරම්භ කරනු ලැබේ. එවිට ඔබට වස්තු වර්ගයක විචල්යයක් ඇති අතර එය දත්ත කැබැල්ලක් ලෙස සම්මත කරන්න, මන්ද අවධානය යොමු වන්නේ එහි ස්වභාවය දත්ත ලෙස ය.
වසා දැමීමේදී, අනෙක් අතට, වස්තුව වස්තු පන්තියක් මෙන් ඉහළට නිර්වචනය කර නැත, නැතහොත් ඔබේ කේතයේ ඉදිකිරීම්කරු ඇමතුමක් හරහා ක්ෂණිකව සකසා ඇත. ඒ වෙනුවට, ඔබ වසා දැමීම වෙනත් ශ්රිතයක ඇතුළත ශ්රිතයක් ලෙස ලියයි. වසා දැමීමෙන් බාහිර ශ්රිතයේ ඕනෑම දේශීය විචල්යයකට යොමු විය හැකි අතර, සම්පාදකයා එය හඳුනාගෙන මෙම විචල්යයන් බාහිර ශ්රිතයේ සිරස් අවකාශයේ සිට වසා දැමීමේ සැඟවුණු වස්තු ප්රකාශනය දක්වා ගෙන යයි. එවිට ඔබට වසා දැමීමේ වර්ගයක විචල්යයක් ඇති අතර, එය මූලික වශයෙන් කබාය යට වස්තුවක් වුවද, ඔබ එය ශ්රිත යොමු කිරීමක් ලෙස එය පසුකර යයි, මන්දයත් එහි ස්වභාවය ශ්රිතයක් ලෙස අවධානය යොමු කර ඇති බැවිනි.
වසා දැමීම යන පදය පැමිණෙන්නේ කේත කැබැල්ලකට (වාරණය, ශ්රිතය) කේත වාරණය අර්ථ දක්වා ඇති පරිසරය විසින් වසා ඇති (එනම් අගයකට බැඳී ඇති) නිදහස් විචල්යයන් තිබිය හැකි බැවිනි.
Scala ශ්රිත අර්ථ දැක්වීම උදාහරණයක් ලෙස ගන්න:
def addConstant(v: Int): Int = v + k
මෙම උත්සවයට සිරුරේ නම් (විචල්යයන්) දෙකක් ඇත v
හා k
පූර්ණ සංඛ්යාමය අගයන් දෙකක් පෙන්නුම්. නම v
බැඳී ඇත්තේ එය ශ්රිතයේ තර්කයක් ලෙස ප්රකාශයට පත් කර ඇති බැවිනි addConstant
(ශ්රිතය ප්රකාශ කිරීම දෙස බැලීමෙන් v
ශ්රිතය ආයාචනා කරන විට එය අගයක් පවරනු ඇත). k
ශ්රිතයට නම නිදහස් වේ. ශ්රිතයට addConstant
කුමන අගයකට k
බැඳී ඇත්ද යන්න පිළිබඳ කිසිදු හෝඩුවාවක් නොමැති නිසා (සහ කෙසේද).
වැනි ඇමතුමක් ඇගයීම සඳහා:
val n = addConstant(10)
අපට k
අගයක් පැවරිය යුතුය, එය සිදුවිය හැක්කේ k
අර්ථ දක්වා ඇති සන්දර්භය තුළ addConstant
නම අර්ථ දැක්වුවහොත් පමණි. උදාහරණයක් වශයෙන්:
def increaseAll(values: List[Int]): List[Int] =
{
val k = 2
def addConstant(v: Int): Int = v + k
values.map(addConstant)
}
දැන් අපි අර්ථ ඇති බව addConstant
ද, සන්ධර්භයක, k
අර්ථ දක්වා ඇත, addConstant
එය බවට පත් වී තිබේ වසා එහි සියලු නිදහස් විචල්ය දැන් නිසා වසා (අ අගය කිරීමට බැඳී): addConstant
එය කාර්යය නම් ලෙස ආයාචනා සහ ඒ අවට සම්මත කළ හැක. මෙම නිදහස් විචල්ය සටහන k
වසා විට අගය කිරීමට බැඳී ඇත අර්ථ තර්කය විචල්ය ඇති ෙහයින්ද, v
වසා දැමීම විට බැඳී පළ කළහ .
එබැවින් වසා දැමීම මූලික වශයෙන් ශ්රිතයක් හෝ කේත වාරණයක් වන අතර එමඟින් සන්දර්භය මගින් බැඳී ඇති පසු එහි නිදහස් විචල්යයන් හරහා දේශීය නොවන අගයන්ට ප්රවේශ විය හැකිය.
බොහෝ භාෂාවලින්, ඔබ වසා දැමීමක් භාවිතා කරන්නේ එක් වරක් පමණක් නම්, ඔබට එය නිර්නාමික කළ හැකිය , උදා
def increaseAll(values: List[Int]): List[Int] =
{
val k = 2
values.map(v => v + k)
}
නිදහස් විචල්යයන් නොමැති ශ්රිතයක් වසා දැමීමේ විශේෂ අවස්ථාවක් බව සලකන්න (හිස් නිදහස් විචල්ය සමූහයක් සමඟ). ප්රතිසමයට අනුව, නිර්නාමික ශ්රිතයක් යනු නිර්නාමික වසා දැමීමේ විශේෂ අවස්ථාවකි , එනම් නිර්නාමික ශ්රිතයක් යනු නිදහස් විචල්යයන් නොමැති නිර්නාමික වසා දැමීමකි.
JavaScript හි සරල පැහැදිලි කිරීමක්:
var closure_example = function() {
var closure = 0;
// after first iteration the value will not be erased from the memory
// because it is bound with the returned alertValue function.
return {
alertValue : function() {
closure++;
alert(closure);
}
};
};
closure_example();
alert(closure)
හි කලින් සාදන ලද අගය භාවිතා කරයි closure
. ආපසු ලබා දුන් alertValue
ශ්රිතයේ නාම අවකාශය closure
විචල්යය වාසය කරන නාම අවකාශයට සම්බන්ධ වේ . ඔබ සම්පූර්ණ ශ්රිතය closure
මකා දැමූ විට, විචල්යයේ අගය මකා දැමෙනු ඇත, නමුත් එතෙක් alertValue
ශ්රිතයට විචල්යයේ අගය කියවීමට / ලිවීමට හැකි closure
වේ.
ඔබ මෙම කේතය ක්රියාත්මක කරන්නේ නම්, පළමු ක්රියාවලිය closure
විචල්යයට 0 අගයක් ලබා දී ශ්රිතය නැවත ලියන්නේ:
var closure_example = function(){
alertValue : function(){
closure++;
alert(closure);
}
}
ශ්රිතය ක්රියාත්මක කිරීම alertValue
සඳහා දේශීය විචල්යය අවශ්ය වන හෙයින් closure
, එය කලින් පවරා ඇති දේශීය විචල්යයේ අගය සමඟ බැඳී පවතී closure
.
දැන් ඔබ closure_example
ශ්රිතය අමතන සෑම අවස්ථාවකම එය closure
විචල්යයේ වැඩි කළ අගය ලියා තබනු ඇත alert(closure)
.
closure_example.alertValue()//alerts value 1
closure_example.alertValue()//alerts value 2
closure_example.alertValue()//alerts value 3
//etc.
“වසා දැමීම” යනු සාරාංශයක් ලෙස සමහර ප්රාදේශීය රාජ්ය සහ සමහර කේත පැකේජයකට ඒකාබද්ධ කිරීමයි. සාමාන්යයෙන්, ප්රාදේශීය රාජ්යය පැමිණෙන්නේ අවට ඇති (ශබ්දකෝෂ) විෂය පථයකින් වන අතර කේතය (අත්යවශ්යයෙන්ම) අභ්යන්තර ශ්රිතයක් වන අතර එය නැවත පිටතට යවනු ලැබේ. වසා දැමීම යනු අභ්යන්තර ශ්රිතය දකින ග්රහිත විචල්යයන්ගේ එකතුවක් සහ අභ්යන්තර ශ්රිතයේ කේතයයි.
නුහුරු නුපුරුදු නිසා අවාසනාවකට එය පැහැදිලි කිරීමට ටිකක් අපහසු වන එකකි.
අතීතයේ දී මම සාර්ථකව භාවිතා කළ එක් ප්රතිසමයක් නම්, “අපට පොත” යනුවෙන් යමක් ඇතැයි සිතන්න, කාමරය වසා දැමීමේදී, “පොත” යනු එහි පිටපතක්, කෙළවරේ, TAOCP හි පිටපතක්, නමුත් මේසය වැසීම මත ය. , එය ඩ්රෙස්ඩන් ලිපිගොනු පොතක පිටපතකි. එබැවින් ඔබ සිටින්නේ කුමන සංවෘතද යන්න මත පදනම්ව, 'මට පොත දෙන්න' යන කේතය විවිධ දේ සිදුවීමට හේතු වේ. "
static
දේශීය විචල්යයක් සහිත සී ශ්රිතයක් වසා දැමීමක් ලෙස සැලකිය හැකිද? හස්කල් හි වසා දැමීම්වලට රාජ්ය සම්බන්ධ වේද?
static
දේශීය විචල්යයක් සමඟ, ඔබට හරියටම එකක් තිබේ).
'රාජ්යය' යන සංකල්පය නිර්වචනය නොකර වසා දැමීම යනු කුමක්ද යන්න නිර්වචනය කිරීම දුෂ්කර ය.
මූලික වශයෙන්, කාර්යයන් පළමු පන්තියේ අගයන් ලෙස සලකන පූර්ණ ශබ්ද කෝෂ සහිත භාෂාවක, විශේෂ දෙයක් සිදු වේ. මම මේ වගේ දෙයක් කරනවා නම්:
function foo(x)
return x
end
x = foo
විචල්යය x
යොමු කිරීම් function foo()
පමණක් නොව foo
එය නැවත පැමිණෙන විට තත්වය ඉතිරිව ඇති බව ද සඳහන් කරයි . සැබෑ මැජික් සිදුවන්නේ foo
වෙනත් කාර්යයන් එහි විෂය පථය තුළ තවදුරටත් අර්ථ දක්වා ඇති විට ය; එය තමන්ගේම කුඩා පරිසරයක් හා සමානයි ('සාමාන්යයෙන්' අපි ගෝලීය පරිසරයක කාර්යයන් නිර්වචනය කරනවා සේම).
ක්රියාකාරීව එයට C ++ (C?) හි ස්ථිතික මූලපදය හා සමාන බොහෝ ගැටලු විසඳිය හැකි අතර එය බහු ක්රියාකාරී ඇමතුම් පුරා දේශීය විචල්ය තත්වයක් රඳවා ගනී; කෙසේ වෙතත් එය ශ්රිතයකට එකම මූලධර්මය (ස්ථිතික විචල්යය) යෙදීම හා සමාන වේ. වසා දැමීම මඟින් සමස්ත ශ්රිතයේම සුරැකීමට සහය එක් කරයි (C ++ හි ස්ථිතික ශ්රිත සමඟ කිසිදු සම්බන්ධයක් නැත).
කාර්යයන් පළමු පන්තියේ අගයන් ලෙස සැලකීම සහ වසා දැමීම් සඳහා ආධාරක එකතු කිරීම යන්නෙන් අදහස් කරන්නේ ඔබට එකම ශ්රිතයේ අවස්ථා එකකට වඩා වැඩි ප්රමාණයක් මතකයේ තිබිය හැකි බවයි (පන්ති වලට සමාන). මෙයින් අදහස් කරන්නේ ශ්රිතයක් තුළ C ++ ස්ථිතික විචල්යයන් සමඟ කටයුතු කිරීමේදී අවශ්ය වන පරිදි ශ්රිතයේ තත්වය නැවත සැකසීමකින් තොරව ඔබට එකම කේතය නැවත භාවිතා කළ හැකිය (මේ පිළිබඳව වැරදි විය හැකිද?).
මෙන්න ලුආගේ වසා දැමීමේ සහාය පිළිබඳ පරීක්ෂණ කිහිපයක්.
--Closure testing
--By Trae Barlow
--
function myclosure()
print(pvalue)--nil
local pvalue = pvalue or 10
return function()
pvalue = pvalue + 10 --20, 31, 42, 53(53 never printed)
print(pvalue)
pvalue = pvalue + 1 --21, 32, 43(pvalue state saved through multiple calls)
return pvalue
end
end
x = myclosure() --x now references anonymous function inside myclosure()
x()--nil, 20
x() --21, 31
x() --32, 42
--43, 53 -- if we iterated x() again
ප්රතිපල:
nil
20
31
42
එය උපක්රමශීලී විය හැකි අතර, එය බොහෝ විට භාෂාවෙන් භාෂාවට වෙනස් විය හැකි නමුත්, ශ්රිතයක් ක්රියාත්මක වන සෑම විටම එහි තත්වය යළි පිහිටුවන බව ලුවා හි පෙනේ. මා එසේ කියන්නේ අප විසින් myclosure
ශ්රිතයට / තත්වයට කෙලින්ම ප්රවේශ වන්නේ නම් (එය නැවත පැමිණෙන නිර්නාමික ශ්රිතය හරහා නොව) ඉහත කේතයේ ප්රති results ල වෙනස් pvalue
වනු ඇති නිසා ය. නමුත් අපි x (නිර්නාමික ශ්රිතය) හරහා මයික්ලෝසර් තත්වයට පිවිසෙන්නේ නම් pvalue
එය සජීවීව හා මතකයේ කොතැනක හෝ ඇති බව ඔබට දැක ගත හැකිය . එයට තව ටිකක් ඇති බව මම සැක කරමි, සමහර විට ක්රියාත්මක කිරීමේ ස්වභාවය වඩා හොඳින් යමෙකුට පැහැදිලි කළ හැකිය.
PS: මම C ++ 11 (පෙර සංස්කරණවල ඇති දේ හැර) ලෙවකෑමක් නොදනිමි, එබැවින් මෙය C ++ 11 සහ Lua හි වසා දැමීම් අතර සංසන්දනයක් නොවන බව සලකන්න. එසේම, ලුවා සිට සී ++ දක්වා ඇති සියලුම 'රේඛා' ස්ථිතික විචල්යයන් හා සමාන කිරීම් වන අතර වසා දැමීම් 100% සමාන නොවේ; සමහර විට ඒවා සමාන ගැටළු විසඳීමට භාවිතා කළත්.
මට විශ්වාස නැති දෙය නම්, ඉහත කේත උදාහරණයේ දී, නිර්නාමික ශ්රිතය හෝ ඉහළ පෙළේ ශ්රිතය වසා දැමීමක් ලෙස සලකන්නේ ද?
වසා දැමීම යනු රාජ්යයට සම්බන්ධ වූ ශ්රිතයකි:
පර්ල් වලදී ඔබ මේ වගේ වසා දැමීම් නිර්මාණය කරයි:
#!/usr/bin/perl
# This function creates a closure.
sub getHelloPrint
{
# Bind state for the function we are returning.
my ($first) = @_;a
# The function returned will have access to the variable $first
return sub { my ($second) = @_; print "$first $second\n"; };
}
my $hw = getHelloPrint("Hello");
my $gw = getHelloPrint("Goodby");
&$hw("World"); // Print Hello World
&$gw("World"); // PRint Goodby World
C ++ සමඟ සපයා ඇති නව ක්රියාකාරිත්වය දෙස බැලුවහොත්.
වත්මන් තත්වය වස්තුවට බැඳීමට ද එය ඔබට ඉඩ දෙයි:
#include <string>
#include <iostream>
#include <functional>
std::function<void(std::string const&)> getLambda(std::string const& first)
{
// Here we bind `first` to the function
// The second parameter will be passed when we call the function
return [first](std::string const& second) -> void
{ std::cout << first << " " << second << "\n";
};
}
int main(int argc, char* argv[])
{
auto hw = getLambda("Hello");
auto gw = getLambda("GoodBye");
hw("World");
gw("World");
}
සරල කාර්යයක් සලකා බලමු:
function f1(x) {
// ... something
}
මෙම ශ්රිතය වෙනත් මට්ටමේ ශ්රිතයක් තුළ කූඩු කර නොමැති නිසා එය ඉහළ මට්ටමේ ශ්රිතයක් ලෙස හැඳින්වේ. සෑම ජාවාස්ක්රිප්ට් ශ්රිතයක්ම “විෂය පථය” යනුවෙන් හැඳින්වෙන වස්තු ලැයිස්තුවක් සමඟ සම්බන්ධ වේ . මෙම විෂය පථය ඇණවුම් කරන ලද වස්තු ලැයිස්තුවකි. මෙම සෑම වස්තුවක්ම සමහර විචල්යයන් අර්ථ දක්වයි.
ඉහළ මට්ටමේ කාර්යයන් වලදී, විෂය පථය තනි වස්තුවක් වන ගෝලීය වස්තුවකින් සමන්විත වේ. උදාහරණයක් ලෙස, f1
ඉහත ශ්රිතයට විෂය පථ දාමයක් ඇති අතර එහි තනි වස්තුවක් ඇති අතර එය සියලු ගෝලීය විචල්යයන් අර්ථ දක්වයි. .
මෙම ශ්රිතය ආයාචනා කළ විට, ජාවාස්ක්රිප්ට් “සක්රිය වස්තුවක්” ලෙස යමක් නිර්මාණය කර එය විෂය පථයේ ඉහළින් තබයි. මෙම වස්තුවෙහි සියලුම දේශීය විචල්යයන් අඩංගු වේ (උදාහරණයක් ලෙස x
මෙහි). එබැවින් දැන් අපට විෂය පථයේ වස්තු දෙකක් ඇත: පළමුවැන්න සක්රීය වස්තුව වන අතර ඊට යටින් ගෝලීය වස්තුව වේ.
විවිධ වේලාවන්හිදී වස්තූන් දෙක විෂය පථයට ඇතුළත් කර ඇති බව ඉතා ප්රවේශමෙන් සලකන්න. ශ්රිතය අර්ථ දක්වන විට ගෝලීය වස්තුව දමනු ලැබේ (එනම්, ජාවාස්ක්රිප්ට් ශ්රිතය විග්රහ කොට ශ්රිත වස්තුව නිර්මාණය කළ විට), සහ ක්රියාකාරී වස්තුව ඇතුළු වන විට සක්රිය වස්තුව ඇතුල් වේ.
ඉතින්, අපි දැන් මෙය දනිමු:
අපි කැදැලි කාර්යයන් සමඟ කටයුතු කරන විට තත්වය සිත්ගන්නාසුළු වේ. ඉතින්, අපි එකක් නිර්මාණය කරමු:
function f1(x) {
function f2(y) {
// ... something
}
}
f1
නිර්වචනය කළ විට අපට ගෝලීය වස්තුව පමණක් අඩංගු විෂය පථයක් ලැබේ.
දැන් f1
ඇමතූ විට , විෂය පථයේ දාමය f1
සක්රීය වස්තුව ලබා ගනී. මෙම සක්රිය වස්තුවෙහි ශ්රිතය වන විචල්යය x
සහ විචල්යය අඩංගු වේ f2
. තවද, f2
එය අර්ථ දක්වා ඇති බව සලකන්න . එබැවින්, මෙම අවස්ථාවෙහිදී, ජාවාස්ක්රිප්ට් සඳහා නව විෂය පථයක් ද ඉතිරි කරයි f2
. මෙම අභ්යන්තර ශ්රිතය සඳහා සුරකින ලද විෂය පථය දැනට ක්රියාත්මක වන විෂය පථ දාමයයි. වත්මන් විෂය පථය දාමය වේ f1
. ඒ නිසා f2
ගේ විෂය පථය දාම වේ f1
ගේ වත්මන් සකී්රය වස්තුව අඩංගු - විෂය පථය දාම f1
හා ගෝලීය වස්තුව.
f2
එය හැඳින්වූ විට , එය සක්රීය කිරීමේ වස්තුව අඩංගු y
වන අතර එහි විෂය පථයට එකතු කර ඇති අතර එය දැනටමත් සක්රිය වස්තුව f1
සහ ගෝලීය වස්තුව අඩංගු වේ .
තවත් කැදැලි ශ්රිතයක් නිර්වචනය කර ඇත්නම් f2
, එහි විෂය පථයේ අර්ථ දැක්වීමේ වේලාවට වස්තු තුනක් (බාහිර ශ්රිත දෙකක සක්රීය වස්තු 2 ක් සහ ගෝලීය වස්තුව) අඩංගු වන අතර ඉන්වොයිසි වේලාවේදී 4 ක් අඩංගු වේ.
ඉතින්, දැන් අපට තේරෙනවා විෂය පථය ක්රියා කරන ආකාරය නමුත් අපි තවමත් වසා දැමීම් ගැන කතා කර නැත.
ශ්රිතයේ විචල්යයන් නිරාකරණය කර ඇති ශ්රිත වස්තුවක් සහ විෂය පථයක් (විචල්ය බන්ධන සමූහයක්) සංයෝජනය පරිගණක විද්යා සාහිත්යයේ වසා දැමීමක් ලෙස හැඳින්වේ - ජාවාස්ක්රිප්ට් ඩේවිඩ් ෆ්ලැනගන් විසින් නිශ්චිත මාර්ගෝපදේශය
බොහෝ ශ්රිතයන් ආයාචනය කරනු ලබන්නේ ශ්රිතය නිර්වචනය කරන විට ක්රියාත්මක වූ එකම විෂය පථ දාමය භාවිතා කර වන අතර එය වසා දැමීමක් සිදුවීම ඇත්තෙන්ම වැදගත් නොවේ. ඒවා නිර්වචනය කරන විට බලපැවැත්වූ ඒවාට වඩා වෙනස් විෂය පථයක් යටතේ ආයාචනා කරන විට වසා දැමීම් සිත්ගන්නාසුළු වේ. මෙය වඩාත් සුලභව සිදුවන්නේ කැදැලි ශ්රිත වස්තුවක් අර්ථ දක්වා ඇති ශ්රිතයෙන් ආපසු ලබා දෙන විටය .
ශ්රිතය නැවත පැමිණි විට, එම සක්රිය වස්තුව විෂය පථයෙන් ඉවත් කරනු ලැබේ. කැදැලි කාර්යයන් නොතිබුනේ නම්, සක්රීය වස්තුව පිළිබඳ වැඩි සඳහනක් නොමැති අතර එය කසළ එකතු වේ. කැදැලි ශ්රිත නිර්වචනය කර ඇත්නම්, එම එක් එක් ශ්රිතයට විෂය පථ දාමය ගැන සඳහනක් ඇති අතර, එම විෂය පථය සක්රීය වස්තුවට යොමු වේ.
කෙසේ වෙතත්, එම කැදැලි ශ්රිත වස්තූන් ඒවායේ බාහිර ක්රියාකාරිත්වය තුළ පවතින්නේ නම්, ඒවාම කුණු කසළ එකතු කරනු ලැබේ. නමුත් ශ්රිතය කැදැලි ශ්රිතයක් නිර්වචනය කර එය නැවත ලබා දෙන්නේ නම් හෝ එය කොතැනක හෝ දේපලක් තුළ ගබඩා කරන්නේ නම්, එවිට කූඩු කළ ශ්රිතයට බාහිර සඳහනක් ඇත. එය කසළ එකතු නොවන අතර එය සඳහන් කරන සක්රිය වස්තුව කසළ එකතු නොකෙරේ.
අපගේ ඉහත උදාහරණය, අපි ආපසු හැරී එන්නේ නැහැ f2
සිට f1
ඒ නිසා,, ඇමතුමක් විට f1
ප්රතිලාභ, එහි සක්රිය වස්තුව එහි විෂය පථය දාම හා කුණු කසළ එකතු ඉවත් කරනු ඇත. නමුත් අපට මේ වගේ දෙයක් තිබුණා නම්:
function f1(x) {
function f2(y) {
// ... something
}
return f2;
}
මෙන්න, ආපසු පැමිණීමේ f2
විෂය පථය සක්රීය කිරීමේ වස්තුව අඩංගු වන f1
අතර එම නිසා එය කසළ එකතු නොවේ. මෙම අවස්ථාවෙහිදී, අප අමතන්නේ නම්, අප පිටත සිටියද එයට විචල්යයට f2
ප්රවේශ විය හැකිය.f1
x
f1
එබැවින් ශ්රිතයක් මඟින් එහි විෂය පථය එය සමඟ තබා ගන්නා අතර විෂය පථ දාමය සමඟ බාහිර ශ්රිතවල සියලුම සක්රීය වස්තු පැමිණේ. වසා දැමීමේ සාරය මෙයයි. ජාවාස්ක්රිප්ට් හි කාර්යයන් “ශබ්දකෝෂයෙන් පරිහරණය කර ඇති ” බව අපි කියමු , එයින් අදහස් කරන්නේ ඒවා ඇමතූ විට ක්රියාකාරී වූ විෂය පථයට පටහැනිව අර්ථ දැක්වීමේදී ක්රියාකාරී වූ විෂය පථය සුරකිනු ඇති බවයි.
පුද්ගලික විචල්යයන් ආසන්න වශයෙන් ගණනය කිරීම, සිදුවීම් මත පදනම් වූ ක්රමලේඛනය, අර්ධ යෙදුම වැනි වසා දැමීම් ඇතුළත් ප්රබල ක්රමලේඛන ක්රම ගණනාවක් තිබේ .
වසා දැමීමට සහාය වන සියලුම භාෂාවන්ට මේ සියල්ල අදාළ වන බව සලකන්න. උදාහරණයක් ලෙස PHP (5.3+), පයිතන්, රූබි ආදිය.
වසා දැමීම යනු සම්පාදක ප්රශස්තිකරණයකි (සින්ටැක්ටික් සීනි?). සමහර අය මෙය දුප්පත් මිනිසාගේ වස්තුව ලෙසද හැඳින්වේ.
එරික් ලිපර්ට්ගේ පිළිතුර බලන්න : (පහත උපුටා ගැනීම)
සම්පාදකයා මෙවැනි කේත ජනනය කරයි:
private class Locals
{
public int count;
public void Anonymous()
{
this.count++;
}
}
public Action Counter()
{
Locals locals = new Locals();
locals.count = 0;
Action counter = new Action(locals.Anonymous);
return counter;
}
තේරුමක් තිබේද?
එසේම, ඔබ සැසඳීම් ඉල්ලා සිටියේය. VB සහ JScript යන දෙකම එකම ආකාරයකින් වසා දැමීම් නිර්මාණය කරයි.