“Let” සහ “var” භාවිතා කිරීම අතර ඇති වෙනස කුමක්ද?


4546

සම්මතයන් 6 හඳුන්වා ඇති letප්රකාශය .

එය "දේශීය" විචල්‍යයක් ලෙස විස්තර කර ඇති බව මා අසා ඇත, නමුත් එය varයතුරු පදයට වඩා වෙනස් ලෙස හැසිරෙන්නේ කෙසේදැයි මට තවමත් විශ්වාස නැත .

වෙනස්කම් මොනවාද? letනැවත භාවිතා කළ යුත්තේ කවදාද?var ?


105
ECMAScript යනු ප්‍රමිතිය letවන අතර එය 6 වන සංස්කරණ කෙටුම්පතට ඇතුළත් කර ඇති අතර බොහෝ දුරට අවසාන පිරිවිතරයට ඇතුළත් වේ.
රිචඩ් අයෝට්

5
බලන්න kangax.github.io/es5-compat-table/es6 ES6 දිනය සහාය න්යාසය කිරීමට දක්වා (කිරීමටද ඇතුළුව) දක්වයි. ෆයර්ෆොක්ස් ලියන අවස්ථාව වන විට, ක්‍රෝම් සහ අයිඊ 11 සියල්ලම එයට සහය දක්වයි (එෆ්එෆ් ක්‍රියාත්මක කිරීම තරමක් ප්‍රමිතියක් නොවන බව මා විශ්වාස කළත්).
නිකෝ බර්න්ස්

22
දීර් for කාලයක් තිස්සේ මා දැන සිටියේ නැත, ලූපයක වර්ස් එය ඔතා ඇති ශ්‍රිතයට පරික්ෂා කර ඇති බව. මට මතකයි මෙය පළමු වරට හදුනාගෙන එය ඉතා මෝඩ යැයි සිතුවෙමි. විවිධ හේතුන් මත මේ දෙක භාවිතා කළ හැකි ආකාරය සහ සමහර අවස්ථාවලදී ඔබට ඇත්ත වශයෙන්ම a සඳහා පුඩුවක් තුළ var භාවිතා කිරීමට අවශ්‍ය වන්නේ කෙසේ ද යන්නත්, එය වාරණයට නොගැලපෙන ආකාරයත් දැන සිටියද මට යම් බලයක් පෙනේ.
එරික් බිෂාඩ්

1
මෙය ඉතා හොඳ කියවීමකි wesbos.com/javascript-scoping
onmyway133

1
හොඳින් පැහැදිලි කළ පිළිතුර මෙහි stackoverflow.com/a/43994458/5043867
ජේන්

Answers:


6103

විෂය පථය නීතිගත කිරීම

ප්‍රධාන වෙනස වන්නේ විෂය පථය පාලනය කිරීමයි. විචල්ය මගින් ප්රකාශයට 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

23
ඔබට අවශ්‍ය විටෙක බ්ලොක් එකක් සෑදිය හැකි බව මතක තබා ගන්න. ශ්‍රිතය () {කේතය; {inBlock = 5; } කේතය; };
සාමාන්‍ය ජෝ

178
යම් ප්‍රකාශයක අවශ්‍ය නොවන විට මතකය නිදහස් කිරීම සඳහා පමණක් ප්‍රකාශ කිරීමට ඉඩ දීමේ අරමුණ තිබේද?
NoBugs

220
O නොබග්ස්, ඔව්, විචල්‍යයන් පවතින්නේ ඒවා අවශ්‍ය තැන පමණක් බව දිරිමත් කරනු ලැබේ.
බැට්මෑන්

67
letවාරණ ප්‍රකාශනය let (variable declaration) statementසම්මත නොවන අතර අනාගතයේදී ඉවත් කරනු ලැබේ, bugzilla.mozilla.org/show_bug.cgi?id=1023609 .
ගජස්

19
ඉතින්, var භාවිතා කිරීමෙන් කිසිදු ප්‍රයෝජනයක් ඇති අවස්ථාවක් ගැන මට සිතිය නොහැකිය. Var භාවිතා කිරීම වඩාත් සුදුසු තත්වයක් පිළිබඳව යමෙකුට උදාහරණයක් ලබා දිය හැකිද?
ලුයිස් සියෙරා

623

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>


