Soru JavaScript'te bir değişken bildirmek için “let” ve “var” kullanımı arasındaki fark nedir?


ECMAScript 6 tanıtıldı let Beyan. Bunu "yerel" bir değişken olarak tanımladı duydum, ama hala nasıl farklı davrandığından emin değilim var Anahtar kelime.

Farklılıklar nedir? Ne zaman let bitmek var?


3259
2018-04-17 20:09


Menşei


ECMAScript standarttır ve let içinde yer almaktadır 6. baskı taslağı ve büyük olasılıkla son şartnamede olacak. - Richard Ayotte
Görmek kangax.github.io/es5-compat-table/es6 ES6 özelliklerinin güncel bir destek matrisi için (izin verilenler dahil). Firefox, Chrome ve IE11'in yazımı sırasında bunların hepsi destekliyor (FF'nin uygulamasının oldukça standart olmadığını düşünüyorum). - Nico Burns
En uzun süre için, for döngüsündeki varyasyonların, sarılmış olduğu işleve kadar uzandığını bilmiyordum. Bunu ilk kez anladığımı hatırlıyorum ve çok aptalca olduğunu düşündüm. Şimdi iktidarı görüyorum, ancak ikisinin farklı nedenlerle nasıl kullanılabileceğini ve bazı durumlarda aslında bir for döngüsünde bir varyantı nasıl kullanabileceğinizi ve bloğa kadar genişlemediğini biliyorum. - Eric Bishard
ES6 özellik desteği geliştikçe, ES6'nın benimsenmesi ile ilgili soru, özellik desteğinden performans farklılıklarına odaklanır. Gibi, ES6 ve ES5 arasında karşılaştırma performans farkları bulduğum bir site. Motorların ES6 kodu için optimize ettiği zamanlar muhtemelen değişeceğini unutmayın. - timolawl
Bu çok iyi bir okuma wesbos.com/javascript-scoping - onmyway133


Cevaplar:


Fark kapsamdır. var en yakın fonksiyon bloğu ve let en yakın parça Bir fonksiyon bloğundan daha küçük olan blok. Her ikisi de herhangi bir blok dışındaysa küreseldir.

Ayrıca, bildirilen değişkenler let kapalı bloklarında beyan edilmeden önce erişilebilir değildir. Demoda görüldüğü gibi, bu bir ReferenceError istisnasını atar.

gösteri: 

var html = '';

write('#### global ####\n');
write('globalVar: ' + globalVar); //undefined, but visible

try {
  write('globalLet: ' + globalLet); //undefined, *not* visible
} catch (exception) {
  write('globalLet: exception');
}

write('\nset variables');

var globalVar = 'globalVar';
let globalLet = 'globalLet';

write('\nglobalVar: ' + globalVar);
write('globalLet: ' + globalLet);

function functionScoped() {
  write('\n#### function ####');
  write('\nfunctionVar: ' + functionVar); //undefined, but visible

  try {
    write('functionLet: ' + functionLet); //undefined, *not* visible
  } catch (exception) {
    write('functionLet: exception');
  }

  write('\nset variables');

  var functionVar = 'functionVar';
  let functionLet = 'functionLet';

  write('\nfunctionVar: ' + functionVar);
  write('functionLet: ' + functionLet);
}

function blockScoped() {
  write('\n#### block ####');
  write('\nblockVar: ' + blockVar); //undefined, but visible

  try {
    write('blockLet: ' + blockLet); //undefined, *not* visible
  } catch (exception) {
    write('blockLet: exception');
  }

  for (var blockVar = 'blockVar', blockIndex = 0; blockIndex < 1; blockIndex++) {
    write('\nblockVar: ' + blockVar); // visible here and whole function
  };

  for (let blockLet = 'blockLet', letIndex = 0; letIndex < 1; letIndex++) {
    write('blockLet: ' + blockLet); // visible only here
  };

  write('\nblockVar: ' + blockVar);

  try {
    write('blockLet: ' + blockLet); //undefined, *not* visible
  } catch (exception) {
    write('blockLet: exception');
  }
}

function write(line) {
  html += (line ? line : '') + '<br />';
}

functionScoped();
blockScoped();

document.getElementById('results').innerHTML = html;
<pre id="results"></pre>

global:

Bir fonksiyon bloğu dışında bunun gibi kullanıldığında çok benzerler.

