../b17/b17s2.htm b17s1

JavaScript Temelleri

Bölüm 17

Programların Kapsam Alanları

Bölüm 17 Sayfa 1

17.1 - Kapsam Alanlarının Tanıtımı

Kapsam alanları JavaScript programlarında çalıştırılabilir bir kodun çalışmasında oluşan çalışma alanlarıdır. Çalışma kapsam alanları sanal bir program bellek alanı (stack memory) oluştururlar. Etkin çalışma alanının program bellek alanı en üst düzeydedir yani en önce çalışır. JavaScript, üç türlü çalışma kapsamı alanı tanımlar. Bunlar Global, Eval ve Fonksiyon çalışma kapsam alanlarıdır.

17.1.1 - Global Kapsam Alanı

Global kapsam alanı,

...
<script type = "text/javascript">
global kodlar...
</script>
...
		

şeklinde script elemanları arasında veya sayfaya bağlantılı kodlar.js gibi bir dış JavaScript sayfasında, fonksiyon {} çalışma alanları dışında olan kodlardır. Global kapsam alanına, Üst Düzey Çalışma Alanı adı da verilir. Üst düzey çalışma alanında bulunan çalışabilen tüm kodlar çalışır. Her sayfada sadece bir tane üst düzey çalışma alanı bulunur. Bir sayfada ne kadar script elemanı içeriği tanımlanırlarsa tanımlansın, hepsinin içeriği aynı global kapsam alanı içindedir. Aynı şekilde, kaç tane olursa olsun, tüm bağlantılı JavaScript kod sayfaları aynı global kapsam alanına açılır. İster sayfa içinde tanımlanmış script elemanı içeriğinden gelsin, ister bir dış JavaScript program sayfasının global alanında tanımlansın, tüm global kodlar aynı global kapsam alanının bir parçasıdır. Global alanda tanımlanmış olan her değişken ve fonksiyona, global alana erişilebilen her yerden erişilebilir.

17.1.2 - Eval Kapsam Alanı

Eval kapsam alanı, eval('kodlar'), şeklinde, eval fonksiyonunun argümanı olarak tanımlanmış karakter dizgisidir. Bu karakter dizigisi argümanın içeriği, aynı bir JavaScript programı gibi çalışır. Bu kodlara kısaca eval makroları adı da verilir. Her eval() fonksiyonu, stack bellğindeki en son değeri geri döndürür. Bunun anlamı, tüm eval() argümanı kodlarının çalışıp sonucunun geri döndürüldüğüdür. eval() argümanında tanımlanımış kodlarda tüm JavaScript programları gibi, global kapsam alanı ve fonksiyon kapsam alanları bulunur. eval() kodlarına örnek olarak JavaScriptDeneme programı verilebilir.

Genel kanı olarak eval() kodlarının programları yavaşlattığı ve kullanılmaması sağlık verilmektedir. Bunun geçerliği duruma bağlıdır. Yukarıda örnek olarak verilen JavaScriptDeneme programı, matematik ifadelerin sonuçlarının kısa yoldan alınması için çok kulanışlıdır ve programda başka adım da olmadığından, yavaşlatacak başka kod da bulunmamaktadır. Doğal olarak kapsamlı JavaScript programlarında eval() kodları kullanılmamalıdır. Genel olarak bu kodlar yerine daima aynı işlevi görebilecek başka yöntemler olduğu belirtilmektedir.

17.1.3 - Fonksiyon Kapsam Alanları

JavaScript programlarında, fonksiyonlar, genel fonksiyon bildirimi, fonksiyon literaller ve fonksion nesne sınıf örneği olarak yaratılabiliir. Hangi yöntemle yaratılırsa, yaratılsın, fonksiyon içeriklerinin kapsam alanları birbiribinin aynıdır. Her fonksiyon içeriği bağımsız bir kod çalıştırma alanı olarak hareket eder.

17.2 - Değişken Nesne Sınıfı Örnekleri

Her kapsam alanı kendine bağlı bir değişken sınıf nesne örneği içerir. Bu kapsam alanında tanımlanmış her değişken ve fonksiyon, bu değişken nesnesi sınıf örneğinin özelliklerine eklenir. JavaScript çalışma sisteminin de nesne teknolojisine dayalı olması çok ilginçtir.