54
එය ඇත්තෙන්ම සිසිල් ය. ලූප් බොඩි වර්‍ග තුළ අඩංගු වන අතර "අයි" වටා "වසා දැමීමක්" ඇති නොකිරීමට මම බලාපොරොත්තු වෙමි .ඔබගේ උදාහරණය වෙනත් ආකාරයකින් ඔප්පු වේ. මම සිතන්නේ එය සින්ටැක්ස් දෘෂ්ටි කෝණයෙන් තරමක් අවුල් සහගත නමුත් මෙම තත්වය එතරම් සුලභ බැවින් එය ඒ ආකාරයෙන් සහාය දැක්වීම අර්ථවත් කරයි. මෙය ගෙන ඒමට බොහෝ ස්තූතියි.
කැරොල් කොලෙන්ඩා

9
IE 11 සහය දක්වයි let, නමුත් එය සියලු බොත්තම් සඳහා "6" දැනුම් දෙයි. letහැසිරිය යුතු ආකාරය පවසන කිසියම් ප්‍රභවයක් ඔබට තිබේද ?
ජිම් හන්සිකර්

10
: ඔබගේ පිළිතුර වගේ නිවැරදි හැසිරීම developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
ජිම් Hunziker

11
ඇත්ත වශයෙන්ම මෙය ජාවාස්ක්‍රිප්ට් හි පොදු අනතුරක් වන අතර letඇත්තෙන්ම ප්‍රයෝජනවත් වන්නේ මන්දැයි මට දැන් පෙනේ . සිදුවීම් සවන්දෙන්නන් ලූපයක් ලෙස සැකසීමට තවදුරටත් iඑක් එක් පුනරාවර්තනයේදී දේශීයව පරික්ෂා කිරීම සඳහා ක්ෂණිකව ආයාචිත ශ්‍රිත ප්‍රකාශනයක් අවශ්‍ය නොවේ .
ඒඩ්‍රියන් මොයිසා

19
"ඉඩ" භාවිතා කිරීම මෙම ගැටළුව වළක්වයි. එබැවින් සෑම පුනරාවර්තනයක්ම පෞද්ගලික ස්වාධීන වාරණ විෂය පථයක් නිර්මාණය කරයි, නමුත් "i" විචල්‍යය තවමත් බ්ලොක් තුළ සිදුවන වෙනස්වීම් මගින් දූෂිත විය හැකිය. (අනුකාරක විචල්‍යය සාමාන්‍යයෙන් බ්ලොක් තුළ වෙනස් නොවන නමුත් බ්ලොක් තුළ ඇති අනෙකුත් ප්‍රකාශිත ඉඩ විචල්‍යයන් ද විය හැකිය. විය) සහ ඕනෑම උත්සවය වාරණ තුළ ප්රකාශ කලේ, සඳහන් කිරීමේ වෙනත් කාර්යයන් සඳහා "i" දූෂිත වටිනාකම වාරණ තුළ ඔවුන් නිසා ප්රකාශ කළ හැකි නෑ "මම" යන එකම යොමු ඒ නිසා එම පෞද්ගලික වාරණ විෂය පථය බෙදා ගන්න.
ගැරී

199

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පිටුව බලන්න .


(*) ජාවාස්ක්‍රිප්ට් විචල්‍යයන් ඔසවා ඇති බැවින් ඒවා ප්‍රකාශයට පත් කිරීමට පෙර ගෝලීයව හා ක්‍රියාකාරීව විෂය පථයන් ආරම්භ කර භාවිතා කළ හැකිය . මෙයින් අදහස් කරන්නේ ප්‍රකාශන සෑම විටම විෂය පථයට ඉහළින් ඇති බවයි.

(**) අවහිර කළ හැකි විචල්‍යයන් ඔසවා නැත


14
පිළිතුර v4 සම්බන්ධයෙන්: iශ්‍රිත කොටසෙහි සෑම තැනකම දන්නා කරුණකි! undefinedඔබ වටිනාකමක් ලබා දෙන තෙක් එය (එසවීම හේතුවෙන්) ආරම්භ වේ ! ps: letද ඔසවා ඇත (එහි බ්ලොක් අඩංගු මුදුනට), නමුත් ReferenceErrorපළමු පැවරුමට පෙර බ්ලොක් එකෙහි සඳහන් කළ විට එය ලබා දෙනු ඇත . (ps2: මම අර්ධ-අර්ධ-ගැති පුද්ගලයෙක්, නමුත් ඔබට සැබවින්ම අර්ධ සළකුණක් අවශ්‍ය නොවේ). එසේ පැවසුවහොත්, සහාය පිළිබඳ යථාර්ථය පරීක්ෂා කිරීම ගැන ස්තූතියි!
ගිතාර්ලාබ්