let me = 'go';  // globally scoped
var i = 'able'; // globally scoped

Bununla birlikte, global değişkenler let global olarak özellik olarak eklenmeyecek window ile tanımlananlar gibi nesne var.

console.log(window.me); // undefined
console.log(window.i); // 'able'

İşlev:

Bir fonksiyon bloğunda böyle kullanıldığında aynıdırlar.

function ingWithinEstablishedParameters() {
    let terOfRecommendation = 'awesome worker!'; //function block scoped
    var sityCheerleading = 'go!'; //function block scoped
}

Blok:

İşte fark. let sadece görünür for() döngü ve var tüm işlev için görünür.

function allyIlliterate() {
    //tuce is *not* visible out here

    for( let tuce = 0; tuce < 5; tuce++ ) {
        //tuce is only visible in here (and in the for() parentheses)
        //and there is a separate tuce variable for each iteration of the loop
    }

    //tuce is *not* visible out here
}

function byE40() {
    //nish *is* visible out here

    for( var nish = 0; nish < 5; nish++ ) {
        //nish is visible to the whole function
    }

    //nish *is* visible out here
}

yeniden bildirilmiş:

Katı modu varsayarsak, var Aynı değişkeni aynı kapsamda yeniden ilan edersiniz. Diğer yandan, let olmaz:

'use strict';
let me = 'foo';
let me = 'bar'; // SyntaxError: Identifier 'me' has already been declared
'use strict';
var me = 'foo';
var me = 'bar'; // No problem, `me` is replaced.

4571
2018-05-27 10:16



Yani ifadelerin sadece belirli bir blokta gerekmediğinde hafızayı boşaltmasına izin vermenin amacı nedir? - NoBugs
@NoBugs, Evet ve değişkenlerin sadece ihtiyaç duyulduğu yerlerde var olduğu konusunda teşvik edilir. - batman
let blok ifadesi let (variable declaration) statement standart dışı ve gelecekte kaldırılacak bugzilla.mozilla.org/show_bug.cgi?id=1023609. - Gajus
Global kapsamdaki farklar: let global değişkene özellik eklemeyin 2ality.com/2015/02/es6-scoping.html#the_global_object - Yukulélé
@ThinkingStiff: Lütfen gözden geçirin bu meta gönderive ortaya çıkan teknik meselelerde tartışın. - Robert Harvey♦


let kapaklarla ilgili problemlerden kaçınmak için de kullanılabilir. Aşağıdaki örneklerde gösterildiği gibi eski bir referans tutmak yerine taze değeri bağlar.

DEMO

for(var i = 1; i < 6; i++) {
  document.getElementById('my-element' + i)
    .addEventListener('click', function() { alert(i) })
}

Yukarıdaki kod, klasik bir JavaScript kapatma sorununu göstermektedir. Referans i değişken, gerçek değerden ziyade tıklama işleyicisinin kapanmasında depolanır. i.

Her bir tıklama işleyicisi aynı nesneyi referans gösterecektir, çünkü her bir tıklamada altıya sahip olmanız için 6'yı tutan tek bir sayaç nesnesi vardır.

Genel çözüm, bunu anonim bir işlevle sarmak ve i argüman olarak. Bu gibi konular şimdi de kullanılabilir. let yerine var Aşağıdaki kodda gösterildiği gibi.

