Javascript’te Scope kavramını anlamak

Yusuf GÜNGÖR
5 min readJan 11, 2019

--

Javascriptin Scope denilen bir özelliği vardır. Böyle bir konsept olmasına rağmen yeni geliştiriciler için bunu anlamak kolay değildir. Bunu basit şekilde size anlatmaya çalışacağım. Scope kavramını anlamak kodunuzu ön plana çıkarır, hataları azaltır ve daha güçlü bir tasarım deseni oluşturmanıza yardımcı olur.

Konu başlıkları

  • Scope nedir?
  • Neden Scope? En az erişim prensibi
  • JavaScript’te Scope
  • Global Scope
  • Yerel (Local) Scope
  • Blok ifadeleri (Block Statements)
  • Context (Bağlam)
  • Lexical Scope
  • The Module Pattern (Modül Deseni)
  • Changing Context with .call(), .apply() and .bind()

Scope nedir?

Scope, çalışma zamanı sırasında kodunuzun belirli bir bölümündeki değişkenlerin, fonksiyonların ve nesnelerin(objects) erişilebilirliğidir. Başka bir deyişle, Scope, kodunuzun belli kısımlarında değişkenlerin ve benzerlerinin görünürlüğüdür.

Neden Scope? En az erişim prensibi

Değişkenlerin görünürlüğünü sınırlandırmanın ve her yerde erişememenin amacı nedir? Çünkü bu işlem bize bir miktar güvenlik sağlar ve bu da bir avantajdır.

Bilgisayar yöneticilerini düşünün. Şirketin sistemleri üzerinde çok fazla kontrole sahip oldukları için, onlara tam erişim kullanıcı hesabı vermek uygun görünebilir. Hepsi sistemlere tam erişime sahip üç yöneticili bir şirketiniz olduğunu ve her şeyin sorunsuz çalıştığını varsayalım. Fakat aniden kötü bir şey oldu ve sisteminizden birine kötü amaçlı bir virüs bulaştı. Şimdi kimin hatası olduğunu bilmiyor musun? Bu yüzden herkese tam erişim vermemelisiniz. Bu, değişiklikleri izlemenize ve kimin ne yaptığını açıklamanıza yardımcı olur. Buna En Az Erişim Prensibi denir. Bu ilke, programlama dili tasarımlarına da uygulanır. Bu ilke, daha sonra çalışacağımız JavaScript dahil olmak üzere çoğu programlama dilinde Scope olarak adlandırılan programlama dili tasarımlarına da uygulanır.

Programlama yolculuğunuza devam ederken, Scope kullanımının kodunuzun verimliliği artırmaya, hatalarınızı izlemeye ve azaltmanıza yardımcı olduğunu fark edeceksiniz. Scope, aynı ada sahip, ancak farklı kapsamlarda değişkenleriniz olduğunda adlandırma sorununuzu da çözer.

JavaScript’te Scope

Javascript dilinde iki tip Scope vardır:

  • Global Scope
  • Local Scope

Değişken bir fonksiyonun içinde tanımlanırsa Local Scope olur eğer fonksiyonun dışında tanımlanırsa Global Scope olur. Tüm fonksiyonlar kendi içinde yeni bir Scope oluşturur.

Global Scope

Bir dosyaya JavaScript kodu yazmaya başladığınızda Global kapsamdasınız demektir. Bir JavaScript dosyasında yalnızca bir Global Scope vardır.

Global kapsam içindeki değişkenlere başka bir kapsamda erişilebilir ve değiştirilebilir.

Local Scope

Değişken bir fonksiyonun içinde tanımlanmışsa o değişken Local Scope’a sahiptir. Bu şu anlama gelmektedir biz her farklı Scope’da aynı isimle değişkenler tanımlayabiliriz ve birbirlerine karışmazlar. Çünkü onlar bulunduğu Scope’un değişkenidirler ve başka bir Scope’a sahip fonksiyondan erişilemezler.

Blok ifadeleri (Block Statements)