Ita ගිටාර්ලාබ්: මොසිල්ලා සංවර්ධක ජාලයට අනුව : "ECMAScript 2015 හි, බැඳීම් විචල්‍ය එසවීමකට යටත් නොවිය යුතුය, එයින් අදහස් වන්නේ ප්‍රකාශයන් වත්මන් ක්‍රියාත්මක කිරීමේ සන්දර්භයේ ඉහළට නොයන බවයි." - කෙසේ වෙතත්, මම මගේ පිළිතුරට වැඩි දියුණු කිරීම් කිහිපයක් සිදු කළ අතර එමඟින් letසහ අතර හැසිරීමේ වෙනස පැහැදිලි කළ යුතුය var!
ජෝන් ස්ලෙගර්ස්

1
ඔබගේ පිළිතුර බොහෝ දියුණු විය (මම හොඳින් පරීක්ෂා කර බැලුවෙමි). ඔබේ අදහස් දැක්වීමේදී ඔබ සඳහන් කළ එම සබැඳියම මෙසේ කියයි: "(ඉඩ දෙන්න) විචල්‍යය බ්ලොක් ආරම්භයේ සිට ආරම්භය සැකසෙන තෙක් " තාවකාලික මළ කලාපයක " පවතී." එයින් අදහස් වන්නේ 'අනන්‍යතාවය' ('යමක්' වෙත යොමු කිරීම සඳහා 'වෙන් කර ඇති' පෙළ-පෙළ) දැනටමත් අදාළ විෂය පථය තුළ වෙන් කර ඇති අතර එසේ නොවුවහොත් එය මූල / ධාරක / කවුළු විෂය පථයේ කොටසක් බවට පත්වනු ඇත. මට පෞද්ගලිකව, 'එසවීම' යන්නෙන් අදහස් කරන්නේ ප්‍රකාශිත 'හඳුනාගැනීම්' අදාළ විෂය පථයට වෙන් කිරීම / සම්බන්ධ කිරීම පමණි. ඔවුන්ගේ ආරම්භය / පැවරුම / වෙනස් කිරීමේ හැකියාව හැර!
ගිතාර්ලාබ්

සහ .. + 1. ඔබ සම්බන්ධ කළ කයිල් සිම්සන් ලිපිය විශිෂ්ට කියවීමකි, ඒ සඳහා ඔබට ස්තූතියි! "තාවකාලික මළ කලාපය" හෝ "TDZ" ගැන ද පැහැදිලි ය. මම MDN මත කියෙව්වා: මම එකතු කිරීමට කැමතියි සිත්ගන්නා දෙයක් letහා constලදී ඇත්ත වශයෙන්ම ඔබ ඔවුන්ගේ අමතර පහසුකම් අවශ්ය වන විට පමණක් භාවිතා කිරීම රෙකමදාරු කරනු ක්රියාත්මක / 'වැඩි වැඩ නිසා (කපා පමණක් const වැනි) මෙම අමතර අංග පරීක්ෂා නිසා, (සහ) (වත්මන්) එන්ජිම (ය) බලාත්මක කිරීම / පරීක්ෂා කිරීම / සත්‍යාපනය / සැකසීම සඳහා (සහ විෂය පථයේ අතිරේක විෂය පථ-නෝඩ්).
ගිතාර්ලාබ්

1
එම්ඩීඑන් පවසන පරිදි අයිඊ අර්ථ නිරූපණය නිවැරදිව අර්ථ නිරූපණය කරයි. එය කුමක්ද? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Katinka Hesselink

146

මෙන්න උදාහරණ කිහිපයක් සමඟ මූලික පදය පිළිබඳ පැහැදිලි කිරීමක්let .

letගොඩක් වැඩ කරනවා වගේ var. ප්රධාන වෙනස වන්නේ varවිචල්යයේ විෂය පථය සමස්ත කොටු කිරීමේ කාර්යයයි

විකිපීඩියාවේ මෙම වගුවේ දැක්වෙන්නේ ජාවාස්ක්‍රිප්ට් 1.7 සඳහා සහය දක්වන බ්‍රව්සර් මොනවාද යන්නයි.

එයට සහය දක්වන්නේ මොසිල්ලා සහ ක්‍රෝම් බ්‍රව්සර් පමණි. අයිඊ, සෆාරි සහ වෙනත් අය එසේ නොකරයි.


5
සම්බන්ධිත ලේඛනයේ ප්‍රධාන පා bit ය ලෙස පෙනෙන්නේ, "var මෙන් බොහෝ සෙයින් ක්‍රියා කිරීමට ඉඩ දෙන්න. ප්‍රධාන වෙනස වන්නේ var විචල්‍යයක විෂය පථය සමස්ත සංවෘත ශ්‍රිතයයි" යන්නයි.
මයිකල් බර්