DEMO (Chrome ve Firefox 50'de test edilmiştir)

'use strict';

for(let i = 1; i < 6; i++) {
  document.getElementById('my-element' + i)
    .addEventListener('click', function() { alert(i) })
}

451
2018-04-17 20:11



Bu aslında harika. Döngü gövdesinin köşeli parantez içinde tanımlanmasından ve "i" etrafında bir "kapanma" oluşturulmasından "i" olmasını beklerim. Elbette, örneğiniz aksi kanıtlanır. Sözdizimi, sözdizimi açısından biraz kafa karıştırıcı olduğunu düşünüyorum, ancak bu senaryo o kadar yaygındır ki, bu şekilde desteklemesi mantıklıdır. Bunu getirdiğiniz için çok teşekkürler. - Karol Kolenda
IE 11 destekler letAncak, tüm düğmeler için "6" uyarır. Nasıl olduğunu söyleyen bir kaynağın var mı let davranması gerekiyordu? - Jim Hunziker
Cevabın doğru davranış gibi görünüyor: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... - Jim Hunziker
Gerçekten de bu Javascript'te yaygın bir tuzak ve şimdi neden olduğunu anlayabiliyorum let gerçekten yararlı olur. Bir döngüdeki olay dinleyicilerini ayarlama, yerel olarak kapsam belirleme için anında bir çağrılmış işlev ifadesi gerektirmez. i her iterasyonda. - Adrian Moisa
"Let" kullanımı bu sorunu çözmektedir. Bu nedenle, her yineleme özel bağımsız bir blok kapsamı oluşturur, ancak "i" değişkeni hala bloktaki sonraki değişiklikler tarafından bozulabilir, (yineleyici değişkeni verilen değil genellikle bloğun içinde değiştirildi, ancak diğer bildirilenler bloğun içindeki değişkenler iyi olabilir) ve blok içinde bildirilen herhangi bir işlev, çağrıldığında, blok içinde bildirilen diğer işlevler için "i" değerini bozabilir, çünkü yap Aynı özel blok kapsamını, "i" ile aynı referansı paylaşır. - gary


İşte bir açıklaması let anahtar kelime bazı örneklerle.

var gibi çok çalışalım. Temel fark, bir değişken değişkeninin kapsamının tüm kapatma işlevi olmasıdır.

Bu masa Wikipedia'da hangi tarayıcıların Javascript'i desteklediğini gösterir 1.7.

Yalnızca Mozilla ve Chrome tarayıcılarının desteklediğini unutmayın. IE, Safari ve potansiyel olarak diğerleri yok.


131
2018-02-23 18:35



Bağlantılı belgeden alınan metnin anahtar biti, "çok çeşitlilikte çalışsın. Ana fark, bir değişken değişkeninin kapsamının tüm kapama işlevi olmasıdır". - Michael Burr
IE'nin bunu desteklemediğini söylemek teknik olarak doğru olsa da, yalnızca bir uzantı olduğunu söylemek daha doğru olur. - olliej
@olliej, aslında Mozilla oyunun tam önündedir. Sayfa 19'a bakın ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf - Tyler Crompton
@TylerCrompton, yıllardır ayrılmış olan kelime dizisidir. Mozilla eklendiğinde, bununla ilgili bir özellik içermeyen tamamen bir mozilla uzantısı olmasına izin ver. ES6, izin ifadeleri için davranışı tanımlamalı, ancak mozilla sözdizimini tanıttıktan sonra geldi. Unutmayın ki moz da sadece tamamen ölü ve moz olan E4X'e sahiptir. - olliej
IE11 desteği eklendi let  msdn.microsoft.com/en-us/library/ie/dn342892%28v=vs.85%29.aspx - eloyesp


Arasındaki fark nedir let ve var?

  • Kullanılarak tanımlanan bir değişken var deyim boyunca bilinen işlev Fonksiyonun başlangıcından itibaren tanımlanır. (*)
  • Kullanılarak tanımlanan bir değişken let ifade sadece bilinir blok ileride tanımlandığı andan itibaren tanımlanır. (**)

Farkı anlamak için aşağıdaki kodu dikkate alın:

// 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

Burada değişkeni görebiliriz j sadece ilk döngüde bilinir, ancak önce ve sonra değil. Yine de değişkenimiz i tüm işlevde bilinir.

Ayrıca, blok kapsamındaki değişkenlerin, kaldırılmadıkları için bildirilmeden önce bilinmediklerini de göz önünde bulundurun. Aynı bloğun kapsamındaki aynı bloğu kapsam dışı değişkenini de tekrar reddetme izniniz yok. Bu, blok kapsamındaki değişkenleri, küresel olarak veya işlevsel olarak kapsamlandırılmış değişkenlere göre daha az hataya eğilimli hale getirir; bunlar, kaldırılır ve çoklu beyanlarda herhangi bir hata üretmez.


Kullanmak için güvenli mi let bugün?

Bazı insanlar ileride SADECE izin ifadeleri kullanacağımızı ve bu var deyimlerin eskimiş olacağını tartışacaktı. JavaScript guru Kyle Simpson yazdı durumun neden böyle olmadığına dair çok özenli bir yazı.

Ancak bugün, bu kesinlikle böyle değil. Aslında, aslında güvenli olup olmadığını kendimize sormamız gerekiyor. let Beyan. Bu sorunun cevabı ortamınıza bağlıdır:

  • Sunucu tarafı JavaScript kodu yazıyorsanız (node.js), güvenle kullanabilirsiniz let Beyan.

  • İstemci tarafında JavaScript kodu yazıyorsanız ve bir transpiler kullanıyorsanız traceur), güvenle kullanabilirsiniz let ifadesi, ancak kodunuzun performans açısından en iyi, ancak en iyi şey olması muhtemeldir.

  • İstemci tarafında JavaScript kodu yazıyorsanız ve bir transpiler kullanmıyorsanız, tarayıcı desteğini dikkate almanız gerekir.