Başlangıç değeri verilmemiş değişkenler, undefined değerini alırlar. Eğer bir fonksiyon ismi veya parametresi, bir değişken ismi ile çakışırsa, çakışma fonksiyon isimini veya parametresini etkilemez. Eğer aynı adla ve aynı parametre listesi ile, daha önceden tanımlanmış bir fonksiyon varsa içeriği yenisi ile değiştirilir. Buna çok dikkat etmek gerekir, çünkü bir hata uyarısı vermez ama yanlış sonuçlara neden olabilir. En doğrusu, her programda, her öğenin ayrı isimleri olmasıdır.

Fonksiyon kapsamı içinde, değişkenler nesnesinin özellikleri, fonksiyonun formal parametre listesini ve tanımlanmış değişkenleri içerir. Eğer içlerinden bazılaraının adı aynı ise, en son tanımlannın değeri gerçerlidir. Bu yüzden aynı isimle tanımlamalar yapmaktan kaçınılması gerekir. Bir fonksiyon, formal parametre listesinden daha fazla sayıda argümanla çağrılırsa, ekstra argümanlarının değeri undefined olarak kabul edilir.

17.3 - Kapsam Zinciri ve Değişken Çözümlenmesi

Program kontrolü yeni bir kapsam alanına gidiğinde yeni bir değişken nesne sınıfı örneği yaratılır ve eskisi tahrip edilir. Değişken nesnesi tamamı ile bir iç çalışma mekanizmesıdır ve kullamıcının bu nesneye erişimi yoktur. Bu nesne kapsam alanında tanımlanan her değişken ve fonksiyonu yani bir özellik olarak içerir. Kullanıcılar sadece bu özelliklere erişebilirler. Her kapsam alanının kendine özgü bir kapsam zinciri vardır. Kapsam zinciri, bir değişkenin değeri aranırken arama listesinde olan öğelerden oluşur. Kapsam alanı sadece değişken nesnesi tarafından belirlenir. Kapsam zincirleri birbirlerine bağlanabilir. Bu durumda alt kapsamda değeri bulunamayan değişkenler ve değişken değerleri bir üst kapsamda aranır. Arama en üst kapsam alanı olan üst düzey kapsam alanına (global alan) erişilinceye kadar devam eder. Kapsam zincirleri sadece with bildirimleri ve catch cümlecikleri tarafından kesintiye uğratılırlar. Kapsam zinciri, bir kapsam alanına girilince yaratılır ve kapsam alanı terkedilince tahrip edilir, fakat özellikle kapalı devrelerde henüz etkin olan değişken nesnesi değişkenleri saklar. Kapalı devrelerde alt kapsamlar bu değişkenlere bu şekilde erişebilirler.

17.4 - Global Nesne

Her program için tek bir global nesne bulunabilir. Global nesnenin başlangıçta, Math, Date gibi, öntanımlı nesneleri bulunur. Bunlara, programın konuk edildiği (host) ortamın tanımlı nesnleri de katılır. Konuk eden ortamın nesne özelliklerinden birinin değeri global nesnenin kendisi olabilir. Örnek olarak (X)HTML ortamında, global nesnenin window özelliğinin değeri, global nesnenin kendisidir. Kolaylık olması için bazen window nesnesinin belirtilmesi ihmal edilebilir. Örnek olarak, window.Math yerine sadece Math olarak belirtilebilir.

Global kapsam alanında program çalışmaya başladığında, global nesnenin başlangıç özelliklerine yeni tanımlanan değişken ve fonksiyonlar da yeni özellikler olarak eklenirler ve başlangıç özellik değerlerinin bazıları değişebilir.

17.5 - Aktivasyon Nesnesi

Etkinleştirme( Aktivasyon) nesnesi, JavaScript yorumlayıcısının çalışma sistemi ile ilgilidir ve kullanıcıların bu nesneye erişimleri yoktur, fakat özelliklerine erişilebilir.

Bir fonksiyon kapsam alanına girildiğinde, bir etkinleştirme nesnesi arguments isimli bir özellikle birlikte oluşturulur. Bu özellik bir nesnedir ve kullanımı aşağıda açıklanmıştır. Bundan sonra etkinleştirme nesnesi, değişken nesnesinin örneklenmesi için kullanılır.

17.5.1 - Arguments Nesnesi

Bu nesnenin prototipi, Object nesnesinin prototipidir. Yani bu nesne bir generik nesne sınıfı alt sınıfıdır.

Program kontrolü bir fonksiyon kapsam alanına girince, arguments isimli bir nesne sınıf örneği aşağıda açıklanan özellikler ile yaratılır.