50
IE එයට සහය නොදක්වන බව පැවසීම තාක්‍ෂණිකව නිවැරදි වුවත්, එය මොසිල්ලා පමණක් දිගුවක් යැයි පැවසීම වඩාත් නිවැරදිය.
olliej

55
@olliej, ඇත්ත වශයෙන්ම මොසිල්ලා ක්‍රීඩාවට වඩා ඉදිරියෙන් සිටී. Ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf හි
ටයිලර්

Yt ටයිලර් ක්‍රොම්ප්ටන් යනු වසර ගණනාවක් තිස්සේ වෙන් කර ඇති වචන සමූහයකි. මොසිල්ලා එකතු කළ විට එය තනිකරම මොසිල්ලා දිගුවක් විය. ඊඑස් 6 ඉඩ ප්‍රකාශ සඳහා හැසිරීම නිර්වචනය කළ යුතු නමුත් මොසිල්ලා සින්ටැක්ස් හඳුන්වා දීමෙන් පසුව එය සිදුවිය. මතක තබා ගන්න moz සතුව E4X ද ඇති අතර එය සම්පූර්ණයෙන්ම මිය ගොස් ඇති අතර moz පමණි.
olliej


112

පිළිගත් පිළිතුරට කරුණක් නොමැත:

{
  let a = 123;
};

console.log(a); // ReferenceError: a is not defined

19
පිළිගත් පිළිතුර එහි උදාහරණයේ මෙම කරුණ පැහැදිලි නොකරයි. පිළිගත් පිළිතුර එය පෙන්නුම් කළේ forලූප් ආරම්භකය තුළ පමණක් වන අතර , සීමාවන්හි යෙදීමේ විෂය පථය නාටකාකාර ලෙස පටු කරයි let. ඉහළට.
ජෝන් ඩේවිස්

37
@ stimpy77 එය පැහැදිලිවම සඳහන් කරන්නේ “ළඟම ඇති කොටු කොටසට ඉඩ දෙන්න” යනුවෙනි; ප්‍රකාශ වන සෑම ක්‍රමයක්ම ඇතුළත් කළ යුතුද?
ඩේව් නිව්ටන්

6
උදාහරණ රාශියක් ඇති අතර ඔවුන්ගෙන් කිසිවෙකු කාරණය නිසි ලෙස නිරූපණය කර නැත .. මම පිළිගත් පිළිතුර සහ මෙය යන දෙකම ඉහළට ඔසවා තැබුවා විය හැකිද?
ජෝන් ඩේවිස්

5
මෙම දායකත්වය පෙන්නුම් කරන්නේ “බ්ලොක්” යනු වරහන් තුළ කොටා ඇති රේඛා සමූහයක් විය හැකි බවයි; එනම් එය කිසිදු ආකාරයක පාලන ප්‍රවාහයක්, ලූපයක් සමඟ සම්බන්ධ වීමට අවශ්‍ය නොවේ
වෙබෙලෝ

81

let

විෂය පථය අවහිර කරන්න

letමූල පදය භාවිතයෙන් ප්‍රකාශයට පත් කරන ලද විචල්‍යයන් බ්ලොක්-ස්කෝප් කර ඇති අතර එයින් අදහස් කරන්නේ ඒවා ලබා ගත හැක්කේ ඒවා ප්‍රකාශයට පත් කළ කොටසෙහි පමණක් බවයි.

ඉහළ මට්ටමේ (ශ්‍රිතයකට පිටතින්)

ඉහළ මට්ටමේ දී, විචල්‍යයන් භාවිතා කරමින් ප්‍රකාශිත 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

const

constඑය 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

51

මේ දෙක අතර වෙනස සඳහා උදාහරණයක් මෙන්න (ක්‍රෝම් සඳහා සහය දැන් ආරම්භ කර ඇත):
රූප විස්තරය මෙහි ඇතුළත් කරන්න

ඔබට පෙනෙන පරිදි 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);


2
මම මෙහි බලන්නේ කුමන මෙවලමද?
බාටන්

20
Chrome devtools
vlio20

කුරුඳු සඳහා ඩෙස්ක්ටොප් ඇප්ලෙට් සංවර්ධකයෙකු ලෙස, මම එවැනි දිදුලන මෙවලම් වලට නිරාවරණය වී නොමැත.
බාර්ටන්

48

සමහර සියුම් වෙනස්කම් තිබේ - letවිචල්‍ය විෂය පථය වෙනත් ඕනෑම භාෂාවකින් වැඩි වශයෙන් හෝ අඩු ලෙස හැසිරේ.