Bugün, Jun 8 2018, hala desteklemeyen bazı tarayıcılar var let!

enter image description here


Tarayıcı desteği nasıl takip edilir?

Hangi tarayıcıların desteklediği ile ilgili güncel bir genel bakış için let Bu cevabı okuma zamanındaki beyanı, bkz. bu Can I Use sayfa.


(*) Küresel ve işlevsel olarak kapsamlandırılmış değişkenler, JavaScript değişkenleri olduğu için bildirilmeden önce başlatılabilir ve kullanılabilir. hoisted. Bu, beyanların her zaman kapsamın en üstünde olduğu anlamına gelir.

(**) Engelli değişkenler kaldırılmaz


116
2018-06-02 20:59



cevap v4 ile ilgili: i Fonksiyon bloğunda her yerde bilinir! Olarak başlar undefined Bir değer atayana kadar (kaldırma nedeniyle)! ps: let aynı zamanda (bloğu içeren bloğun üstüne) kaldırılır, ancak ReferenceError İlk atamadan önce blokta referans verildiğinde. (ps2: Ben bir yanlısı yarıyıl gencim ama ben bir bloktan sonra bir noktalı virgül gerekmez). Bu söyleniyor, destek ile ilgili gerçek-kontrol eklediğiniz için teşekkürler! - GitaarLAB
@GitaarLAB: göre Mozilla Geliştirici Ağı : "ECMAScript 2015'te, bağlantıların Değişken Kaldırma işlemine tabi tutulmasına izin vermeyin; bu, beyanların geçerli yürütme bağlamının en üstüne taşınmasına izin vermez." - Her neyse, aramdaki kaldırma davranışındaki farkı açıklığa kavuşturmak için cevabımda birkaç iyileştirme yaptım. let ve var! - John Slegers
Cevabınız çok arttı (iyice kontrol ettim). Yorumunuzda başvurulan aynı bağlantıyı da not edin: "(let) değişkeni" geçici ölü bölge "içinde bloğun başlangıcı Başlatma işlemi işlenene kadar. "Bu," tanımlayıcı "nın ('bir şey' işaret etmek için 'ayrılmış' metin dizesi) olduğu anlamına gelir. zaten İlgili kapsamda saklıdır, aksi takdirde kök / ana bilgisayar / pencere kapsamının bir parçası olacaktır. Şahsen benim için 'kaldırma', 'tanımlayıcıları' beyan edilen ilgili alanlara ayırmaktan / linklemekten başka bir şey ifade etmiyor; onların başlatılması / atanması / değiştirilebilirliği hariç! - GitaarLAB
Ve .. + 1. Bağladığınız Kyle Simpson makalesi bir mükemmel Oku, bunun için teşekkürler! Ayrıca "geçici ölü bölge" aka "TDZ" hakkında açıktır. Eklemek istediğim ilginç bir şey: MDN'de okudum ki let ve const idi Yalnızca ek işlevlerine gerçekten ihtiyaç duyduğunuzda kullanılması önerilirBu ek özelliklerin (yalnızca yazım kurgusu gibi) zorlanması / kontrol edilmesi, (geçerli) motorun / sürücülerin zorlanması / kontrol edilmesi / doğrulanması / ayarlanması için 'daha fazla çalışma' (ve kapsam ağacındaki ek kapsam-düğümleri) ile sonuçlandığından . - GitaarLAB


Kabul edilen cevap bir nokta eksik:

{
  let a = 123;
};

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

98
2018-04-17 21:38



