Genel ve yerel değişken kapsamı

Bu makalede, kapsam ve JavaScript'te işleyiş şekli hakkında bilgi edineceksiniz.

Kapsam, JavaScript'te ve diğer programlama dillerinde değişkenlere erişildiği ve değişkenlerin kullanıldığı bağlamı tanımlayan temel bir kavramdır. Siz JavaScript öğrenmeye ve değişkenlerle daha çok çalışmaya devam ettikçe bu kod kodunuz için daha kullanışlı ve uygulanabilir hale gelir.

Kapsam size şu konularda yardımcı olabilir:

  • Belleği daha verimli kullanın: Kapsam, değişkenleri yalnızca gerektiğinde yükleme olanağı sağlar. Kapsam dışında olan bir değişkeni, o anda yürütülmekte olan kod için kullanılabilir hale getirmeniz gerekmez.
  • Hataları daha kolay bulup düzeltin: Yerel kapsamlı değişkenleri izole etmeniz, genel değişkenlerin aksine dış kapsamda yer alan bu kodun yerel kapsamlı değişkenler üzerinde değişiklik yapamayacağına güvenebileceğiniz için kodunuzdaki hataları gidermeyi kolaylaştırır.
  • Yeniden kullanılabilir küçük kod blokları oluşturun: Örneğin, dış kapsamı kullanmayan bir tam işlev yazabilirsiniz. Böyle bir işlevi, çok az değişiklikle başka bir yere kolayca taşıyabilirsiniz.

Kapsam nedir?

Değişkenlerin kapsamı, değişkenleri kodun neresinde kullanabileceğinizi belirler.

JavaScript, global veya yerel kapsam değişkenlerini tanımlar:

  • Genel kapsama sahip değişkenler, JavaScript kodu içindeki diğer tüm kapsamlardan kullanılabilir.
  • Yerel kapsamlı değişkenler yalnızca belirli bir yerel bağlamda kullanılabilir ve var, let ve const gibi anahtar kelimeler tarafından oluşturulur. Bir işlev içinde değişken oluşturmak için var, let veya const anahtar kelimelerini kullanırsanız bu değişken yerel kapsama sahip olur.

Bu makalenin ilerleyen bölümlerinde engelleme ve sözlüksel kapsam ele alınmaktadır:

  • Engelleme kapsamı değişkenleri, blok ifadesinin tanımlandığı kıvrık ayraçların konumuna göre belirlenen bloklarda yerel olarak kullanılabilir. Yalnızca let veya const anahtar kelimeleriyle tanımlanan değişkenler engelleme kapsamına sahiptir.
  • Sözlü kapsam, bir değişkenin nerede kullanılabildiğini belirlemek için kaynak kodda değişkenin bildirildiği konumu kullanır. Kapalı bir işleve, dış kapsamda başvurulan, sözlüksel ortam olarak bilinen değişkenlere erişim vermek için kapanışlar kullanırsınız.

Bir değişkene kapsamı dahilinde erişildiğinde, JavaScript atanan değerini döndürür veya başka bir şekilde hata verir.

Bir değişken bildirmek için:

  • Yerel veya global kapsamlı değişkenleri bildirmek için var, const veya let anahtar kelimelerini kullanın.
  • Blok kapsamlı değişkenleri bildirmek için const veya let anahtar kelimelerini kullanın.

Bir fonksiyonda var değişkeni bildirdiğinizde, bildirim, değişkeni en yakın ilgili işlevde kullanılabilir hale getirir. Engelleme kapsamlı değişkenleri bildirmek için var anahtar kelimesini kullanamazsınız.

Kapsam örnekleri

Bu örnekte, greeting değişkeni herhangi bir işlevin veya bloğun dışında tanımlandığı için global kapsam gösterilmektedir. Bu durum, değişkenin değerini geçerli dokümandaki tüm kodlar için kullanılabilir hale getirir:

const greeting = 'hello';
console.log(greeting); // 'hello'

Global kapsam örneğinde, greeting değişkenine bir hello değeri atanmıştır.

Bu örnekte, greeting değişkenini bir işlev içindeki let anahtar kelimesiyle bildirdiği için yerel kapsam gösterilmektedir. greeting değişkeni, yerel kapsamlı bir değişkendir ve işlevin dışında kullanılamaz.

function greet() {
  let greeting = 'Hello World!';
  console.log(greeting);
}

Bu örnekte, bir blok içindeki greeting değişkenini bildirdiği ve değişkene yalnızca süslü ayraçların içine erişilebildiği için blok kapsamı gösterilmektedir:

if (true) {
   const greeting = 'hello';
}

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