if ve switch gibi koşullu ifadeler veya for ve while gibi döngü ifadeleri fonksiyonların yaptığı gibi Scope oluşturmazlar. Burada tanımlanan değişkenler yine bulundukları Scope’a bağlı olacaklardır.

ECMAScript 6 ile let ve const anahtar kelimeleri tanıtıldı. Bu anahtar kelimeler var anahtar kelimesinin yerine kullanılabilir.

Var anahtar sözcüğünün aksine, let ve const anahtar sözcükleri if ve for gibi blok ifadelerinin içinde kendi kendine Scope oluştururlar.

Global Scope, uygulamanız devam ettiği sürece yaşar. Local Scope, işlevleriniz çağrılıp yürütüldüğü sürece yaşar.

Context (Bağlam)

Birçok geliştirici, genellikle Scope ve Context kavramlarının aynı şeyi ifade ettiğini düşünerek bu ikisini karıştırır. Ama aynı şey değildirler. Scope yazının yukarısında anlamaya çalıştığımız şeydir ve Context ise , kodunuzun belirli bir bölümündeki this değerini ifade etmek için kullanılır. Eğer bir nesnenin içinde değilseniz this kavramı yine window nesnesini işaret edecektir.

Eğer bir nesnenin içindeyseniz this kavramı bu sefer o nesneyi işaret edecektir.

Eğer bir fonksiyonu new anahtar kelimesi ile çağırırsanız nesne gibi davranacaktır ve bu sefer this kavramı o fonksiyonu ifade edecektir.

Lexical Scope (Sözcüksel Kapsam)

Lexical Scope, iç içe geçmiş bir işlev grubunda, iç işlevlerin değişkenlere ve kendi ana kapsamlarındaki diğer kaynaklara erişebileceği anlamına gelir. Bu, içte bulunan fonksiyonların üstte bulunan fonksiyonların yürütme bağlamına sözcüksel olarak bağlı olduğu anlamına gelir. Lexical Scope bazen Static Scope olarak da adlandırılır.

Gördüğümüz gibi en içteki fonksiyon içinde bulunduğu diğer fonksiyonların varlıklarına erişebilir ancak bu yöntem en dıştan en içe çalışmaz.

The Module Pattern (Modül Deseni)

Modül deseni ise şöyledir:

Modülün return ifadesi bizim gizli fonksiyonlarımızı içerir. Özel fonksiyonlar sadece direkt çağırılamayan fonksiyonlardır. Modül deseni sayesinde bu fonksiyonlar erişilemez hale gelir.

Genel olarak gizli fonksiyonlar isimlendirilirken “_” ile başlanır bu kod bloğumuz büyüdüğünde bize ayırt etmede yardımcı olur.

Bağlam Değiştirme (Changing Context) with .call(), .apply() and .bind()

call() ve apply() işlevleri, bir işlevi çağırırken contexti (bağlamı) değiştirmek için kullanılır. Call veya apply işlevini kullanmak için, işlevi bir parantez kullanarak çağırmak yerine işlev üzerinde çağırmanız ve context’i ilk argüman olarak iletmeniz yeterlidir. Örneklerle inceleyelim.

.Call () ve .apply () arasındaki fark, Call’da, argümanların geri kalanını virgülle ayrılmış bir liste olarak iletebilmenizdir.

Şimdiye kadar .call (), .apply ()‘i tartıştık. Call ve apply’dan farklı olarak, Bind işlevi kendisi çağırmaz, işlevi çağırmadan önce yalnızca context ve diğer argümanların değerini bağlamak için kullanılabilir. Bind uygulamasını yukarıdaki örneklerden birinde kullanalım:

Bind, call işlevi gibi aynı şekilde kullanılır.

Bu yazımda orjinali İngilizce olan bir yazının bir kısmını çevireceğim. Orjinal yazıya buradan ulaşabilirsiniz. Orjinal yazının tamamını çeviremedim bu kadarıyla umarım faydalı olmuştur. Gördüğünüz eksikleri belirtirseniz hemen düzeltebilirim. İyi çalışmalar.. :)

--

--