Kabul edilen cevap bu noktayı açıklıyor. - TM.
Kabul edilen cevap, bu noktayı kendi örneğinde açıklamıyor. Kabul edilen cevap sadece bir for döngü başlatıcı, sınırlamalarının uygulama kapsamını önemli ölçüde daraltma let. Upvoted. - Jon Davis
@ stimpy77 Açıkça "en yakın kapalı bloğa kadar genişletilmiş" ifadesini belirtir; tezahür etmenin her yolu dahil edilmeli mi? - Dave Newton
Çok fazla örnek vardı ve bunların hiçbiri meseleyi düzgün bir şekilde gösteremedi. Hem kabul edilen cevabı hem de bu ikisini birden bastırabilir miyim? - Jon Davis
Bu katkı, bir "bloğun" basitçe parantez içine alınmış bir dizi küme olabileceğini göstermektedir; yani, herhangi bir kontrol akışı, ilmek, vb. ile ilişkili olması gerekmemektedir. - webelo


Bazı ince farklılıklar var - let scoping daha fazla ya da daha az başka bir dilde yaptığı gibi değişken kapsam belirleme gibi davranır.

Örneğin. Kapama bloğuna kadar uzanır, ilan edilmeden önce var olmazlar, vs.

Ancak buna değer let yeni Javascript uygulamalarının sadece bir parçasıdır ve değişken dereceleri vardır tarayıcı desteği.


40
2018-03-06 10:41



Ayrıca ECMAScript'in standart olduğunu ve let içinde yer almaktadır 6. baskı taslağı ve büyük olasılıkla son şartnamede olacak. - Richard Ayotte
3 yıllık fark bu: D - olliej
Sadece bu soruya cevap vermedi ve 2012'de sadece Mozilla tarayıcılarının desteklediği durum devam ediyor. let. Safari, IE ve Chome hepsi yok. - pseudosavant
Kazara kazara kısmi blok kapsamı yaratma fikri iyi bir nokta, dikkat, let tarafından tanımlanan bir değişken kullanmak için let bloğunuzun üstünde tanımlanmış. Eğer bir if Sadece birkaç satırlık koddan daha fazlası olan deyim, tanımlandıktan sonra bu değişkeni kullanamazsınız. BÜYÜK NOKTASI !!! - Eric Bishard
@EricB: evet ve hayır: "ECMAScript 2015'te, let  kaldıracak Değişken bloğun tepesine. Ancak, değişken bildiriminden önce bloğun içindeki değişkene başvurmak, ReferenceError (notum: iyi eski yerine undefined). Değişken, bildirimin başlangıcına kadar bloğun başlangıcından itibaren bir 'geçici ölü bölge' dir. ”Aynı durum," yalnızca bir alt bloğun olduğu için anahtar ifadeleri "için de geçerlidir. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... - GitaarLAB


İşte ikisi arasındaki fark için bir örnek (destek sadece krom için başladı): enter image description here

Gördüğünüz gibi var j değişken hala for loop kapsamının dışında bir değere sahip (Block Scope), ancak let i değişken döngü kapsamı dışında tanımsızdır.

"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);


39
2017-11-23 22:52



Burada hangi aracı arıyorum? - Barton
Chrome devtools - vlio20
Tarçın için bir masaüstü uygulaması geliştiricisi olarak, bu kadar parlak araçlara maruz kalmadım. - Barton


let

Blok kapsamı

Kullanarak bildirilen değişkenler let anahtar kelime blok kapsamlıdır, yani yalnızca blok onlar ilan edildi.

En üst seviyede (bir fonksiyonun dışında)

En üst düzeyde, kullanılarak bildirilen değişkenler let global nesne üzerinde özellik oluşturmayın.

var globalVariable = 42;
let blockScopedVariable = 43;

console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43

console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined

Bir fonksiyonun içinde

İçinde bir funciton (ama bir blok dışında), let aynı kapsamı var 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

Bir blok içinde

Kullanarak bildirilen değişkenler let Bir bloğun içine bu bloğun dışında erişilemez.

{
  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

Bir döngü içinde

İle bildirilen değişkenler let döngüler içinde sadece bu döngü içinde başvuru yapılabilir.

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.

Kapaklı döngüler

Eğer kullanırsan let yerine var Bir döngüde, her yineleme ile yeni bir değişken alırsınız. Bu, bir döngü içinde bir kapamayı güvenle kullanabileceğiniz anlamına gelir.

// 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);
}