console.log işlevi, greeting değişkeninin değerini çıktı olarak almaya çalıştığında JavaScript'in beklenen hello mesajı yerine ReferenceError hata mesajı döndürdüğüne dikkat edin. Neden?

greeting değişkeni blok kapsama sahip olduğundan ve en yakın blok if koşullu ifadesinin bir parçası olduğundan hata döndürülür. Bir blok içinde tanımladığınız let ve const değişkenlerine blok dışından erişemezsiniz. Dolayısıyla, greeting değişkenine yalnızca blok kapsamını belirten kıvrık ayraçlar içinde erişebilirsiniz.

Bu örnekte, console.log(message) yöntemi süslü ayraçlar içine hareket ettiğinden hata düzeltildi. Güncellenen kod, console.log(message) yöntemini blokun içine yeniden yerleştirir.

if (true) {
   const greeting = 'hello';
   console.log(greeting);
}

Kapsam türleri

Global kapsam

Global kapsamlı değişkenlere programda her yerden erişebilirsiniz.

Şu iki JavaScript dosyasını içe aktaran bir HTML dosyası düşünün: file-1.js ve file-2.js:

<script src="file-1.js"></script>
<script src="file-2.js"></script>

Bu örnekte, globalMessage değişkeni genel bir kapsama sahiptir ve bir işlevin dışına yazılmıştır. Çalıştırma ve yürütme sırasında, globalMessage değişkeninin değerine JavaScript programında herhangi bir yerden erişebilirsiniz.

Bu kod snippet'inde file-1.js ve file-2.js dosyalarının içeriğini görebilirsiniz. Her iki dosyada da globalMessage değişkeninin kullanılabilir olduğuna dikkat edin.

// file-1.js
function hello() {
    var localMessage = 'Hello!';
}

var globalMessage = 'Hey there!';

// file-2.js
console.log(localMessage); // localMessage is not defined
console.log(globalMessage); // Hey there!

Bu makalede ele alınmayan başka bir kapsam türü de vardır. JavaScript modülü içinde ancak bir işlevin veya bloğun dışında oluşturduğunuz bir değişken genel kapsamı değil, modül kapsamına sahip olur. Modül kapsamına sahip değişkenler, geçerli modülün herhangi bir yerinde kullanılabilir ancak diğer dosya veya modüllerde kullanılamaz. Modül kapsamlı bir değişkeni diğer dosyaların kullanımına sunmak için oluşturulduğu modülden dışa aktarmanız ve değişkene erişmesi gereken modülden import gerekir.

Yerel kapsam ve işlev kapsamı

JavaScript işlevinde var, let veya const anahtar kelimeleriyle değişkenler oluşturduğunuzda, değişkenler işlevde yerel olur. Dolayısıyla, bunlara yalnızca işlev içinden erişebilirsiniz. Yerel değişkenler işlev başlatıldığında oluşturulur ve işlev yürütmesi tamamlandığında etkin bir şekilde silinir.

Bu örnekte, addNumbers() işlevindeki total değişkeni açıklanmaktadır. addNumbers() işlevindeki a, b, ve total değişkenlerine yalnızca erişebilirsiniz.

function addNumbers(a, b) {
    const total = a + b;
}

addNumbers(3, 4);

Değişkenleri adlandırmak için let ve const anahtar kelimelerini kullanabilirsiniz. let anahtar kelimesini kullandığınızda JavaScript değişkeni güncelleyebilir. Ancak const anahtar kelimesinde değişken sabit kalır.

var variable1 = 'Declared with var';
var variable1 = 'Redeclared with var';
variable1; // Redeclared with var

let variable2 = 'Declared with let. Cannot be redeclared.';
variable2 = 'let cannot be redeclared, but can be updated';
variable2; // let cannot be redeclared, but can be updated

const variable3 = 'Declared with const. Cannot be redeclared or updated';
variable3; // Declared with const. Cannot be redeclared or updated

Kapsam engelleme

Engellemeler, tek bir ifadeyi veya bir ifade grubunu birlikte gruplandırmak için kullanılır. Blok kapsamlı bir yerel değişken bildirmek için const veya let anahtar kelimelerini kullanabilirsiniz. Engelleme kapsamlı değişkenleri bildirmek için var anahtar kelimesini kullanamayacağınızı unutmayın.

Örneğin, bu blokta name değişkeninin kapsamı ve "Elizabeth" değeri küme parantezleri içinde yer alır. Bir engelleme kapsamındaki değişkenler, engellemenin dışında kullanılamaz.

{
    const name = "Elizabeth";
}

if, for veya while ifadelerinde blok kapsamlı değişkenleri kullanabilirsiniz.