Bu nesnenin callee özelliğinin değeri, fonksiyonun kendisidir. Böylece, anonim fonksiyonların rekürsiv olabilmeleri sağlanabilecektir.

Bu nesnenin length özelliğinin değeri, fonksiyona kullanıcılar tarafından tanımlanan gerçek formal parametre listesinin formal parametre sayısıdır. Bu özelliğe arguments.length şeklinde ulaşılır.

Fonksiyon kodunun belirtiği kadar arguments [0], arguments [1], arguments [2]... şeklinde erişilebilen özellikler yaratılır. Bu özelliklerin başlangıç değerleri, kullanıcıların fonksiyon yazılımında belirttikleri başlangıç değerleridir. Bu değerler, bir dizinin elemanları değil, arguments nesnesinin özellikleridir. Yine de erişim metoduna bakılarak buna arguments dizisi denilmektedir.

Fonksiyonların tanımında, arguments nesnesinden, formal parametresi olmadan tanımlanmış fonksiyonların, formal parametre listesi ile çağrılması olanağının sağlanması için yararlanılır. Bu bir tür gizli parametre listesi olan fonksiyon tanımı anlamına gelir. Bu yöntemin, formal parametre listesi değişmeyecek olan fonksiyonlar için fazla bir avantajı yoktur, sadece olayı bilmeyenler kodları okurken biraz şaşırabilirler, fakat en büyük avantaj, formal parametre listesinin uzunluğu olaydan olaya değişen istatistik hesaplar için değişken sayıda argüman içerebilen fonksiyonların tanımında elde edilir. Aslında, bu sorun da formal paramatre olarak basit bir dizinin tanımlanması ile çözülebilirdi. Yine de aşağıda kodları görülen, gizli parametreli bir ortalama fonksiyonu hoş bir çözüm sunabilir. Bu programın çalışması, bağlantılı olduğu sayfada denenebilir.

...
function ortalama() {
var toplam = 0;
for (var i = 0; i<arguments.length; i++ ) {
toplam += arguments[i];
}
return toplam / arguments.length;
}

...
var değer = [];
değer[0]  = 98;
değer[1]  = 99;

bilgiYaz(ortalama(değer[0],değer[1]), 'b17.5.1-uyg-1-sonuç-1');
...
...
		

Doğal olarak, değişken parametre sayılı bir ortalama hesabı fonksiyonun tasarımı için arguments nesnesine mutlak gereksinmemiz yoktur. Prensip olarak kodları aşağıda görülen, parametresi basit bir dizi olan bir ortalama fonksiyonu da aynı işlevi sağlayabilecektir. Bu programın çalışması, bağlantılı olduğu sayfada görülebilir.

...
function ortalamaDeğer(veriler) {
var toplam = 0;
for (var i = 0; i<veriler.length; i++ ) {
toplam += veriler[i];
}
return toplam / veriler.length;
}

...
var değer = [];
değer[0]  = 98;
değer[1]  = 99;

bilgiYaz(ortalamaDeğer(değer), 'b17.5.1-uyg-2-sonuç-1');
...
		

Bu programların etkileşimli (interaktif) çözümlerinde, arguments nesnesinin kullanımına gerek duyulmamaktadır. Kodları aşağıda verilen, İlk etkileşimli çözüm örneğinde, JavaScript yorumlayıcısının değeri paha biçilmez split metodundan yararlanılmıştır. Bu program ilişikli olduğu uygulama sayfasında denenebilir.

Her zaman kendi kod çözümleyicilerimizi kolaylıkla yazabileceğimiz bu dersler çerçevesinde sık sık açıklanmıştı. Aşağıdaki program bunu kanıtlamaktadır. Aşağıdaki programda, JavaScript yorumlayıcısının hiçbir hazır metodu kullanılmamış, tüm kodlar sıfırdan başlanarak yazılmıştır. Bu programın iyice incelenmesi sağlık verilir.

/* <![CDATA[  */
			
/* Bu Program bdelib.js Kitaplık Programını Kullanmaktadır */

function ortalama(veriler) {
var toplam = 0;
for (var i = 0; i<veriler.length; i++ ) {
toplam += veriler[i];
}
return toplam / veriler.length;
}