Zamansal ölü bölge

Nedeniyle geçici ölü bölge, kullanılarak bildirilen değişkenler let bildirilmeden önce erişilemez. Bunu yapmaya teşebbüs etmek bir hata atıyor.

console.log(noTDZ); // undefined
var noTDZ = 43;
console.log(hasTDZ); // ReferenceError: hasTDZ is not defined
let hasTDZ = 42;

Yeniden ilan edilmiyor

Aynı değişkeni birden çok kez kullanarak bildiremezsiniz. let. Ayrıca bir değişken kullanarak bildiremezsiniz. let kullanarak bildirilen başka bir değişken ile aynı tanımlayıcı ile 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 oldukça benzer let- Block scoped ve TDZ var. Bununla birlikte, farklı olan iki şey var.

Yeniden atama yok

Değişken kullanılarak bildirildi const yeniden atanamaz.

const a = 42;
a = 43; // TypeError: Assignment to constant variable.

Bunun, değerin değişmez olduğu anlamına gelmediğini unutmayın. Özellikleri hala değiştirilebilir.

const obj = {};
obj.a = 42;
console.log(obj.a); // 42

Eğer değişmez bir nesneye sahip olmak istiyorsanız, kullanmalısınız. Object.freeze().

Başlatıcı gerekli

Değişken kullanarak bildirirken her zaman bir değer belirtmelisiniz. const.

const a; // SyntaxError: Missing initializer in const declaration

38
2018-01-17 15:11





  • Değişken Kaldırma

    let irade kaldırma Göründükleri bloğun tüm kapsamına. Buna karşılık, var aşağıdaki gibi kaldırabilir.

    {
       console.log(cc); // undefined. Caused by hoisting
       var cc = 23;
    }
    
    {
       console.log(bb); // ReferenceError: bb is not defined
       let bb = 23;
    }
    

    Aslında, Per @Bergi, Her ikisi de var ve let çekilir.

  • Çöp toplama

    Blok kapsamı let faydalıdır, hafızayı geri almak için kapaklar ve çöp toplama ile ilgilidir. Düşünmek,

    function process(data) {
        //...
    }
    
    var hugeData = { .. };
    
    process(hugeData);
    
    var btn = document.getElementById("mybutton");
    btn.addEventListener( "click", function click(evt){
        //....
    });
    

    click işleyici geri çağırma gerekmez hugeData tüm değişken. Teorik olarak, sonra process(..) çalışır, dev veri yapısı hugeData çöp toplanabilir. Ancak, bazı JS motorlarının bu devasa yapıyı korumak zorunda kalacağı, click Fonksiyonun tüm kapsamı üzerinde bir kapatma vardır.

    Bununla birlikte, blok kapsamı bu büyük veri yapısını toplanan çöplere dönüştürebilir.

    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 döngüler

    let döngü içinde yeniden bağlar Döngünün her yinelemesine, önceki döngü yinelemesinin sonundan değeri yeniden atadığınızdan emin olun. Düşünmek,

    // print '5' 5 times
    for (var i = 0; i < 5; ++i) {
        setTimeout(function () {
            console.log(i);
        }, 1000);  
    }
    

    Ancak, yerine var ile let

    // print 1, 2, 3, 4, 5. now
    for (let i = 0; i < 5; ++i) {
        setTimeout(function () {
            console.log(i);
        }, 1000);  
    }
    

    Çünkü let a) Başlatıcı ifadesi b) her yineleme (önceden ifade ifadesini değerlendirmek için); İşte.


20
2018-03-22 14:39



Aslında Hala çekiliyorlar - Bergi
Yipleri kaldırılırlar, fakat (davul) Temporal Ölü Bölge yüzünden kaldırılmamış gibi davranırlar - bir tanımlayıcının bildirilinceye kadar erişilebilir olmaması için çok dramatik bir isim. - Drenai
Öyleyse izin verilir, fakat kullanılamaz? Bu nasıl “çekilmez” den farklı? - N-ate
Umarım Brian ya da Bergi buna cevap vermek için geri döner. Beyannamenin beyanı değil mi, değil mi? Teşekkürler! - N-ate
@ N-yedik, İşte bir yazı Bergi, belki cevabını bulabilirsin. - zangw