Bu kod snippet'indeki iki for döngüsüne dikkat edin. Bir for döngüsü, başlatıcı değişkenini tanımlamak için var anahtar kelimesini kullanır ve bu değişken 0, 1 ve 2 sayıları kadar artar. Diğer for döngüsü, başlatıcı değişkenini bildirmek için let anahtar kelimesini kullanır.

for (var i = 0; i < 2; i++) {
    // ...
}

console.log(i); // 2

for (let j = 0; j < 2; j++) {
    // ...
}

console.log(j); // The j variable isn't defined.

Önceki kod örneğinde, ilk for döngüsündeki i değişkeninin for döngüsünün dışına sızdığını ve var anahtar kelimesi engelleme kapsamını kullanmadığı için hâlâ 2 değerini koruduğunu fark edebilirsiniz. Sorun, let anahtar kelimesiyle tanımlanan j değişkeninin for döngüsü bloğuna dahil edildiği ve for döngüsü bittikten sonra mevcut olmadığı ikinci for döngüsünde düzeltildi.

Bir değişken adının farklı bir kapsamda yeniden kullanımı

Aynı değişken adını farklı bir kapsamda başka bir yerde yeniden kullansanız bile kapsam, işlev içindeki bir değişkeni izole edebilir.

Bu örnekte, kapsam kullanımının aynı değişken adını farklı işlevlerde yeniden kullanmanıza nasıl olanak sağladığı gösterilmektedir:

function listOne() {
    let listItems = 10;
    console.log(listItems); // 10
}

function listTwo() {
   let listItems = 20;
   console.log(listItems); // 20
}

listOne();
listTwo();

listOne() ve listTwo() işlevlerindeki listItems değişkenlerine beklenen değerler atandığı için birbirleriyle çakışmamalıdır.

Kapanışlar ve sözlüksel kapsam

Kapanışlar, iç işlevin dış işlev kapsamına erişebildiği, bu da sözlüksel ortam olarak da bilinen kapalı işlevi ifade eder. Dolayısıyla, JavaScript'te işlevlerin dış sözcüksel ortama başvurmasını sağlamak için kapanışlar kullanırsınız. Böylece, bir işlev içindeki kod, işlevin dışında tanımlanan değişkenlere referans verebilir. Aslında harici sözlüksel ortamlara yönelik bir referans zincirini kodlayabilirsiniz. Böylece bir işlev, başka bir işlev tarafından da çağrılır.

Bu örnekte kod, outer() işlevi çağrıldığında oluşturulan sözlüksel ortamla bir kapanış oluşturur. Söz konusu ortam, hello değişkeni üzerinde kapanır. Bu nedenle, setTimeout geri çağırma işlevinde hello değişkeni kullanılır.

function outer() {
    const hello = 'world';

    setTimeout(function () {
        console.log('Within the closure!', hello)
    }, 100);
}

outer();

Sözcüksel kapsam ile kapsam çalışma zamanında değil, kaynak kodun derlenmesi sırasında belirlenir. Sözcüksel ortam hakkında daha fazla bilgi edinmek için Sözlük kapsamı oluşturma ve Kapatma sayfasına bakın.

Modüller

JavaScript modülleri, JavaScript kodunun düzenlenmesine yardımcı olur. Doğru kullanıldığında, kod tabanınız için etkili bir yapı sağlar ve kodun yeniden kullanılmasına yardımcı olur. JavaScript modülleri, farklı dosyalar arasında değişkenleri paylaşmak için genel değişkenleri kullanmak yerine, değişkenleri dışa ve import yönelik bir teknik sağlar.

// hello.js file
function hello() {
  return 'Hello world!';
}

export { hello };

// app.js file
import { hello } from './hello.js';

console.log(hello()); // Hello world!

Kapsam görselleştirici demosu

Kapsam, her JavaScript geliştiricisinin anlaması gereken temel bir kavramdır. Kapsam sistemini daha iyi anlamak için JS Scope Visualizer (JS Kapsam Görselleştirici) ile kendi kodunuzu yazmayı deneyebilirsiniz. Demo, JavaScript kapsamlarını görselleştirmenize yardımcı olmak için koddaki renklendirmeyi kullanır.

Sonuç

Bu makalede farklı kapsam türleri açıklanmaktadır. JavaScript kapsamı, web geliştirmedeki en ileri kavramlardan biridir. Bu nedenle, bu içeriği okuyup konuyu anlamak için zaman ayırmanız faydalı olacaktır.

Kapsam, kullanıcılara yönelik bir özellik değil. Bu durum yalnızca kodu yazan web geliştiricisini etkiler. Ancak kapsamın nasıl çalıştığını bilmek hataları ortaya çıktığında düzeltmenize yardımcı olabilir.