සම්මතයන් 6 හඳුන්වා ඇති letප්රකාශය .
එය "දේශීය" විචල්යයක් ලෙස විස්තර කර ඇති බව මා අසා ඇත, නමුත් එය varයතුරු පදයට වඩා වෙනස් ලෙස හැසිරෙන්නේ කෙසේදැයි මට තවමත් විශ්වාස නැත .
වෙනස්කම් මොනවාද? letනැවත භාවිතා කළ යුත්තේ කවදාද?var ?
සම්මතයන් 6 හඳුන්වා ඇති letප්රකාශය .
එය "දේශීය" විචල්යයක් ලෙස විස්තර කර ඇති බව මා අසා ඇත, නමුත් එය varයතුරු පදයට වඩා වෙනස් ලෙස හැසිරෙන්නේ කෙසේදැයි මට තවමත් විශ්වාස නැත .
වෙනස්කම් මොනවාද? letනැවත භාවිතා කළ යුත්තේ කවදාද?var ?
Answers:
ප්රධාන වෙනස වන්නේ විෂය පථය පාලනය කිරීමයි. විචල්ය මගින් ප්රකාශයට varඅතර වහාම කාර්යය ශරීරය (ඒ අනුව මෙම උත්සවයට විෂය පථය) වෙත scoped ඇත ඉඟි පද letවිචල්ය වහාම කිරීමට scoped ඇත කවරෙ මගින් වන වාරණ { }(ඒ අනුව වාරණ විෂය පථය).
function run() {
var foo = "Foo";
let bar = "Bar";
console.log(foo, bar);
{
let baz = "Bazz";
console.log(baz);
}
console.log(baz); // ReferenceError
}
run();
හේතුව letඉඟි පද භාෂාව වෙත හඳුන්වා දෙන ලදී කාර්යය විෂය පථය ඔබට පමණක් වූ අතර JavaScript දී දෝෂ ප්රධාන මූලාශ්ර එකක් විය.
තවත් ස්ටැක් ඕවර් ප්රවාහ ප්රශ්නයකින් මෙම උදාහරණය දෙස බලන්න :
var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++) {
// and store them in funcs
funcs[i] = function() {
// each should log its value.
console.log("My value: " + i);
};
}
for (var j = 0; j < 3; j++) {
// and now let's run each one to see
funcs[j]();
}
My value: 3 සෑම අවස්ථාවකම කොන්සෝලය සඳහා ප්රතිදානය විය funcs[j]();නිර්නාමික ශ්රිත එකම විචල්යයට බැඳී ඇති බැවින් .
ලූප වලින් නිවැරදි අගය ග්රහණය කර ගැනීම සඳහා මිනිසුන්ට වහාම ආයාචනා කරන ලද කාර්යයන් නිර්මාණය කිරීමට සිදු වූ නමුත් එය ද කෙස් කළඹකි.
varමූල පදය සමඟ ප්රකාශිත විචල්යයන් ඔසවා ඇති අතර ( undefinedකේතය ක්රියාත්මක වීමට පෙර ආරම්භ කරන ලදි) එයින් අදහස් වන්නේ ඒවා ප්රකාශයට පත් කිරීමටත් පෙර ඒවායේ සංවෘත විෂය පථයට ප්රවේශ විය හැකි බවයි:
function run() {
console.log(foo); // undefined
var foo = "Foo";
console.log(foo); // Foo
}
run();
letඒවායේ අර්ථ දැක්වීම ඇගයීමට ලක් කරන තුරු විචල්යයන් ආරම්භ නොවේ. ආරම්භයට පෙර ඒවාට ප්රවේශ වීම a ReferenceError. විචල්යය බ්ලොක් ආරම්භයේ සිට ආරම්භය සැකසෙන තෙක් "තාවකාලික මළ කලාපයේ" පවතින බව කියනු ලැබේ.
function checkHoisting() {
console.log(foo); // ReferenceError
let foo = "Foo";
console.log(foo); // Foo
}
checkHoisting();
ඉහළ මට්ටමින්, letමෙන් නොව var, ගෝලීය වස්තුව මත දේපලක් නිර්මාණය නොකරයි:
var foo = "Foo"; // globally scoped
let bar = "Bar"; // globally scoped
console.log(window.foo); // Foo
console.log(window.bar); // undefined
දැඩි ආකාරයෙන්, varlet සින්ටැක්ස් දෝෂයක් මතු කරන අතරම එකම විචල්යය එකම විෂය පථය තුළ නැවත ප්රකාශ කිරීමට ඔබට ඉඩ සලසයි.
'use strict';
var foo = "foo1";
var foo = "foo2"; // No problem, 'foo' is replaced.
let bar = "bar1";
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared
letවාරණ ප්රකාශනය let (variable declaration) statementසම්මත නොවන අතර අනාගතයේදී ඉවත් කරනු ලැබේ, bugzilla.mozilla.org/show_bug.cgi?id=1023609 .
letවසා දැමීමේ ගැටළු වළක්වා ගැනීමට ද භාවිතා කළ හැකිය. පහත උදාහරණවල පෙන්වා ඇති පරිදි පැරණි සඳහනක් තබා ගැනීමට වඩා එය නැවුම් වටිනාකමක් බැඳ තබයි.
for(var i=1; i<6; i++) {
$("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Clicking on each number will log to console:</p>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>
ඉහත කේතය සම්භාව්ය ජාවාස්ක්රිප්ට් වැසීමේ ගැටලුවක් පෙන්නුම් කරයි. වෙත යොමු කිරීමi විචල්ය වෙනුවට සැබෑ වටිනාකම වඩා, ක්ලික් හසුරුවන්නා වසා ගබඩා කොට ඇත i.
සෑම ක්ලික් හසුරුවන්නෙක්ම එකම වස්තුවකට යොමු වන්නේ 6 ක් ඇති එක් ප්රති වස්තුවක් පමණක් ඇති නිසා ඔබට එක් ක්ලික් එකකට හයක් ලැබෙනු ඇත.
සාමාන්ය විසඳුමක් නම් මෙය නිර්නාමික ශ්රිතයක් තුළට ඔතා iතර්කයක් ලෙස සම්මත කිරීමයි. පහත දැක්වෙන කේතයේ පෙන්වා ඇති පරිදි letඒ වෙනුවට භාවිතා කිරීමෙන් එවැනි ගැටළු ද දැන් වළක්වා ගත හැකිය var.
(ක්රෝම් සහ ෆයර්ෆොක්ස් 50 හි පරීක්ෂා කර ඇත)
for(let i=1; i<6; i++) {
$("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Clicking on each number will log to console:</p>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>
let, නමුත් එය සියලු බොත්තම් සඳහා "6" දැනුම් දෙයි. letහැසිරිය යුතු ආකාරය පවසන කිසියම් ප්රභවයක් ඔබට තිබේද ?
letඇත්තෙන්ම ප්රයෝජනවත් වන්නේ මන්දැයි මට දැන් පෙනේ . සිදුවීම් සවන්දෙන්නන් ලූපයක් ලෙස සැකසීමට තවදුරටත් iඑක් එක් පුනරාවර්තනයේදී දේශීයව පරික්ෂා කිරීම සඳහා ක්ෂණිකව ආයාචිත ශ්රිත ප්රකාශනයක් අවශ්ය නොවේ .
letසහ අතර ඇති වෙනස varකුමක්ද?varප්රකාශයක් භාවිතා කර නිර්වචනය කරන ලද විචල්යයක් ශ්රිතයේ ආරම්භයේ සිටම එය අර්ථ දක්වා ඇත. (*)letප්රකාශයක් පමණක් දන්නා , වාරණ එය පටන් අර්ථ මොහොතේ සිට, එය අර්ථ දක්වා ඇත. (**)වෙනස තේරුම් ගැනීමට, පහත කේතය සලකා බලන්න:
// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here
function loop(arr) {
// i IS known here, but undefined
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( var i = 0; i < arr.length; i++ ) {
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( let j = 0; j < arr.length; j++ ) {
// i IS known here, and has a value
// j IS known here, and has a value
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
}
loop([1,2,3,4]);
for( var k = 0; k < arr.length; k++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
};
for( let l = 0; l < arr.length; l++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS known here, and has a value
};
loop([1,2,3,4]);
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
මෙහිදී, අපගේ විචල්යය jප්රථම වරට ලූප සඳහා පමණක් දන්නා නමුත් පෙර සහ පසු නොවන බව අපට පෙනේ . එහෙත්, අපගේ විචල්යය iසමස්ත ශ්රිතය තුළම දන්නා කරුණකි.
තවද, බ්ලොක් ස්කොප් විචල්යයන් ප්රකාශයට පත් කිරීමට පෙර නොදන්නා බව සලකන්න. එකම බ්ලොක් විෂය පථය එකම බ්ලොක් තුළ නැවත ප්රකාශ කිරීමට ඔබට අවසර නැත. මෙමඟින් බ්ලොක් ස්කොප් විචල්යයන් ගෝලීයව හෝ ක්රියාකාරීව විෂය පථයට වඩා අඩු දෝෂයක් ඇති කරයි, ඒවා ඔසවා ඇති අතර බහු ප්රකාශන වලදී කිසිදු දෝෂයක් ඇති නොවේ.
letඅද භාවිතා කිරීම ආරක්ෂිතද ?සමහර අය තර්ක කරන්නේ අනාගතයේ දී අපි අවසර ප්රකාශ පමණක් භාවිතා කරන බවත් var ප්රකාශ යල් පැන යන බවත් ය. ජාවාස්ක්රිප්ට් ගුරු කයිල් සිම්ප්සන් එය එසේ නොවනු ඇතැයි විශ්වාස කරන්නේ මන්ද යන්න පිළිබඳව ඉතා සවිස්තරාත්මක ලිපියක් ලිවීය .
කෙසේ වෙතත් අද එය එසේ නොවේ. ඇත්ත වශයෙන්ම, letප්රකාශය භාවිතා කිරීම ආරක්ෂිත දැයි අප අපෙන්ම අසාගත යුතුය . එම ප්රශ්නයට පිළිතුර ඔබේ පරිසරය මත රඳා පවතී:
ඔබ සේවාදායක පැත්තේ ජාවාස්ක්රිප්ට් කේතය ( Node.js ) ලියන්නේ නම් , ඔබට ආරක්ෂිතව letප්රකාශය භාවිතා කළ හැකිය .
ඔබ සේවාදායක පාර්ශවීය ජාවාස්ක්රිප්ට් කේතයක් ලියන්නේ නම් සහ බ්රව්සර් මත පදනම් වූ ට්රාන්ස්පෝලර් ( ට්රේසර් හෝ බාබල්- ස්ටැන්ඩලෝන් වැනි ) භාවිතා කරන්නේ නම්, ඔබට ආරක්ෂිතව letප්රකාශය භාවිතා කළ හැකිය , කෙසේ වෙතත් ඔබේ කේතය කාර්ය සාධනය සම්බන්ධයෙන් ප්රශස්ත විය හැකි නමුත් ඕනෑම දෙයක් විය හැකිය.
ඔබ සේවාදායක පාර්ශවීය ජාවාස්ක්රිප්ට් කේතයක් ලියන්නේ නම් සහ නෝඩ් මත පදනම් වූ ට්රාන්ස්පෝලර් භාවිතා කරන්නේ නම් ( ට්රේසර් ෂෙල් ස්ක්රිප්ට් හෝ බාබෙල් වැනි ), ඔබට එම letප්රකාශය ආරක්ෂිතව භාවිතා කළ හැකිය . ඔබේ බ්රව්සරය දැනගත හැකි වන්නේ සම්ප්රේෂණය කළ කේතය ගැන පමණක් බැවින්, කාර්ය සාධන අඩුපාඩු සීමිත විය යුතුය.
ඔබ සේවාදායක පාර්ශවීය ජාවාස්ක්රිප්ට් කේතයක් ලියන්නේ නම් සහ ප්රවාහකයෙකු භාවිතා නොකරන්නේ නම්, ඔබ බ්රව්සරයේ සහාය සලකා බැලිය යුතුය.
කිසිසේත් සහාය නොදක්වන සමහර බ්රව්සර් තවමත් letඇත:
ඔබ letමෙම පිළිතුර කියවන අවස්ථාවේ ප්රකාශයට සහය දක්වන බ්රව්සර් පිළිබඳ යාවත්කාලීන දළ විශ්ලේෂණයක් සඳහා , මෙම Can I Useපිටුව බලන්න .
(*) ජාවාස්ක්රිප්ට් විචල්යයන් ඔසවා ඇති බැවින් ඒවා ප්රකාශයට පත් කිරීමට පෙර ගෝලීයව හා ක්රියාකාරීව විෂය පථයන් ආරම්භ කර භාවිතා කළ හැකිය . මෙයින් අදහස් කරන්නේ ප්රකාශන සෑම විටම විෂය පථයට ඉහළින් ඇති බවයි.
(**) අවහිර කළ හැකි විචල්යයන් ඔසවා නැත
iශ්රිත කොටසෙහි සෑම තැනකම දන්නා කරුණකි! undefinedඔබ වටිනාකමක් ලබා දෙන තෙක් එය (එසවීම හේතුවෙන්) ආරම්භ වේ ! ps: letද ඔසවා ඇත (එහි බ්ලොක් අඩංගු මුදුනට), නමුත් ReferenceErrorපළමු පැවරුමට පෙර බ්ලොක් එකෙහි සඳහන් කළ විට එය ලබා දෙනු ඇත . (ps2: මම අර්ධ-අර්ධ-ගැති පුද්ගලයෙක්, නමුත් ඔබට සැබවින්ම අර්ධ සළකුණක් අවශ්ය නොවේ). එසේ පැවසුවහොත්, සහාය පිළිබඳ යථාර්ථය පරීක්ෂා කිරීම ගැන ස්තූතියි!
letසහ අතර හැසිරීමේ වෙනස පැහැදිලි කළ යුතුය var!
letහා constලදී ඇත්ත වශයෙන්ම ඔබ ඔවුන්ගේ අමතර පහසුකම් අවශ්ය වන විට පමණක් භාවිතා කිරීම රෙකමදාරු කරනු ක්රියාත්මක / 'වැඩි වැඩ නිසා (කපා පමණක් const වැනි) මෙම අමතර අංග පරීක්ෂා නිසා, (සහ) (වත්මන්) එන්ජිම (ය) බලාත්මක කිරීම / පරීක්ෂා කිරීම / සත්යාපනය / සැකසීම සඳහා (සහ විෂය පථයේ අතිරේක විෂය පථ-නෝඩ්).
මෙන්න උදාහරණ කිහිපයක් සමඟ මූලික පදය පිළිබඳ පැහැදිලි කිරීමක්let .
letගොඩක් වැඩ කරනවා වගේvar. ප්රධාන වෙනස වන්නේvarවිචල්යයේ විෂය පථය සමස්ත කොටු කිරීමේ කාර්යයයි
විකිපීඩියාවේ මෙම වගුවේ දැක්වෙන්නේ ජාවාස්ක්රිප්ට් 1.7 සඳහා සහය දක්වන බ්රව්සර් මොනවාද යන්නයි.
එයට සහය දක්වන්නේ මොසිල්ලා සහ ක්රෝම් බ්රව්සර් පමණි. අයිඊ, සෆාරි සහ වෙනත් අය එසේ නොකරයි.
පිළිගත් පිළිතුරට කරුණක් නොමැත:
{
let a = 123;
};
console.log(a); // ReferenceError: a is not defined
forලූප් ආරම්භකය තුළ පමණක් වන අතර , සීමාවන්හි යෙදීමේ විෂය පථය නාටකාකාර ලෙස පටු කරයි let. ඉහළට.
letletමූල පදය භාවිතයෙන් ප්රකාශයට පත් කරන ලද විචල්යයන් බ්ලොක්-ස්කෝප් කර ඇති අතර එයින් අදහස් කරන්නේ ඒවා ලබා ගත හැක්කේ ඒවා ප්රකාශයට පත් කළ කොටසෙහි පමණක් බවයි.
ඉහළ මට්ටමේ දී, විචල්යයන් භාවිතා කරමින් ප්රකාශිත letගෝලීය වස්තුවෙහි ගුණාංග නිර්මාණය නොකරයි.
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined
ශ්රිතයක් ඇතුළත (නමුත් බ්ලොක් එකකින් පිටත), letසමාන විෂය පථයක් ඇත var.
(() => {
var functionScopedVariable = 42;
let blockScopedVariable = 43;
console.log(functionScopedVariable); // 42
console.log(blockScopedVariable); // 43
})();
console.log(functionScopedVariable); // ReferenceError: functionScopedVariable is not defined
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
letබ්ලොක් එකක් තුළ භාවිතා කර ප්රකාශිත විචල්යයන් එම බ්ලොක් එකෙන් පිටත ප්රවේශ විය නොහැක.
{
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
}
console.log(globalVariable); // 42
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
letලූප වලින් ප්රකාශිත විචල්යයන් යොමු කළ හැක්කේ එම ලූපය තුළ පමණි.
for (var i = 0; i < 3; i++) {
var j = i * 2;
}
console.log(i); // 3
console.log(j); // 4
for (let k = 0; k < 3; k++) {
let l = k * 2;
}
console.log(typeof k); // undefined
console.log(typeof l); // undefined
// Trying to do console.log(k) or console.log(l) here would throw a ReferenceError.
ඔබ ලූපයක් letවෙනුවට භාවිතා කරන්නේ නම් var, එක් එක් පුනරාවර්තනය සමඟ ඔබට නව විචල්යයක් ලැබේ. එයින් අදහස් කරන්නේ ඔබට ලූපයක් තුළ වසා දැමීමක් ආරක්ෂිතව භාවිතා කළ හැකි බවයි.
// Logs 3 thrice, not what we meant.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// Logs 0, 1 and 2, as expected.
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 0);
}
නිසා ලෞකික මළ කලාපය , විචල්ය භාවිතා ප්රකාශ letඔවුන් ප්රකාශ කිරීමට පෙර ප්රවේශ විය නොහැක. එසේ කිරීමට උත්සාහ කිරීම දෝෂයක් ඇති කරයි.
console.log(noTDZ); // undefined
var noTDZ = 43;
console.log(hasTDZ); // ReferenceError: hasTDZ is not defined
let hasTDZ = 42;
ඔබට එකම විචල්යය කිහිප වතාවක් භාවිතා කරමින් ප්රකාශ කළ නොහැක let. letභාවිතයෙන් ප්රකාශයට පත් කරන ලද වෙනත් විචල්යයක් ලෙස එකම අනන්යතාවය භාවිතා කරමින් විචල්යයක් ප්රකාශ කළ නොහැක var.
var a;
var a; // Works fine.
let b;
let b; // SyntaxError: Identifier 'b' has already been declared
var c;
let c; // SyntaxError: Identifier 'c' has already been declared
constconstඑය letබ්ලොක්-ස්කෝප් වලට බෙහෙවින් සමාන වන අතර TDZ ඇත. කෙසේ වෙතත්, වෙනස් කරුණු දෙකක් තිබේ.
භාවිතයෙන් ප්රකාශිත විචල්යය constනැවත පැවරිය නොහැක.
const a = 42;
a = 43; // TypeError: Assignment to constant variable.
වටිනාකම වෙනස් කළ නොහැකි බව එයින් අදහස් නොවන බව සලකන්න. එහි ගුණාංග තවමත් වෙනස් කළ හැකිය.
const obj = {};
obj.a = 42;
console.log(obj.a); // 42
ඔබට වෙනස් කළ නොහැකි වස්තුවක් ලබා ගැනීමට අවශ්ය නම්, ඔබ භාවිතා කළ යුතුය Object.freeze().
භාවිතයෙන් විචල්යයක් ප්රකාශ කිරීමේදී ඔබ සැමවිටම අගයක් නියම කළ යුතුය const.
const a; // SyntaxError: Missing initializer in const declaration
මේ දෙක අතර වෙනස සඳහා උදාහරණයක් මෙන්න (ක්රෝම් සඳහා සහය දැන් ආරම්භ කර ඇත):

ඔබට පෙනෙන පරිදි var jවිචල්යය සඳහා for loop විෂය පථයට (බ්ලොක් විෂය පථයට) පිටතින් අගයක් ඇත, නමුත් let iවිචල්යය for loop විෂය පථයට පිටතින් නිර්වචනය කර නොමැත.
"use strict";
console.log("var:");
for (var j = 0; j < 2; j++) {
console.log(j);
}
console.log(j);
console.log("let:");
for (let i = 0; i < 2; i++) {
console.log(i);
}
console.log(i);
සමහර සියුම් වෙනස්කම් තිබේ - letවිචල්ය විෂය පථය වෙනත් ඕනෑම භාෂාවකින් වැඩි වශයෙන් හෝ අඩු ලෙස හැසිරේ.
උදා: එය කොටු කොටසට විහිදේ, ඒවා ප්රකාශයට පත් කිරීමට පෙර ඒවා නොපවතී.
කෙසේ වෙතත් එය letනව ජාවාස්ක්රිප්ට් ක්රියාවට නැංවීමේ කොටසක් පමණක් වන අතර විවිධ මට්ටමේ බ්රව්සර් සහාය ඇත.
letවන අතර එය 6 වන සංස්කරණ කෙටුම්පතට ඇතුළත් කර ඇති අතර එය බොහෝ විට අවසාන පිරිවිතරයට ඇතුළත් වනු ඇත.
let. සෆාරි, අයිඊ සහ චෝම් සියල්ලම එසේ නොවේ.
letඑසවීම නොකරයි, letඔබේ බ්ලොක් එකේ ඉහළින් අර්ථ දක්වා ඇති විචල්යයක් භාවිතා කිරීම . ඔබට ifකේත පේළි කිහිපයකට වඩා වැඩි ප්රකාශයක් තිබේ නම්, එය අර්ථ දක්වා ඇති තෙක් ඔබට එම විචල්යය භාවිතා කළ නොහැකි බව ඔබට අමතක විය හැකිය. විශාල පොයින්ට් !!!
let එස ඇත තුළ විචල්ය ප්රකාශ ප්රතිඵල පෙර වාරණ දී විචල්ය පිලිබඳව සඳහන්, වාරණ මුදුනට විචල්ය කෙසේ වෙතත්. ReferenceError (මගේ සටහන: ඒ වෙනුවට හොඳ පැරණි undefined). මෙම ප්රකාශය සැකසෙන තෙක් විචල්යය වාරණයේ ආරම්භයේ සිට තාවකාලික මළ කලාපයක පවතී. “ස්විච් ප්රකාශ සඳහා එකම යටි තට්ටුවක් ඇති බැවින්” යන්න සමාන වේ. මූලාශ්රය: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
ප්රධාන වෙනස වන්නේ විෂය පථය අතර, වෙනස කිරීමටද ඇතුළත පමණක් ලබා ගත හැකි විය හැකි විෂය පථය පුඩුවක් සඳහා, මෙන්, එය ප්රකාශ කරනවා var උදාහරණයක් පුඩුවක් පිටත ප්රවේශ විය හැකිය. එම්ඩීඑන් හි ප්රලේඛනයෙන් (උදාහරණ එම්ඩීඑන් වෙතින් ද):
එය භාවිතා කරන වාරණය, ප්රකාශය හෝ ප්රකාශනය සඳහා විෂය පථයට සීමා වූ විචල්යයන් ප්රකාශ කිරීමට ඔබට ඉඩ දෙයි. මෙය var මෙන් නොව යතුරු පදයට වන අතර එය විචල්යයක් ගෝලීයව හෝ දේශීයව සමස්ත ශ්රිතයක් සඳහාම අර්ථ දක්වයි.
ඉඩ දී ඇති පරිදි ප්රකාශයට පත් කරන ලද විචල්යයන්ට ඒවායේ විෂය පථය ලෙස අර්ථ දක්වා ඇති කොටස මෙන්ම අඩංගු ඕනෑම උප බ්ලොක් ද ඇත. මේ ආකාරයෙන්, var වැනි බොහෝ වැඩ කිරීමට ඉඩ දෙන්න . ප්රධාන වෙනස වන්නේ var විචල්යයක විෂය පථය සමස්ත කොටු කිරීමේ කාර්යයයි:
function varTest() {
var x = 1;
if (true) {
var x = 2; // same variable!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // different variable
console.log(x); // 2
}
console.log(x); // 1
}`
ඉහළ මට්ටමේ වැඩසටහන් සහ කාර්යයන් වලදී , var මෙන් නොව , ගෝලීය වස්තුව මත දේපලක් නිර්මාණය නොකරමු . උදාහරණයක් වශයෙන්:
var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined
බ්ලොක් එකක් තුළ භාවිතා කරන විට, විචල්යයේ විෂය පථය එම බ්ලොක් එකට සීමා කරමු. එය ප්රකාශයට පත් කරන ලද ශ්රිතය තුළ විෂය පථය ඇති var අතර වෙනස සැලකිල්ලට ගන්න .
var a = 1;
var b = 2;
if (a === 1) {
var a = 11; // the scope is global
let b = 22; // the scope is inside the if-block
console.log(a); // 11
console.log(b); // 22
}
console.log(a); // 11
console.log(b); // 2
එය ECMA6 විශේෂාංගයද අමතක නොකරන්න, එබැවින් එය තවමත් පූර්ණ සහය නොදක්වයි, එබැවින් එය සෑම විටම බාබල් ආදිය භාවිතා කරමින් ECMA5 වෙත සම්ප්රේෂණය කිරීම වඩා හොඳය ... බාබල් වෙබ් අඩවියට පිවිසීම පිළිබඳ වැඩි විස්තර සඳහා
විචල්ය එසවීම නොවේ
letඇත ඇඳීමට නැහැ ඔවුන් පෙනී වාරණ සමස්ත විෂය පථය. ඊට ප්රතිකූලව, varපහත ලෙස ඔසවා විය.
{
console.log(cc); // undefined. Caused by hoisting
var cc = 23;
}
{
console.log(bb); // ReferenceError: bb is not defined
let bb = 23;
}
ඇත්ත වශයෙන්ම, පර් er බර්ජි, දෙකම varසහ letඔසවා ඇත.
කසළ එකතුව
letමතකය නැවත ලබා ගැනීම සඳහා වසා දැමීම් සහ කසළ එකතු කිරීම සම්බන්ධ අවහිරතා විෂය පථය ප්රයෝජනවත් වේ. සලකා බලන්න,
function process(data) {
//...
}
var hugeData = { .. };
process(hugeData);
var btn = document.getElementById("mybutton");
btn.addEventListener( "click", function click(evt){
//....
});
මෙම clickහසුරුවන්නා callback එම අවශ්ය නොවන hugeDataසියලු දී විචල්ය. න්යායාත්මකව, ධාවනයෙන් පසු process(..), විශාල දත්ත ව්යුහය hugeDataකසළ එකතු කළ හැකිය. කෙසේ වෙතත්, සමහර ජේඑස් එන්ජිමට තවමත් මෙම දැවැන්ත ව්යුහය තබා ගැනීමට සිදුවනු ඇතclick ශ්රිතය සමස්ත විෂය පථයටම වසා ඇති බැවිනි.
කෙසේ වෙතත්, බ්ලොක් විෂය පථයට මෙම විශාල දත්ත ව්යුහය එකතු කරන කසළ බවට පත් කළ හැකිය.
function process(data) {
//...
}
{ // anything declared inside this block can be garbage collected
let hugeData = { .. };
process(hugeData);
}
var btn = document.getElementById("mybutton");
btn.addEventListener( "click", function click(evt){
//....
});let ලූප
letලූපය තුළ එය ලූපයේ එක් එක් පුනරාවර්තනයට නැවත බන්ධනය කළ හැකි අතර, පෙර ලූප පුනරාවර්තනයේ අවසානයේ සිට එහි අගය නැවත පැවරීමට වග බලා ගන්න. සලකා බලන්න,
// print '5' 5 times
for (var i = 0; i < 5; ++i) {
setTimeout(function () {
console.log(i);
}, 1000);
}
කෙසේ වෙතත්, ප්රතිස්ථාපනය varකරන්නlet
// print 1, 2, 3, 4, 5. now
for (let i = 0; i < 5; ++i) {
setTimeout(function () {
console.log(i);
}, 1000);
}
letඅ) ආරම්භක ප්රකාශනය ආ) එක් එක් පුනරාවර්තනය (වර්ධක ප්රකාශනය ඇගයීමට පෙර) සඳහා නව ශබ්දකෝෂ පරිසරයක් නිර්මාණය කිරීම නිසා , වැඩි විස්තර මෙහි ඇත.
අනෙක් අය දැනටමත් ලියා ඇති දේ එකතු කිරීමට උදාහරණයක් මෙන්න. ඔබට ශ්රිත පෙළක් සෑදීමට අවශ්ය යැයි සිතමු adderFunctions, එහිදී සෑම ශ්රිතයක්ම තනි සංඛ්යා තර්කයක් ගෙන අරාවෙහි එකතුව සහ අරාවෙහි ශ්රිත දර්ශකය ලබා දෙයි. යතුරුපදය adderFunctionsභාවිතා කර ලූපයක් සමඟ උත්පාදනය කිරීමට උත්සාහ කිරීම varයමෙකු අ ාන ලෙස අපේක්ෂා කරන ආකාරයට ක්රියා නොකරනු ඇත:
// An array of adder functions.
var adderFunctions = [];
for (var i = 0; i < 1000; i++) {
// We want the function at index i to add the index to its argument.
adderFunctions[i] = function(x) {
// What is i bound to here?
return x + i;
};
}
var add12 = adderFunctions[12];
// Uh oh. The function is bound to i in the outer scope, which is currently 1000.
console.log(add12(8) === 20); // => false
console.log(add12(8) === 1008); // => true
console.log(i); // => 1000
// It gets worse.
i = -8;
console.log(add12(8) === 0); // => true
ඉහත ක්රියාවලිය මඟින් අපේක්ෂිත ශ්රිත පෙළක් ජනනය නොකෙරේ, මන්ද එක් එක් ශ්රිතය නිර්මාණය කරන ලද බ්ලොක් iඑකෙහි පුනරාවර්තනයෙන් ඔබ්බට විෂය පථය විහිදේ for. ඒ වෙනුවට, ලූපය අවසානයේ, iඑක් එක් ශ්රිතය වැසීමේදී, iසෑම නිර්නාමික ශ්රිතයක් සඳහාම ලූපයේ (1000) අවසානයේ ඇති අගය දක්වයි adderFunctions. මෙය අපට කිසිසේත්ම අවශ්ය වූ දෙයක් නොවේ: අපට දැන් එකම ක්රියාකාරිත්වයකින් යුත් මතකයේ විවිධ ශ්රිත 1000 ක් ඇත. අපි පසුව එහි අගය යාවත්කාලීන කළහොත් i, විකෘතිය සියල්ලටම බලපායිadderFunctions .
කෙසේ වෙතත්, අපට letයතුරුපදය භාවිතා කර නැවත උත්සාහ කළ හැකිය :
// Let's try this again.
// NOTE: We're using another ES6 keyword, const, for values that won't
// be reassigned. const and let have similar scoping behavior.
const adderFunctions = [];
for (let i = 0; i < 1000; i++) {
// NOTE: We're using the newer arrow function syntax this time, but
// using the "function(x) { ..." syntax from the previous example
// here would not change the behavior shown.
adderFunctions[i] = x => x + i;
}
const add12 = adderFunctions[12];
// Yay! The behavior is as expected.
console.log(add12(8) === 20); // => true
// i's scope doesn't extend outside the for loop.
console.log(i); // => ReferenceError: i is not defined
මෙම කාලය, ලූපයේ iඑක් එක් නැවත නැවත සිදු forවේ. සෑම ශ්රිතයක්ම දැන් iශ්රිතය නිර්මාණය කරන අවස්ථාවේ වටිනාකම තබා ඇති adderFunctionsඅතර අපේක්ෂිත පරිදි ක්රියා කරයි.
දැන්, හැසිරීම් දෙක මිශ්ර කරන රූපය සහ එකම පිටපතෙහි අළුත් letහා constපැරණි දේ මිශ්ර කිරීමට නිර්දේශ නොකරන්නේ මන්දැයි ඔබට පෙනෙනු varඇත. එසේ කිරීමෙන් ප්රති result ල ලැබිය හැක්කේ දර්ශනීය ලෙස ව්යාකූල කේතයකි.
const doubleAdderFunctions = [];
for (var i = 0; i < 1000; i++) {
const j = i;
doubleAdderFunctions[i] = x => x + i + j;
}
const add18 = doubleAdderFunctions[9];
const add24 = doubleAdderFunctions[12];
// It's not fun debugging situations like this, especially when the
// code is more complex than in this example.
console.log(add18(24) === 42); // => false
console.log(add24(18) === 42); // => false
console.log(add18(24) === add24(18)); // => false
console.log(add18(24) === 2018); // => false
console.log(add24(18) === 2018); // => false
console.log(add18(24) === 1033); // => true
console.log(add24(18) === 1030); // => true
මෙය ඔබට සිදුවීමට ඉඩ නොදෙන්න. ලයිනර් භාවිතා කරන්න.
සටහන: මෙය ඉගැන්වීමේ උදාහරණයකි, ලූපවල
var/letහැසිරීම නිරූපණය කිරීමට අදහස් කරන අතර ක්රියාකාරී වසා දැමීම් ද තේරුම් ගැනීමට පහසු වේ. අංක එකතු කිරීමට මෙය භයානක ක්රමයක් වනු ඇත. නමුත් නිර්නාමික ශ්රිත වැසීම් වලදී දත්ත ග්රහණය කර ගැනීමේ සාමාන්ය තාක්ෂණය වෙනත් ලෝකයේ සැබෑ ලෝකයේ දක්නට ලැබේ. වයි.එම්.එම්.වී.
let value = i; . මෙම forප්රකාශය lexical පරාසය වාරණ නිර්මාණය කරයි.
වෙනස ඇත්තේ එක් එක් සමඟ ප්රකාශයට පත් කරන ලද විචල්යයන්ගේ විෂය පථය තුළ ය.
ප්රායෝගිකව, විෂය පථයේ වෙනසෙහි ප්රයෝජනවත් ප්රතිවිපාක ගණනාවක් තිබේ:
letවිචල්යයන් දෘශ්ය වන්නේ ඒවායේ ආසන්නතම කොටු කොටසේ ( { ... }) පමණි.letවිචල්යයන් භාවිතා කළ හැක්කේ විචල්යය ප්රකාශයට පත් කිරීමෙන් පසුව සිදුවන කේත රේඛාවල පමණි ( ඒවා එසවූවත් !).letවිචල්යයන් පසුව varහෝ නැවත ප්රකාශයට පත් නොකෙරේ let.letගෝලීය windowවස්තුවට එකතු නොවේ .let විචල්යයන් වේ සමඟ භාවිතා කිරීම පහසුය (ඒවා ධාවන තත්වයන්ට හේතු නොවේ ).letවිචල්යයන්ගේ දෘශ්යතාව අඩු කිරීම සහ අනපේක්ෂිත නාම isions ට්ටන කලින් සොයා ගැනීමේ සම්භාවිතාව වැඩි කිරීම මගින් පනවා ඇති සීමාවන් . විචල්යයන් ඒවායේ ප්රතික්රියාශීලී බව (භාවිතයට නොගත් මතකය නැවත ලබා ගැනීමට උපකාරී වේ) ඇතුළුව ඒවා සොයා ගැනීමට සහ තර්ක කිරීමට මෙය පහසු කරයි .
එහි ප්රති, ලයක් වශයෙන්, let ලයක් ලෙස විචල්යයන් විශාල වැඩසටහන් වල භාවිතා කරන විට හෝ ස්වාධීනව සංවර්ධිත රාමු නව හා අනපේක්ෂිත ආකාරවලින් ඒකාබද්ධ කරන විට ගැටළු ඇතිවීමට ඇති ඉඩකඩ අඩුය.
varලූපයක (# 5) වසා දැමීමක් භාවිතා කරන විට හෝ ඔබේ කේතයේ (# 4) බාහිරව පෙනෙන ගෝලීය විචල්යයන් ප්රකාශ කිරීමේදී ඔබට තනි බන්ධන බලපෑමක් අවශ්ය යැයි ඔබට විශ්වාස නම් තවමත් ප්රයෝජනවත් විය හැකිය. භාවිතය සඳහාvarexportප්රවාහක අවකාශයෙන් හා මූලික භාෂාවට සංක්රමණය වුවහොත් අපනයන සඳහා ප්රතිස්ථාපනය කළ හැකිය .
1. ළඟම ඇති කොටු කොටුවෙන් පිටත කිසිදු භාවිතයක් නොමැත:
මෙම කේත වාරණය යොමු දෝෂයක් ඇති කරයි, මන්දයත් දෙවන භාවිතය xඑය ප්රකාශයට පත් කරන ලද බ්ලොක් එකෙන් පිටත සිදු වන බැවිනි let:
{
let x = 1;
}
console.log(`x is ${x}`); // ReferenceError during parsing: "x is not defined".
ඊට වෙනස්ව, එකම උදාහරණය සමඟ var කෘති .
2. ප්රකාශයට පෙර භාවිතයක් නොමැත:
කේතය ක්රියාත්මක කිරීමට ReferenceErrorපෙර මෙම කේතය අවහිර කරනු ඇත, මන්ද xඑය ප්රකාශයට පත් කිරීමට පෙර භාවිතා වේ:
{
x = x + 1; // ReferenceError during parsing: "x is not defined".
let x;
console.log(`x is ${x}`); // Never runs.
}
ඊට හාත්පසින්ම වෙනස්ව, varකිසිදු ව්යතිරේකයක් නොතකා විග්රහ කර ධාවනය වන එකම උදාහරණය .
3. නැවත ප්රකාශ කිරීමක් නොමැත:
පහත දැක්වෙන කේතය මඟින් ප්රකාශිත විචල්යයක් letපසුව නැවත ප්රකාශ කළ නොහැකි බව පෙන්නුම් කරයි :
let x = 1;
let x = 2; // SyntaxError: Identifier 'x' has already been declared
4. ග්ලෝබල් අමුණා නැත window:
var button = "I cause accidents because my name is too common.";
let link = "Though my name is common, I am harder to access from other JS files.";
console.log(link); // OK
console.log(window.link); // undefined (GOOD!)
console.log(window.button); // OK
5. වසා දැමීම් සමඟ පහසු භාවිතය:
ප්රකාශිත විචල්යයන් varලූප ඇතුළත වසා දැමීම් සමඟ හොඳින් ක්රියා නොකරයි. iකාලයාගේ ඇවෑමෙන් විචල්යයට ඇති අගයන්හි අනුක්රමය ප්රතිදානය කරන සරල පුඩුවක් මෙන්න :
for (let i = 0; i < 5; i++) {
console.log(`i is ${i}`), 125/*ms*/);
}
විශේෂයෙන්, මෙම ප්රතිදානයන්:
i is 0
i is 1
i is 2
i is 3
i is 4
ජාවාස්ක්රිප්ට් හි අපි බොහෝ විට විචල්යයන් නිර්මාණය කරන්නේ ඒවාට වඩා සැලකිය යුතු පසු කාලයකදී ය. වසා දැමීමක් සමඟ ප්රතිදානය ප්රමාද කිරීමෙන් අපි මෙය නිරූපණය කරන විට setTimeout:
for (let i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... අප රැඳී සිටින තාක් කල් ප්රතිදානය නොවෙනස්ව පවතී let. ඊට වෙනස්ව, අපි ඒ var iවෙනුවට භාවිතා කර ඇත්නම් :
for (var i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... ලූපය අනපේක්ෂිත ලෙස "i 5" ලෙස පස් වතාවක් ප්රතිදානය කරයි:
i is 5
i is 5
i is 5
i is 5
i is 5
varවෙනුවට භාවිතා කිරීමෙන් let, කේතය සමාන වේ: var i = 0; while (i < 5) { doSomethingLater(); i++; } iවසා දැමීමෙන් පිටත වන අතර, doSomethingLater()ක්රියාත්මක වන iකාලය වන විටත් , දැනටමත් 5 වතාවක් වැඩි කර ඇත, එබැවින් ප්රතිදානය i is 5පස් ගුණයකි. භාවිතා කිරීමෙන් let, විචල්යය iවසා දැමීම තුළ ඇත, එබැවින් සෑම අසින්ක් ඇමතුමකටම iනිර්මාණය කර ඇති 'ගෝලීය' භාවිතා කිරීම වෙනුවට තමන්ගේම පිටපතක් varලැබේ.
for. වඩාත් නිවැරදි පරිවර්තනයක්, වඩාත් සංකීර්ණ වුවත්, සම්භාව්ය for (var i = 0; i < 5; i++) { (function(j) { setTimeout(_ => console.log(i යනු $ {j is වන අතර එය ශ්රිතයේ නම සමඟ ), 125/*ms*/); })(i); }එක් එක් අගය සුරැකීම සඳහා “ශ්රිත-සක්රීය කිරීමේ වාර්තාවක්” හඳුන්වා දෙයි . ij
පහත දැක්වෙන කාර්යයන් දෙකෙහි වෙනස පෙන්වයි:
function varTest() {
var x = 31;
if (true) {
var x = 71; // Same variable!
console.log(x); // 71
}
console.log(x); // 71
}
function letTest() {
let x = 31;
if (true) {
let x = 71; // Different variable
console.log(x); // 71
}
console.log(x); // 31
}
let සිත්ගන්නා සුළුය, මන්ද එය අපට මෙවැනි දෙයක් කිරීමට ඉඩ සලසයි:
(() => {
var count = 0;
for (let i = 0; i < 2; ++i) {
for (let i = 0; i < 2; ++i) {
for (let i = 0; i < 2; ++i) {
console.log(count++);
}
}
}
})();
එහි ප්රති results ලය ගණනය කිරීම [0, 7].
ෙකෙසේෙවතත්
(() => {
var count = 0;
for (var i = 0; i < 2; ++i) {
for (var i = 0; i < 2; ++i) {
for (var i = 0; i < 2; ++i) {
console.log(count++);
}
}
}
})();
ගණන් කිරීම් පමණක් [0, 1].
අතර ප්රධාන වෙනස varහා letවිචල්යයන් සමග ප්රකාශ බව ය varඇත කාර්යය scoped . කාර්යයන් සමග ප්රකාශ බැවින්ද letඇත වාරණ scoped . උදාහරණයක් වශයෙන්:
function testVar () {
if(true) {
var foo = 'foo';
}
console.log(foo);
}
testVar();
// logs 'foo'
function testLet () {
if(true) {
let bar = 'bar';
}
console.log(bar);
}
testLet();
// reference error
// bar is scoped to the block of the if statement
සමඟ විචල්යයන් var:
පළමු ශ්රිතය testVarවිචල්ය foo ලෙස හැඳින්වූ විට ප්රකාශිතව ප්රකාශයට පත් කළ varහැකිය if. මෙම විචල්යය ශ්රිතයේ විෂය පථය තුළ සෑම තැනකමfoo ලබා ගත හැකිය .testVar
සමඟ විචල්යයන් let:
දෙවන ශ්රිතය testLetවිචල්ය තීරුව ලෙස හැඳින්වූ විට ප්රකාශයට පත් කළ letහැක්කේ ifප්රකාශය තුළ පමණි . විචල්ය ප්රකාශ නිසා letවේ වාරණ scoped (අ වාරණ සඟල වරහන් උදා අතර කේතය කොහෙද if{}, for{}, function{}).
let විචල්යයන් ඔසවන්නේ නැත:අතර තවත් වෙනසක් varහා letසමග ප්රකාශ සමග විචල්ය වේ let එසෙව්වා වෙන්න එපා . මෙම හැසිරීම නිදර්ශනය කිරීමට හොඳම ක්රමය උදාහරණයක්:
විචල්යයන් ඔසවා let නොගන්න :
console.log(letVar);
let letVar = 10;
// referenceError, the variable doesn't get hoisted
සමග විචල්ය var කරන්නද : හමුවීමක් එසෙව්වා
console.log(varVar);
var varVar = 10;
// logs undefined, the variable gets hoisted
letසම්බන්ධ නොවේ window:letගෝලීය විෂය පථය තුළ ප්රකාශිත විචල්යයක් (එය ශ්රිතයක නොමැති කේතය) ගෝලීය windowවස්තුවෙහි දේපලක් ලෙස එකතු නොවේ . උදාහරණයක් ලෙස (මෙම කේතය ගෝලීය විෂය පථයේ ඇත):
var bar = 5;
let foo = 10;
console.log(bar); // logs 5
console.log(foo); // logs 10
console.log(window.bar);
// logs 5, variable added to window object
console.log(window.foo);
// logs undefined, variable not added to window object
letනැවත භාවිතා කළ යුත්තේ කවදාදvar?
භාවිතා letපුරා varඔබට හැකි සෑම විටම එය හුදෙක් වඩාත් නිශ්චිත scoped නිසා. මෙය විචල්යයන් විශාල සංඛ්යාවක් සමඟ කටයුතු කිරීමේදී සිදුවිය හැකි විභව නම් කිරීමේ ගැටුම් අඩු කරයි. varඔබට ගෝලීය විචල්යයක් පැහැදිලිවම windowවස්තුව මත තිබිය යුතු විට භාවිතා කළ හැකිය (මෙය සැබවින්ම අවශ්ය නම් සෑම විටම ප්රවේශමෙන් සලකා බලන්න).
var ගෝලීය විෂය පථය (එසවිය හැකි) විචල්යයයි.
letහා constවාරණ විෂය පථය වේ.
test.js
{
let l = 'let';
const c = 'const';
var v = 'var';
v2 = 'var 2';
}
console.log(v, this.v);
console.log(v2, this.v2);
console.log(l); // ReferenceError: l is not defined
console.log(c); // ReferenceError: c is not defined
for (let i = 0; i < 5; i++) {
// i accessible ✔️
}
// i not accessible ❌
for (var i = 0; i < 5; i++) {
// i accessible ✔️
}
// i accessible ✔️
Around සෙල්ලම් කිරීමට වැලිපිල්ල
භාවිතා කරන විට let
මෙම letමූල පදය ගබඩාගාරයක ඕනෑම වාරණ (පොදුවේ හි විෂය පථය වෙත විචල්ය ප්රකාශ { .. }එහි අඩංගු වෙනවා. වෙනත් වචන වලින් යුගල), letනිසැකයෙන්ම එහි විචල්ය ප්රකාශ කිසිදු වාරණ ගේ විෂය පථය hijacks.
letwindowගෝලීයව ප්රවේශ විය නොහැකි නිසා විචල්යයන්ට වස්තුවට ප්රවේශ විය නොහැක.
function a(){
{ // this is the Max Scope for let variable
let x = 12;
}
console.log(x);
}
a(); // Uncaught ReferenceError: x is not defined
භාවිතා කරන විට var
var සහ ES5 හි විචල්යයන්ට ශ්රිතවල විෂය පථයන් ඇත, එයින් අදහස් වන්නේ විචල්යයන් ශ්රිතය තුළ වලංගු වන අතර එය ශ්රිතයට පිටතින් නොවේ.
varwindowගෝලීයව ප්රවේශ විය නොහැකි නිසා විචල්යයන්ට වස්තුව තුළට ප්රවේශ විය හැකිය.
function a(){ // this is the Max Scope for var variable
{
var x = 12;
}
console.log(x);
}
a(); // 12
ඔබට තවත් දැන ගැනීමට අවශ්ය නම් පහත කියවීම දිගටම කරගෙන යන්න
විෂය පථය පිළිබඳ වඩාත් ම ප්රසිද්ධ සම්මුඛ පරීක්ෂණ ප්රශ්න එක් ද පිළිබඳ නිශ්චිත භාවිතය ප්රමාණවත් හැකි letහාvar පහත පරිදි වේ;
භාවිතා කරන විට let
for (let i = 0; i < 10 ; i++) {
setTimeout(
function a() {
console.log(i); //print 0 to 9, that is literally AWW!!!
},
100 * i);
}
මෙයට හේතුව, භාවිතා කරන විට let, සෑම පුඩුවක්ම පුනරාවර්තනය සඳහා විචල්යය විෂය පථයට අයත් වන අතර එහි පිටපතක් ඇත.
භාවිතා කරන විට var
for (var i = 0; i < 10 ; i++) {
setTimeout(
function a() {
console.log(i); //print 10 times 10
},
100 * i);
}
මෙයට හේතුව, භාවිතා කරන විට var, සෑම පුඩුවක්ම පුනරාවර්තනය සඳහා විචල්යය විෂය පථය හා බෙදාගත් පිටපතකි.
මම පිරිවිතර නිවැරදිව කියවා බැලුවහොත්, පුද්ගලික පමණක් සාමාජිකයන් අනුකරණය කිරීම සඳහා භාවිතා කරන ස්වයං ආයාචනා ක්රියාකාරකම් වලක්වා ගැනීම සඳහා let ස්තූතිවන්ත විය හැකිය - කේත කියවීමේ හැකියාව අඩු කරන, නිදොස් කිරීම සංකීර්ණ කරන, සැබෑ කේත ආරක්ෂාවක් හෝ වෙනත් ප්රතිලාභයක් එක් නොකරන ජනප්රිය මෝස්තර රටාවක් - සමහර විට කෙනෙකුගේ තෘප්තිය හැර අර්ථ නිරූපණය සඳහා ඇති ආශාව, එබැවින් එය භාවිතා කිරීම නවත්වන්න. / රැන්ට්
var SomeConstructor;
{
let privateScope = {};
SomeConstructor = function SomeConstructor () {
this.someProperty = "foo";
privateScope.hiddenProperty = "bar";
}
SomeConstructor.prototype.showPublic = function () {
console.log(this.someProperty); // foo
}
SomeConstructor.prototype.showPrivate = function () {
console.log(privateScope.hiddenProperty); // bar
}
}
var myInstance = new SomeConstructor();
myInstance.showPublic();
myInstance.showPrivate();
console.log(privateScope.hiddenProperty); // error
'බලන්න පෞද්ගලික අතුරු මුහුණත් ආදර්ශනය '
letනොදෙන අතර එය කරන්නේ කෙසේද යන්න විස්තරාත්මකව විස්තර කළ හැකිද ? (මම හිතන්නේ ඔබ අදහස් කරන්නේ IIFE යන්න “ස්වයං ආයාචනා කිරීමේ ශ්රිතයක්” සමඟයි.)
hiddenPropertyඉදිකිරීම්කරු තුළ සිටින්නේ ඇයි? hiddenPropertyඔබගේ “පන්තියේ” සියලු අවස්ථාවන් සඳහා ඇත්තේ එකක් පමණි .
සමඟ සමහර හක්ක let:
1.
let statistics = [16, 170, 10];
let [age, height, grade] = statistics;
console.log(height)
2.
let x = 120,
y = 12;
[x, y] = [y, x];
console.log(`x: ${x} y: ${y}`);
3.
let node = {
type: "Identifier",
name: "foo"
};
let { type, name, value } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
console.log(value); // undefined
let node = {
type: "Identifier"
};
let { type: localType, name: localName = "bar" } = node;
console.log(localType); // "Identifier"
console.log(localName); // "bar"
let:let jar = {
numberOfCookies: 10,
get cookies() {
return this.numberOfCookies;
},
set cookies(value) {
this.numberOfCookies = value;
}
};
console.log(jar.cookies)
jar.cookies = 7;
console.log(jar.cookies)
let { type, name, value } = node;කුමක්ද? ඔබ ගුණාංග 3 කින් යුත් නව වස්තුවක් / නම / අගය නිර්මාණය කර ඒවා නෝඩ් වෙතින් ගුණාංග අගයන් සමඟ ආරම්භ කරනවාද?
varවේ.
let යනු es6 හි කොටසකි. මෙම කාර්යයන් පහසු ආකාරයකින් වෙනස පැහැදිලි කරයි.
function varTest() {
var x = 1;
if (true) {
var x = 2; // same variable!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // different variable
console.log(x); // 2
}
console.log(x); // 1
}
vs vs. ඒ සියල්ල විෂය පථය ගැන ය .
var විචල්යයන් ගෝලීය වන අතර මූලික වශයෙන් සෑම තැනකටම ප්රවේශ විය හැකි අතර විචල්යයන් ගෝලීය නොවන අතර ඒවා පවතින්නේ සංවෘත වරහන් මගින් ඒවා විනාශ වන තුරු පමණි.
පහත මගේ උදාහරණය බලන්න, සහ console.logs දෙකෙහි සිංහ (ඉඩ) විචල්යය වෙනස් ලෙස ක්රියා කරන ආකාරය සටහන් කරන්න; එය 2 වන console.log හි විෂය පථයෙන් බැහැර වේ.
var cat = "cat";
let dog = "dog";
var animals = () => {
var giraffe = "giraffe";
let lion = "lion";
console.log(cat); //will print 'cat'.
console.log(dog); //will print 'dog', because dog was declared outside this function (like var cat).
console.log(giraffe); //will print 'giraffe'.
console.log(lion); //will print 'lion', as lion is within scope.
}
console.log(giraffe); //will print 'giraffe', as giraffe is a global variable (var).
console.log(lion); //will print UNDEFINED, as lion is a 'let' variable and is now out of scope.
ES6 විසින් var ට විකල්පයක් ලෙස නව යතුරු පද දෙකක් ( let සහ const ) හඳුන්වා දෙන ලදි .
ඔබට බ්ලොක් මට්ටමේ පිරිහීමක් අවශ්ය වූ විට ඔබට var වෙනුවට let සහ const සමඟ යා හැකිය.
පහත වගුවේ var, let සහ const අතර වෙනස සාරාංශ කරයි
පහත දැක්වෙන්නේ විෂය පථය තුළ 'ඉඩ' සහ 'var' වෙනස් වන ආකාරයයි:
let gfoo = 123;
if (true) {
let gfoo = 456;
}
console.log(gfoo); // 123
var hfoo = 123;
if (true) {
var hfoo = 456;
}
console.log(hfoo); // 456
මෙම gfooවිසින් අර්ථ, letමුලින් වේ ගෝලීය විෂය පථය , අපි ප්රකාශ කරන විට gfooඇතුළත නැවත if clauseඑහි වෙනස් විෂය පථය හා නව වටිනාකමක් බව විෂය පථය තුල විචල්ය අනුයුක්ත කර ඇත විට එය බලපාන නීතියක් නොවේ ගෝලීය විෂය පථය.
ඇති ෙහයින්ද hfooවිසින් අර්ථ, varතුළ මුලින් වේ ගෝලීය විෂය පථය , නමුත් නැවත අපි ඇතුළත එය ප්රකාශ කරන විට if clause, එය ගෝලීය විෂය පථය hfoo, එය ප්රකාශ කිරීම සඳහා var නැවත භාවිතා කර ඇති නමුත් සලකයි. අප එහි වටිනාකම නැවත පවරන විට ගෝලීය විෂය පථය hfoo ද බලපා ඇති බව අපට පෙනේ. මූලික වෙනස මෙයයි.
ඉහත සඳහන් කළ පරිදි:
වෙනස වන්නේ විෂය පථයයි.
varළඟම ඇති scoped ඇත කාර්යය වාරණ හාletවෙත scoped ඇත ළඟම කවරෙ වාරණ උත්සවයකට වාරණ වඩා කුඩා විය හැකි. ඕනෑම කොටසකින් පිටත නම් දෙකම ගෝලීය වේ. උදාහරණයක් බලමු:
උදාහරණ 1:
මගේ උදාහරණ දෙකෙහිම මට ශ්රිතයක් myfuncඇත. myfuncවිචල්යයක් myvar10 ට සමාන වේ. මගේ පළමු උදාහරණයේ දී මම myvar10 ( myvar==10) ට සමාන දැයි පරීක්ෂා කරමි . ඔව් නම්, මම යතුරුපදය භාවිතා කරමින් විචල්යයක් ප්රකාශ කරමි myvar(දැන් මට මයිවාර් විචල්ය දෙකක් තිබේ) varඑය නව අගයක් (20) පවරයි. ඊළඟ පේළියේ මම එහි වටිනාකම මගේ කොන්සෝලය මත මුද්රණය කරමි. කොන්දේසි සහිත වාරණයෙන් පසුව මම නැවතත් myvarමගේ කොන්සෝලයෙහි අගය මුද්රණය කරමි. ඔබ ප්රතිදානය දෙස බැලුවහොත් myfunc, myvarඅගය 20 ට සමාන වේ.
උදාහරණ 2:
මගේ දෙවන උදාහරණයේ varදී මගේ කොන්දේසි සහිත කොටසෙහි මූල පදය භාවිතා කරනවා වෙනුවට මම ප්රකාශ myvarකරන්නේ letයතුරු පද භාවිතා කරන බවයි. දැන් මම අමතන විට මට myfunc වෙනස් ප්රතිදානයන් දෙකක් ලැබේ: myvar=20සහ myvar=10.
එබැවින් වෙනස ඉතා සරල ය, එනම් එහි විෂය පථය.
මට මේ වචන ක්රියාත්මක කිරීමේ සන්දර්භය හා සම්බන්ධ කිරීමට අවශ්යයි, මන්ද මේ සියල්ලෙහිම ක්රියාත්මක කිරීමේ සන්දර්භය වැදගත් වේ. ක්රියාත්මක කිරීමේ සන්දර්භය අදියර දෙකක් ඇත: නිර්මාණ අවධියක් සහ ක්රියාත්මක කිරීමේ අදියර. ඊට අමතරව, එක් එක් ක්රියාත්මක කිරීමේ සන්දර්භය තුළ විචල්ය පරිසරයක් සහ බාහිර පරිසරයක් (එහි ශබ්දකෝෂ පරිසරය) ඇත.
ක්රියාත්මක කිරීමේ සන්දර්භය නිර්මාණය කිරීමේ අවධියේදී, ලබා දී ඇති ක්රියාත්මක කිරීමේ සන්දර්භයෙහි විචල්ය පරිසරය තුළ නිර්වචනය නොකළ අගයක් සහිත var, let සහ const තවමත් එහි විචල්යය මතකයේ ගබඩා කරයි. වෙනස ක්රියාත්මක කිරීමේ අවධියේ ඇත. අගයක් ලබා දීමට පෙර ඔබ var සමඟ අර්ථ දක්වා ඇති විචල්යයක් භාවිතා කරන්නේ නම්, එය නිර්වචනය නොකෙරේ. ව්යතිරේකයක් මතු නොවේ.
කෙසේ වෙතත්, ප්රකාශිත විචල්යය ප්රකාශ කරන තෙක් ඉඩ නොතැබිය යුතුය. එය ප්රකාශයට පත් කිරීමට පෙර ඔබ එය භාවිතා කිරීමට උත්සාහ කරන්නේ නම්, ක්රියාත්මක කිරීමේ සන්දර්භය තුළ ක්රියාත්මක කිරීමේ අවධියේදී ව්යතිරේකයක් මතු වේ. දැන් විචල්යය තවමත් මතකයේ රැඳෙනු ඇත, ක්රියාත්මක කිරීමේ සන්දර්භය නිර්මාණය කිරීමේ අනුග්රහයෙනි, නමුත් එන්ජිම ඔබට එය භාවිතා කිරීමට ඉඩ නොදේ:
function a(){
b;
let b;
}
a();
> Uncaught ReferenceError: b is not defined
Var සමඟ අර්ථ දක්වා ඇති විචල්යයක් සමඟ, වත්මන් ක්රියාත්මක කිරීමේ සන්දර්භයෙහි විචල්ය පරිසරය තුළ එන්ජිමට විචල්යය සොයාගත නොහැකි නම්, එය විෂය පථය (පිටත පරිසරය) ඉහළට ගොස් විචල්යය සඳහා පිටත පරිසරයේ විචල්ය පරිසරය පරීක්ෂා කරයි. එය එහි සොයාගත නොහැකි නම්, එය විෂය පථය සෙවීම දිගටම කරගෙන යනු ඇත. ඉඩ දීම සහ සංවර්ධනය කිරීම මෙය නොවේ.
ඉඩ දීමේ දෙවන ලක්ෂණය නම් එය බ්ලොක් විෂය පථය හඳුන්වා දීමයි. බ්ලොක් නිර්වචනය කර ඇත්තේ වක්ර වරහන් මගිනි. නිදසුන් අතර ශ්රිත කොටස්, බ්ලොක් නම්, බ්ලොක් සඳහා යනාදිය ඇතුළත් වේ. ඔබ විචල්යයක් බ්ලොක් එකක ඉඩ දී ප්රකාශයට පත් කළ විට, විචල්යය ලබා ගත හැක්කේ බ්ලොක් ඇතුළත පමණි. ඇත්ත වශයෙන්ම, for for loop වැනි බ්ලොක් ධාවනය වන සෑම අවස්ථාවකම එය මතකයේ නව විචල්යයක් නිර්මාණය කරයි.
ES6 විචල්යයන් ප්රකාශ කිරීම සඳහා const keyword ද හඳුන්වා දෙයි. const ද අවහිර කර ඇත. Let සහ const අතර ඇති වෙනස නම් ආරම්භක විචල්යයක් භාවිතා කරමින් const විචල්යයන් ප්රකාශ කිරීම අවශ්ය වේ, නැතහොත් එය දෝෂයක් ජනනය කරනු ඇත.
අවසාන වශයෙන්, ක්රියාත්මක කිරීමේ සන්දර්භය වෙත පැමිණි විට, var සමඟ අර්ථ දක්වා ඇති විචල්යයන් 'මෙම' වස්තුවට අමුණා ඇත. ගෝලීය ක්රියාත්මක කිරීමේ සන්දර්භය තුළ, එය බ්රව්සර්වල කවුළු වස්තුව වනු ඇත. ඉඩ දීම හෝ සංවර්ධනය කිරීම සඳහා මෙය නොවේ.
මම හිතන්නේ නියමයන් සහ බොහෝ උදාහරණ තරමක් අධික ය, මට පෞද්ගලිකව වෙනස ඇති ප්රධාන ගැටළුව වන්නේ “බ්ලොක්” යනු කුමක්ද යන්න තේරුම් ගැනීමයි. යම් අවස්ථාවක දී මම තේරුම් ගත්තා, IFප්රකාශයක් හැර බ්ලොක් යනු ඕනෑම වක්ර වරහනක් වනු ඇත . {ශ්රිතයක හෝ ලූපයක ආරම්භක වරහන මඟින් නව බ්ලොක් එකක් අර්ථ දක්වනු letඇත, එය තුළ අර්ථ දක්වා ඇති කිසිවක් }එකම දේ (ශ්රිතය හෝ ලූපය) වසා දැමීමෙන් පසු ලබා ගත නොහැක . එය මනසේ තබාගෙන තේරුම් ගැනීම පහසු විය:
let msg = "Hello World";
function doWork() { // msg will be available since it was defined above this opening bracket!
let friends = 0;
console.log(msg);
// with VAR though:
for (var iCount2 = 0; iCount2 < 5; iCount2++) {} // iCount2 will be available after this closing bracket!
console.log(iCount2);
for (let iCount1 = 0; iCount1 < 5; iCount1++) {} // iCount1 will not be available behind this closing bracket, it will return undefined
console.log(iCount1);
} // friends will no be available after this closing bracket!
doWork();
console.log(friends);
දැන් මම සිතන්නේ ප්රකාශන සමූහයකට වඩා හොඳ විචල්යයන් පරික්ෂා කිරීම let:
function printnums()
{
// i is not accessible here
for(let i = 0; i <10; i+=)
{
console.log(i);
}
// i is not accessible here
// j is accessible here
for(var j = 0; j <10; j++)
{
console.log(j);
}
// j is accessible here
}
ජාවා, සී #, වැනි වෙනත් භාෂාවන් මෙන් ජාවාස්ක්රිප්ට් වලද ඒ හා සමාන විෂය පථයක් ඇති වන පරිදි මිනිසුන් මෙහි ඉඩදීම භාවිතා කිරීමට පටන් ගනී යැයි මම සිතමි.
ජාවාස්ක්රිප්ට් හි විෂය පථය පිළිබඳ පැහැදිලි අවබෝධයක් නොමැති පුද්ගලයින් කලින් වැරැද්ද කිරීමට පුරුදුව සිටියහ.
එසවීම සඳහා සහය නොදක්වයි let.
මෙම ප්රවේශයත් සමඟ ජාවාස්ක්රිප්ට් හි ඇති දෝෂ ඉවත් වෙමින් පවතී.
ගැඹුරෙහි ES6 වෙත යොමු වන්න : එය වඩා හොඳින් තේරුම් ගැනීමට ඉඩ දෙන්න .
මෙම ලිපිය මගින් var, let සහ const අතර වෙනස පැහැදිලිව අර්ථ දක්වයි
constයනු හඳුනාගැනුම නැවත ලබා නොදෙන බවට සං signal ාවකි.
let, යනු ලූපයක කවුන්ටරයක් හෝ ඇල්ගොරිතමයක අගය හුවමාරුව වැනි විචල්යය නැවත පැවරිය හැකි සං signal ාවකි. විචල්යය භාවිතා කරනු ලබන්නේ එය අර්ථ දක්වා ඇති කොටසෙහි පමණක් බව එය සං als ා කරයි, එය සැමවිටම අඩංගු වන ශ්රිතය නොවේ.
varදැන් ඔබ ජාවාස්ක්රිප්ට් හි විචල්යයක් නිර්වචනය කරන විට ඇති දුර්වලම සං signal ාවයි. විචල්යය නැවත පැවරීමට හෝ නොවීමට ඉඩ ඇති අතර විචල්යය සම්පූර්ණ ශ්රිතයක් සඳහා හෝ බ්ලොක් හෝ ලූපයක් සඳහා පමණක් භාවිතා කළ හැකිය.
https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b
letවන අතර එය 6 වන සංස්කරණ කෙටුම්පතට ඇතුළත් කර ඇති අතර බොහෝ දුරට අවසාන පිරිවිතරයට ඇතුළත් වේ.