Pertanyaan Mengapa variabel cakupan-tertutup ini kehilangan nilainya?


Saya melihat kuis Javascript ini di sini: http://www.netfxharmonics.com/2008/01/NetFX-Harmonics-JavaScript-Quiz

dan saya tidak dapat menemukan masalah ini:

(function(){
    var a = 1;
    var b = 2;

    (function( ) { a = b; var b; })( );

    console.log('a:'+ a);  // => "a:undefined"
    console.log('b:'+ b);  // => "b:2"
})()

Namun, jika Anda menghapus var b; deklarasi dari fungsi batin, lalu a == 2 seperti yang Anda harapkan.

Kenapa ini terjadi?

(Anda dapat bermain dengannya di sini: http://jsfiddle.net/gnhMZ/)


6
2018-04-21 05:57


asal


Jawaban:


Itu terjadi karena fungsi ini:

(function( ) { a = b; var b; })( );

... menugaskan undefined untuk a. var mulai berlaku sejak awal ruang lingkup yang ditulisnya, tidak di mana ia berada dalam kode langkah demi langkah. Dan ketika Anda mendeklarasikan variabel, nilai awalnya adalah undefined. Jadi di atas ditulis lebih eksplisit, tetapi dengan fungsi yang persis sama, terlihat seperti ini:

(function( ) {
    var b = undefined;
    a = b;
})( );

Khususnya, ketika eksekusi memasuki konteks eksekusi, hal ini terjadi:

  1. A belakang layar objek variabel dibuat untuk konteks eksekusi dan diletakkan di bagian atas rantai lingkup (rantai objek variabel yang digunakan untuk menyelesaikan referensi yang tidak memenuhi syarat).
  2. Properti dibuat pada objek variabel untuk masing-masing var dideklarasikan dalam konteks, di mana pun var pernyataan itu. Nilai awal setiap variabel adalah undefined. Inisialisasi tidak ditangani pada titik ini.
  3. Properti dibuat pada objek variabel untuk setiap fungsi yang dideklarasikan (dengan deklarasi fungsi, bukan ekspresi fungsi) dalam konteks, terlepas dari di mana deklarasi fungsi.
  4. Deklarasi fungsi diproses dan hasilnya ditetapkan ke properti untuk fungsi-fungsi tersebut.
  5. Eksekusi berlanjut dengan baris pertama kode langkah demi langkah dalam konteks. Ketika sebuah var pernyataan dengan penginisialisasi ditemui, itu diproses sebagai pernyataan penugasan sederhana.

Itu objek variabel adalah hal yang membuat penutupan bekerja juga, dengan cara. Lebih lanjut di sini, tetapi pada dasarnya, ketika suatu fungsi dibuat, ia mendapat referensi abadi untuk semua benda variabel dalam rantai lingkup pada saat itu. Itulah yang digunakan untuk mencari variabel yang tertutup. Ini penting, karena penutupan tidak hanya memiliki referensi yang bertahan terhadap variabel yang sebenarnya digunakan, tetapi untuk semua variabel dalam-lingkup di mana itu didefinisikan, apakah itu menggunakan mereka atau tidak, yang dapat memiliki implikasi untuk siklus hidup dari variabel-variabel tersebut. .


8
2018-04-21 06:03



Penjelasan yang bagus tetapi jawaban sederhananya adalah bahwa variabel "a" tidak dideklarasikan di dalam fungsi batin. Oleh karena itu, menjadi lingkup global yang melampaui nilai lingkup luar.

a = "tidak terdefinisi"; // cakupan global

var = 1; // relatif terhadap ruang lingkupnya


1
2018-01-28 18:27