function veriGir() {
var _gizli = true;
this.sınırlama = function() {
if (_gizli ) {
çözümle();
}
_gizli = false;
}


function çözümle() {
var bileşen = '', sayılar = '', veri = '', geçici = '', j = 0;

veri = oku('veriler');

for (var i = 0; i < veri.length; i++ ) {
sayılar =  sayılar + veri[i];
if (veri=[i] ==  '') {
for (var k = 0; k < sayılar.length - 1; i++ ) {
geçici = geçici + sayılar[k]; 
}
bileşen[j] = geçici;
sayılar = '';
j++;
}
for (var k = 0; k < sayılar.length - 1; i++ ) {
geçici = geçici + sayılar[k]; 
}
bileşen[j] = geçici;
sayılar = '';

for (var i = 0; i<bileşen.length; i++ ) {
bileşen[i] =  Number (bileşen[i]); 
}

yaz('sonuç', ortalama(veriler);
bilgiYaz('Sonuç Hesaplandı, Yeni Bir Ortalamanın Hesaplanması için Lütfen Sayfayı Yenileyiniz !', 'mesaj');
}


function başlangıç() {
var tıklama = new VeriGir();

yaz('veriler', '');
yaz('sonuç', ''); 

çalıştır('gir', tıklama.sınırlama);
} 

sayfaYüklendiktenSonraÇalıştır(başlangıç);

/* ]]>  */
		

Yukarıdaki program, ilişkili olduğu uygulama sayfasında denenebiir.

Gerek yukarıdaki, gerekse bir önceki çözümleyici programlar, endüstriyel ölçekte dayanıklı ve hata kalıdırabilen programlardır. Kullanıcılar virgülden sonra boşluklar bıraksalar da kod çözümleyiciler bunları doğru okuyacaklardır. Heriki programda da kod kullanıcıların tıklayabilecekleri tek defa ile sınırlandırılmıştır. Sonuçlar alındıktan sonra, yeni bir sonuç için, sayfayı yenileme tuşuna basılarak sayfa yenilenmelidir.

17.6 - Kapsam Alanlarına Giriş ve Çıkış

Her fonksiyon çağrısı yeni bir kapsam alanına girilmesine neden olur. Her returnbildirimi, fonksiyon kapsam alanından çıkılmasına neden olur.

Bir kapsam alanına girildiğinde, kapsam zinciri oluşturulur, değişken sınıfı nesne örneği yaratılır ve this değeri belirlenir. Bu olayların gelişimi, girilen kapsam alanı türüne bağlıdır.

17.6.1 - Global Kodlar

Global kodlar, sadece global olarak geçerli kodları kapsar. Bu kodlar, kapsam zincirinin sadece global nesneyi içermesi ve başka hiçbir kapsamı içermemesini sağlayacak şekilde oluşturulur. Burada, değişken nesnesi global nesnedir ve this saklı sözcüğü, global nesneyi işaret eder.

17.6.2 - Eval Kodları

Kontrol eval kodlarını içeren yeni bir kapsam alanına girince, çağıran kapsam olarak adlandırılan önceki kapsam alanı, değişken nesnesini, kapsam zincirini ve this değerini belirler. Eğer bir çağıran kapsam yoksa, değişken nesnesi, kapsam zinciri ve this değeri, aynı global nesne gibi oluşturulur.

Eğer bir çağıran kapsam varsa, kapsam zinciri, çağıran kapsam ile aynı sıralama ile, aynı nesnelerle oluşturulur. Buna with ve catch cümlecikleri de dahildir. Bu durumda, değişken nesnesi, aynı çağıran kapsam değişkenleri ile fakat boş özellik değerleri ile açılır. Buradaki this değeri, çağıran kapsamın this değeridir.

17.6.3 - Fonksiyon Kodları

Fonksiyon kapsamında, kapsam zinciri , etkinleşme nesnesini içerecek şekide, oluşan fonksiyon nesne sınıf örneğinin kapsam özelliğine uygun olarak açılır. Değişken nesnesi, etkinlik nesnesi değişken nesnesi olarak alınarak oluşturulur. Bu nesne, fonksiyon veya dış fonksiyon çağrılıncaya kadar tanımlanmış olan tüm değişkenleri, global nesneyi( window nesnesini), tüm belirtilmiş parametreleri içeren arguments nesnesini içerir. Burada this nesnesini çağıran kapsam sağlar. Geçerli bir this değerininin sağlanamadığı durumlarda this değeri, global nesne olarak kabul edilir. Bu kuralın en büyük istisnası, fonksiyonun bir nesnenin metodu olması halidir. Bu durumda this değeri, nesneyi işaret eder.

Valid XHTML 1.1