උදා: එය කොටු කොටසට විහිදේ, ඒවා ප්‍රකාශයට පත් කිරීමට පෙර ඒවා නොපවතී.

කෙසේ වෙතත් එය letනව ජාවාස්ක්‍රිප්ට් ක්‍රියාවට නැංවීමේ කොටසක් පමණක් වන අතර විවිධ මට්ටමේ බ්‍රව්සර් සහාය ඇත.


11
ECMAScript ප්‍රමිතිය letවන අතර එය 6 වන සංස්කරණ කෙටුම්පතට ඇතුළත් කර ඇති අතර එය බොහෝ විට අවසාන පිරිවිතරයට ඇතුළත් වනු ඇත.
රිචඩ් අයොට්

23
අවුරුදු 3 ක වෙනස එයයි: D
olliej

4
මෙම ප්‍රශ්නයට බාධා පමුණුවන අතර 2012 දී මොසිල්ලා බ්‍රව්සර් පමණක් සහාය දක්වයි let. සෆාරි, අයිඊ සහ චෝම් සියල්ලම එසේ නොවේ.
ව්‍යාජ සැවොල්

2
අහම්බෙන් අර්ධ වශයෙන් වාරණ විෂය පථයක් නිර්මාණය කිරීමේ අදහස හොඳ කරුණකි, පරෙස්සම් වන්න, letඑසවීම නොකරයි, letඔබේ බ්ලොක් එකේ ඉහළින් අර්ථ දක්වා ඇති විචල්‍යයක් භාවිතා කිරීම . ඔබට ifකේත පේළි කිහිපයකට වඩා වැඩි ප්‍රකාශයක් තිබේ නම්, එය අර්ථ දක්වා ඇති තෙක් ඔබට එම විචල්‍යය භාවිතා කළ නොහැකි බව ඔබට අමතක විය හැකිය. විශාල පොයින්ට් !!!
එරික් බිෂාඩ්

2
@EricB: ඔව් සහ නැත: "දී සම්මතයන් 2015, let එස ඇත තුළ විචල්ය ප්රකාශ ප්රතිඵල පෙර වාරණ දී විචල්ය පිලිබඳව සඳහන්, වාරණ මුදුනට විචල්ය කෙසේ වෙතත්. ReferenceError (මගේ සටහන: ඒ වෙනුවට හොඳ පැරණි undefined). මෙම ප්‍රකාශය සැකසෙන තෙක් විචල්‍යය වාරණයේ ආරම්භයේ සිට තාවකාලික මළ කලාපයක පවතී. “ස්විච් ප්‍රකාශ සඳහා එකම යටි තට්ටුවක් ඇති බැවින්” යන්න සමාන වේ. මූලාශ්රය: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
GitaarLAB

29

ප්රධාන වෙනස වන්නේ විෂය පථය අතර, වෙනස කිරීමටද ඇතුළත පමණක් ලබා ගත හැකි විය හැකි විෂය පථය පුඩුවක් සඳහා, මෙන්, එය ප්රකාශ කරනවා 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 වෙත සම්ප්‍රේෂණය කිරීම වඩා හොඳය ... බාබල් වෙබ් අඩවියට පිවිසීම පිළිබඳ වැඩි විස්තර සඳහා


24
  • විචල්ය එසවීම නොවේ

    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අ) ආරම්භක ප්‍රකාශනය ආ) එක් එක් පුනරාවර්තනය (වර්ධක ප්‍රකාශනය ඇගයීමට පෙර) සඳහා නව ශබ්දකෝෂ පරිසරයක් නිර්මාණය කිරීම නිසා , වැඩි විස්තර මෙහි ඇත.


4
:-) එය ප්රකාශයට පත් කරන තෙක් ප්රවේශ වීම නොවන හඳුනාගැනීමේ සඳහා ඉතා නාට්යමය නම - ඔවුන් ගමන් ගනිද්දී, නමුත් වටේ සංචාරවල යෙදෙමින් නිසා (බෙර රෝල්) ලෞකික මළ කලාපයේ එසෙව්වා නොවේ නම් ලෙස යිප්
Drenai

ඉතින් ඔසවන්න, නමුත් ලබාගත නොහැකිද? එය 'ඔසවා නැත' යන්නට වඩා වෙනස් වන්නේ කෙසේද?
එන්-කෑවා

මේ සඳහා පිළිතුරු දීමට බ්‍රයන් හෝ බර්ගි නැවත පැමිණෙනු ඇතැයි අපේක්ෂා කරමු. ඉඩ ප්‍රස්ථාව ඔසවා තැබීම මිස පැවරුම නොවේද? ස්තූතියි!
එන්-කෑවා

