Şaşırtıcı bir şekilde, buradaki cevapların hiçbiri Kapsam Zincirindeki Yürütme Bağlamının uygunluğundan bahsetmiyor.
JavaScript Motoru, o anda yürütülmekte olan kodu bir Yürütme Bağlamında sarar. Temel yürütme bağlamı, genel Yürütme Bağlamıdır. Her yeni işlev çağrıldığında, yeni bir Yürütme Bağlamı oluşturulur ve Yürütme Yığını'na yerleştirilir. Diğer programlama dillerinde bir Çağrı Yığını üzerinde oturan bir Yığın Çerçevesi düşünün. Son giren ilk çıkar. Artık her Yürütme Bağlamının JavaScript'te kendi Değişken Ortamı ve Dış Ortamı vardır.
Aşağıdaki örneği bir gösteri olarak kullanacağım.
1) İlk olarak, küresel Yürütme Bağlamının Oluşturma Aşamasına giriyoruz. Sözcüksel Ortamın Hem Dış Çevresi hem de Değişken Ortamı yaratılır. Global Nesne kurulur ve ona işaret eden özel değişken 'this' ile belleğe yerleştirilir. A fonksiyonu ve kodu ve tanımlanmamış bir değere sahip myVar değişkeni, global Değişken Ortamında belleğe yerleştirilir. a'nın kodunun çalıştırılmadığına dikkat etmek önemlidir. Sadece a fonksiyonu ile hafızaya alınır.
2) İkincisi, Yürütme Bağlamının Yürütme Aşamasıdır. myVar artık tanımlanmamış bir değer değil. Global Değişken Ortamında saklanan 1 değeriyle başlatılır. A işlevi çağrılır ve yeni bir Yürütme Bağlamı oluşturulur.
3) a işlevinin Yürütme Bağlamında, kendi Yürütme Bağlamının Oluşturma ve Yürütme Aşamasından geçer. Kendi Dış Ortamı ve Değişken Ortamı, dolayısıyla kendi Sözcüksel Ortamı vardır. B fonksiyonu ve myVar değişkeni Değişken Ortamında saklanır. Bu Değişken Ortam, küresel Değişken Ortamdan farklıdır. A işlevi sözcüksel olarak (fiziksel olarak kodda) küresel Yürütme Bağlamıyla aynı düzeyde bulunduğundan, Dış Ortamı küresel Yürütme Bağlamıdır. Bu nedenle, a işlevi Değişken Ortamında olmayan bir değişkene atıfta bulunacaksa, Kapsam Zincirini arayacak ve değişkeni global Yürütme Bağlamının Değişken Ortamında bulmaya çalışacaktır.
4) b işlevi, a işlevinde çağrılır. Yeni bir Yürütme Bağlamı oluşturulur. Sözcüksel olarak a işlevine oturduğundan, Dış Ortamı a'dır. Dolayısıyla, myVar'a başvurduğunda, myVar işlev b'nin Değişken Ortamında olmadığından, a işlevinin Değişken Ortamına bakacaktır. Orada bulur ve console.log 2. yazdırır. Fakat eğer değişken a'nın Değişken Ortamı işlevinde değilse, o zaman a işlevinin Dış Ortamı genel Yürütme Bağlamı olduğundan, Kapsam Zinciri orada aramaya devam edecektir.
5) b ve a işlevinin yürütülmesi tamamlandıktan sonra, Yürütme Yığınından çıkarılırlar. Tek iş parçacıklı JavaScript Motoru, küresel Yürütme Bağlamında çalışmaya devam eder. B işlevini çağırır. Ancak küresel Değişken Ortamında b işlevi yoktur ve küresel Yürütme Bağlamında aranacak başka bir Dış Ortam yoktur. Böylece JavaScript Engine tarafından bir istisna ortaya çıkar.
function a(){
function b(){
console.log(myVar);
}
var myVar = 2;
b();
}
var myVar = 1;
a();
b();
> 2
> Uncaught ReferenceError: b is not defined
Aşağıdaki örnek Kapsam Zincirini iş başında göstermektedir. B fonksiyonunun Yürütme Bağlamının Değişken Ortamında, myVar yoktur. Böylece, a fonksiyonu olan Dış Ortamını arar. A işlevinin de Değişken Ortamında myVar'ı yoktur. Dolayısıyla, Motor aramaları, a'nın Dış Ortamını, yani global Yürütme Bağlamının Dış Ortamı işlevini görür ve myVar burada tanımlanır. Bu nedenle, console.log 1 yazdırır.
function a(){
function b(){
console.log(myVar);
}
b();
}
var myVar = 1;
a();
> 1
Dış Ortam ve Değişken Ortam dahil, Yürütme Bağlamı ve onunla ilişkili Sözcüksel Ortam ile ilgili olarak, JavaScript'teki değişkenlerin kapsamını etkinleştirin. Aynı işlevi birden çok kez çağırsanız bile, her çağrı için kendi Yürütme Bağlamını oluşturur. Dolayısıyla, her Yürütme Bağlamı, Değişken Ortamında değişkenlerin kendi kopyasına sahip olacaktır. Değişkenlerin paylaşımı yoktur.