1
@ එන්-කෑවා, මෙන්න බර්ජි හි එක් පෝස්ට් එකක් , සමහර විට ඔබට එයට පිළිතුර සොයාගත හැකිය.
zangw

එය සිත්ගන්නා සුළුය, එය ඉඩ දෙන විට එසවීම ලෙසද හැඳින්වේ. තාක්‍ෂණිකව විග්‍රහ කිරීමේ එන්ජිම එය පූර්ව ග්‍රහණය කර ගන්නා බව මට වැටහී ඇත, නමුත් සියලු අභිප්‍රායන් සහ අරමුණු සඳහා ක්‍රමලේඛකයෙකු එය නොපවතින ලෙස සැලකිය යුතුය. අනෙක් අතට var එසවීම ක්‍රමලේඛකයෙකුට ඇඟවුම් කරයි.
එන්-කෑවා

19

අනෙක් අය දැනටමත් ලියා ඇති දේ එකතු කිරීමට උදාහරණයක් මෙන්න. ඔබට ශ්‍රිත පෙළක් සෑදීමට අවශ්‍ය යැයි සිතමු 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හැසිරීම නිරූපණය කිරීමට අදහස් කරන අතර ක්‍රියාකාරී වසා දැමීම් ද තේරුම් ගැනීමට පහසු වේ. අංක එකතු කිරීමට මෙය භයානක ක්‍රමයක් වනු ඇත. නමුත් නිර්නාමික ශ්‍රිත වැසීම් වලදී දත්ත ග්‍රහණය කර ගැනීමේ සාමාන්‍ය තාක්ෂණය වෙනත් ලෝකයේ සැබෑ ලෝකයේ දක්නට ලැබේ. වයි.එම්.එම්.වී.


2
@aborz: දෙවන උදාහරණයේ ඉතා සිසිල් නිර්නාමික ශ්‍රිත සින්ටැක්ස්. එය මම සී # හි පුරුදු වී ඇති දෙයයි. මම අද යමක් ඉගෙන ගත්තා.
බාටන්

නිවැරදි: තාක්ෂණික වශයෙන්, වෙරළාරක්ෂක කාර්යය කාරක රීති මෙතන => විස්තර developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
බාට්න්

3
ඇත්තටම, ඔබට අවශ්‍ය නැහැ let value = i; . මෙම forප්රකාශය lexical පරාසය වාරණ නිර්මාණය කරයි.
දත් බුරුසුව

18

වෙනස ඇත්තේ එක් එක් සමඟ ප්රකාශයට පත් කරන ලද විචල්යයන්ගේ විෂය පථය තුළ ය.

ප්රායෝගිකව, විෂය පථයේ වෙනසෙහි ප්රයෝජනවත් ප්රතිවිපාක ගණනාවක් තිබේ:

  1. letවිචල්‍යයන් දෘශ්‍ය වන්නේ ඒවායේ ආසන්නතම කොටු කොටසේ ( { ... }) පමණි.
  2. letවිචල්යයන් භාවිතා කළ හැක්කේ විචල්‍යය ප්රකාශයට පත් කිරීමෙන් පසුව සිදුවන කේත රේඛාවල පමණි ( ඒවා එසවූවත් !).
  3. letවිචල්යයන් පසුව varහෝ නැවත ප්රකාශයට පත් නොකෙරේ let.
  4. ගෝලීය වස්තූන් letගෝලීය windowවස්තුවට එකතු නොවේ .
  5. 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

5
# 5 ධාවන තත්වයක් නිසා නොවේ. ඒ varවෙනුවට භාවිතා කිරීමෙන් let, කේතය සමාන වේ: var i = 0; while (i < 5) { doSomethingLater(); i++; } iවසා දැමීමෙන් පිටත වන අතර, doSomethingLater()ක්‍රියාත්මක වන iකාලය වන විටත් , දැනටමත් 5 වතාවක් වැඩි කර ඇත, එබැවින් ප්‍රතිදානය i is 5පස් ගුණයකි. භාවිතා කිරීමෙන් let, විචල්‍යය iවසා දැමීම තුළ ඇත, එබැවින් සෑම අසින්ක් ඇමතුමකටම iනිර්මාණය කර ඇති 'ගෝලීය' භාවිතා කිරීම වෙනුවට තමන්ගේම පිටපතක් varලැබේ.
ඩැනියෙල් ටී.

An ඩැනියෙල්ට්: ලූප ආරම්භකය වෙතින් විචල්‍ය අර්ථ දැක්වීම එසවීමේ පරිවර්තනය කිසිවක් පැහැදිලි නොකරයි. එය හුදෙක් අර්ථකථනයේ සාමාන්‍ය අර්ථ දැක්වීමයි for. වඩාත් නිවැරදි පරිවර්තනයක්, වඩාත් සංකීර්ණ වුවත්, සම්භාව්‍ය for (var i = 0; i < 5; i++) { (function(j) { setTimeout(_ => console.log(i යනු $ {j is වන අතර එය ශ්‍රිතයේ නම සමඟ ), 125/*ms*/); })(i); }එක් එක් අගය සුරැකීම සඳහා “ශ්‍රිත-සක්‍රීය කිරීමේ වාර්තාවක්” හඳුන්වා දෙයි . ij
mormegil

14

පහත දැක්වෙන කාර්යයන් දෙකෙහි වෙනස පෙන්වයි:

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
}

13

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].


2
විචල්ය සෙවනැල්ල සුදුසු යැයි කිසිවෙකු ක්‍රියා කරන පළමු අවස්ථාව මෙයයි. නැත, ඉඩ දීමේ අරමුණ සෙවනැලි සක්‍රීය කිරීම නොවේ
ජෝන් හෝග්ලන්ඩ්

1
අරමුණ? එය ඉදිකිරීමක්, ඔබට කැමති ආකාරයට එය භාවිතා කළ හැකිය, සිත්ගන්නා ක්‍රමයක් වන්නේ මේ වගේ ය.
දිමිත්‍රි

13

VS වාරණ විෂය පථය:

අතර ප්රධාන වෙනස 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වස්තුව මත තිබිය යුතු විට භාවිතා කළ හැකිය (මෙය සැබවින්ම අවශ්‍ය නම් සෑම විටම ප්‍රවේශමෙන් සලකා බලන්න).


9

අවම වශයෙන් විෂුවල් ස්ටුඩියෝ 2015 හි ටයිප්ස්ක්‍රිප්ට් 1.5 හි “var” එකම විචල්‍ය නාමයක් වාරණයක දී ප්‍රකාශ කිරීමට ඉඩ දෙන අතර “ඉඩ” නොදෙන බව ද පෙනේ.

මෙය සම්පාදක දෝෂයක් ජනනය නොකරයි:

var x = 1;
var x = 2;

මෙය:

let x = 1;
let x = 2;

9

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


9

බොහෝ මූලික වචන වලින්,

for (let i = 0; i < 5; i++) {
  // i accessible ✔️
}
// i not accessible ❌

for (var i = 0; i < 5; i++) {
  // i accessible ✔️
}
// i accessible ✔️

Around සෙල්ලම් කිරීමට වැලිපිල්ල

සංස්කරණය කරමු vs vs


8

භාවිතා කරන විට 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, සෑම පුඩුවක්ම පුනරාවර්තනය සඳහා විචල්‍යය විෂය පථය හා බෙදාගත් පිටපතකි.


7

මම පිරිවිතර නිවැරදිව කියවා බැලුවහොත්, පුද්ගලික පමණක් සාමාජිකයන් අනුකරණය කිරීම සඳහා භාවිතා කරන ස්වයං ආයාචනා ක්‍රියාකාරකම් වලක්වා ගැනීම සඳහා 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ඔබගේ “පන්තියේ” සියලු අවස්ථාවන් සඳහා ඇත්තේ එකක් පමණි .
රොබට් සීමර්

4

සමඟ සමහර හක්ක 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 කින් යුත් නව වස්තුවක් / නම / අගය නිර්මාණය කර ඒවා නෝඩ් වෙතින් ගුණාංග අගයන් සමඟ ආරම්භ කරනවාද?
ඇලයින්ඉබ්

උදාහරණයක් ලෙස 3 ඔබ ව්‍යතිරේකය ඇති කරන නෝඩ් නැවත ප්‍රකාශ කරයි. මෙම සියලු උදාහරණ ද හොඳින් ක්‍රියාත්මක varවේ.
රෙහාන් හයිඩර්

4

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
}

4

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.

4

ES6 විසින් var ට විකල්පයක් ලෙස නව යතුරු පද දෙකක් ( let සහ const ) හඳුන්වා දෙන ලදි .

ඔබට බ්ලොක් මට්ටමේ පිරිහීමක් අවශ්‍ය වූ විට ඔබට var වෙනුවට let සහ const සමඟ යා හැකිය.

පහත වගුවේ var, let සහ const අතර වෙනස සාරාංශ කරයි

රූප විස්තරය මෙහි ඇතුළත් කරන්න


3

පහත දැක්වෙන්නේ විෂය පථය තුළ 'ඉඩ' සහ '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 ද බලපා ඇති බව අපට පෙනේ. මූලික වෙනස මෙයයි.


2

ඉහත සඳහන් කළ පරිදි:

වෙනස වන්නේ විෂය පථයයි. 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.

එබැවින් වෙනස ඉතා සරල ය, එනම් එහි විෂය පථය.


3
කරුණාකර කේතයේ පින්තූර පළ නොකරන්න, එය SO හි නරක පුරුද්දක් ලෙස සලකනු ලබන බැවින් එය අනාගත පරිශීලකයින් සඳහා සෙවිය නොහැකි වනු ඇත (මෙන්ම ප්‍රවේශ්‍යතා අවශ්‍යතා). එසේම, මෙම පිළිතුර වෙනත් පිළිතුරු දැනටමත් ආමන්ත්‍රණය කර නැති කිසිවක් එකතු නොකරයි.
inostia

2

මට මේ වචන ක්‍රියාත්මක කිරීමේ සන්දර්භය හා සම්බන්ධ කිරීමට අවශ්‍යයි, මන්ද මේ සියල්ලෙහිම ක්‍රියාත්මක කිරීමේ සන්දර්භය වැදගත් වේ. ක්‍රියාත්මක කිරීමේ සන්දර්භය අදියර දෙකක් ඇත: නිර්මාණ අවධියක් සහ ක්‍රියාත්මක කිරීමේ අදියර. ඊට අමතරව, එක් එක් ක්‍රියාත්මක කිරීමේ සන්දර්භය තුළ විචල්‍ය පරිසරයක් සහ බාහිර පරිසරයක් (එහි ශබ්දකෝෂ පරිසරය) ඇත.

ක්‍රියාත්මක කිරීමේ සන්දර්භය නිර්මාණය කිරීමේ අවධියේදී, ලබා දී ඇති ක්‍රියාත්මක කිරීමේ සන්දර්භයෙහි විචල්‍ය පරිසරය තුළ නිර්වචනය නොකළ අගයක් සහිත 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 සමඟ අර්ථ දක්වා ඇති විචල්‍යයන් 'මෙම' වස්තුවට අමුණා ඇත. ගෝලීය ක්‍රියාත්මක කිරීමේ සන්දර්භය තුළ, එය බ්‍රව්සර්වල කවුළු වස්තුව වනු ඇත. ඉඩ දීම හෝ සංවර්‍ධනය කිරීම සඳහා මෙය නොවේ.


2

මම හිතන්නේ නියමයන් සහ බොහෝ උදාහරණ තරමක් අධික ය, මට පෞද්ගලිකව වෙනස ඇති ප්‍රධාන ගැටළුව වන්නේ “බ්ලොක්” යනු කුමක්ද යන්න තේරුම් ගැනීමයි. යම් අවස්ථාවක දී මම තේරුම් ගත්තා, 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);


1

දැන් මම සිතන්නේ ප්‍රකාශන සමූහයකට වඩා හොඳ විචල්‍යයන් පරික්ෂා කිරීම 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 වෙත යොමු වන්න : එය වඩා හොඳින් තේරුම් ගැනීමට ඉඩ දෙන්න .


ඒ පිළිබඳ ගැඹුරින් අවබෝධ කර ගැනීම සඳහා සබැඳිය බලන්න - davidwalsh.name/for-and-against-let
swaraj patil

1

මෙම ලිපිය මගින් var, let සහ const අතර වෙනස පැහැදිලිව අර්ථ දක්වයි

const යනු හඳුනාගැනුම නැවත ලබා නොදෙන බවට සං signal ාවකි.

let, යනු ලූපයක කවුන්ටරයක් ​​හෝ ඇල්ගොරිතමයක අගය හුවමාරුව වැනි විචල්‍යය නැවත පැවරිය හැකි සං signal ාවකි. විචල්‍යය භාවිතා කරනු ලබන්නේ එය අර්ථ දක්වා ඇති කොටසෙහි පමණක් බව එය සං als ා කරයි, එය සැමවිටම අඩංගු වන ශ්‍රිතය නොවේ.

varදැන් ඔබ ජාවාස්ක්‍රිප්ට් හි විචල්‍යයක් නිර්වචනය කරන විට ඇති දුර්වලම සං signal ාවයි. විචල්‍යය නැවත පැවරීමට හෝ නොවීමට ඉඩ ඇති අතර විචල්‍යය සම්පූර්ණ ශ්‍රිතයක් සඳහා හෝ බ්ලොක් හෝ ලූපයක් සඳහා පමණක් භාවිතා කළ හැකිය.

https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.