Self Invoking Anonymous Function Bölüm 2

Makalemin ikinci bölümünde Self Invoking Fonksiyon tanımlamaları için kullanılan ve Douglas Crockford tarafından önerilen popüler bir pattern’den bahsetmek istiyorum. Eğer Self Invoking Fonksiyonları hakkında bilgi sahibi değilseniz konu ile ilgili olan bir önceki makalemi okumanızı tavsiye ederim.

;(function(window, document, undefined){
  ...
})(window, document)

İlk başta bakıldığında fonksiyon bloğundan önce tanımlanan ; işaretinin ne işe yaradığını, fonksiyon’a atanan window, document, undefined gibi global değişkenlerin neden tekrardan tanımlama ihtiyacı duyulduğu düşünebilirsiniz. Düşünüldüğünde garip gelebilecek bu tanımlamaları bu kadar popüler hale getiren sebepler nelerdir? Hadi gelin beraberce inceleyelim.

self-invoking fonksiyonu tanımı öncesinde “;” kullanımının önemi

Eğer bir self-invoking fonksiyonu ile çalışacaksanız bu fonksiyonu çağırmadan önce, daha önce eklemiş olan kod bloklarının düzgün şekilde kapatılıyor olmasına dikkat etmemiz gerekmektedir. Aksi durumda fonksiyonumuz çalışmayacaktır. Bu problemin oluşmamasını garantileyebilmek için fonksiyon tanımlamamız yapılmadan hemen önce ; işareti eklenilmiştir.

var x = 42
(function () { alert("Foo")})();​ // Fonksiyonumuz çalışmayacaktır

http://jsfiddle.net/PWZu6/

var x = 42
;(function () { alert("Foo")})();​ // Fonksiyonumuz çalışacaktır

http://jsfiddle.net/sVmqz/

window ve document parametreleri

Fonksiyon içinde çağrılan local değişkenler global değişkenlere oranla biraz daha hızlı işletilirler. Bir çok script bloğumuzun içinde kullandığımız window, document global objelerinin isimlerini kısaltarak referans değişkenler oluşturmak bize birazda olsa byte kazanımı sağlayarak dosya boyutlarını düşürmemizde fayda sağlayacaktır. Ayrıca kullanılan global objeler üzerinde bir başka script tarafından yapılan değişikliklerden etkilenmediğimiz gibi bizim yaptığımız değişikliklerdende diğer scriptler etkilenmiyecektir.

// Normal
(function(window,document,undefined){ ... })(this,this.document);
// Küçültülmüş
(function(b,a,c){ ... })(this,this.document);

“undefined” parametresi

ECMAScript3 kurallarına göre undefined global objesinin değerini herhangi bir kişi tarafından rahatlıkla değiştirilebilir. Böyle bir durumda kod içinde yaptığımız undefined karşılaştırmaları doğru sonucu vermeyecek ve kod akışımızın yanlış ilerlemesini sağlıyacaktır. Bu problemin önüne geçmek için fonksiyonumuzun son parametresi olarak undefined global değişkenini eklemimiz bu problemin önüne geçicektir. Bu sorun ECMAScript5 içinde düzeltilmiştir.

undefined = true; // true
(function (undefined) {
  alert(typeof undefined); // "undefined",
})();

İlgili Makaleler

Self Invoking Anonymous Function Bölüm 1

Bu makalemde javascript içinde bence önemli bir yere sahip olan self-invoking anonymous function olarak bilinen fonksiyon tipinden ve yaygın olarak tercih edilen kullanım şekillerinden bahsediyor olucam.

Self-Invoking Anonymous Function

Self-invoking anonymous diğer fonksiyon tanımlamalarının aksine kendine ait bir ismi olmayan ve oluşturulduğu anda otomatik olarak çalışmaya başlayan fonksiyon tipidir.

// Self-Invoking Anonymous Fonksiyon Tanımı
(function(){
 // code…
})();

// Normal bir fonksiyon tanımı
function foo() {
 // code…
}

Yukarıdaki kod bloklarını dikkatli incelediğinizde ilk fonksiyonun kendine ait bir ismi olmadığı gibi alışık olduğumuzdan farklı bir syntax’a sahip olduğunu farkediceksiniz. Bildiğiniz gibi javascript içinde bir fonksiyonun çalışabilmesi için fonksiyon isminden sonra () işaretlerinin eklenmiş olması yeterlidir. Yukarıdaki örneği göz önüne aldığımızda foo isimli fonksiyonun çalışabilmesi için fonksiyon tanımı yapıldıktan sonra aşağıdaki şekilde çağırılması gerekmektedir.

function foo() {
 // code…
}
foo();

Aynı sıralama self-invoking fonksiyon tipi için geçerli değildir. Çünkü fonksiyon tanımlanması yapılır yapılmaz otomatik olarak kendiliğinden çalışmaya başlayacaktır. Aşağıdaki örnekte bunu rahatlıkla görebilirsiniz.

(function(isim, soyad) {
 alert(isim +" "+ soyad); // Volkan Altınbaş
})("Volkan", "Altınbaş");

http://jsfiddle.net/9wCx6/

Self-Invoking Fonksiyon tipini nerede kullanabilirim?

En çok tercih edilen kullanım şekli bir Scoping oluşturarak içinde yazılmış olan script tanımlarının diğer global ortamda daha önceden tanımlanmış olabilecek diğer scriptler tarafından etkilenmeyeceği bir koruma duvarı oluşturmaktır. Bir plugin yazdığınızı hayal edin. Plugininiz içinde foo() adında bir fonksiyonumuz bulunuyor. Fakat siz daha önce bu isimde bir fonksiyonun başka bir plugin tarafından kullanılıp kullanılmadığından haberdar değilsiniz. Eğer foo() isimli fonksiyonu bir self-invoking function içinde değilde gelişi güzel şekilde global bir fonksiyon olarak tanımlarsanız en son tanımlanan fonksiyon bir öncekini yok edicek ve yerini kendisi alacaktır. Bu bir fonksiyon için olabildiği gibi global olarak kullanılan bir değişken içinde aynı şekilde işleyecektir. Bu durumdan kurtulmanın en kolay ve basit yolu self-invoking fonksiyon kullanımıdır. Aşağıdaki örneklerle konunun daha iyi anlaşılacağını düşünüyorum;


// x.js
function foo() {
 alert("Volkan")
}

// y.js
function foo() {
 alert("Hakan")
}

foo(); // Hakan

http://jsfiddle.net/nHKta/

y.js dosyasının x.js dosyasından sonra sayfaya yüklendiğini hayel edin. Sonuç x.js içinde tanımlanmış olan foo() fonksiyonunun y.js içinde tanımlanan foo() fonksiyonu tarafından ezilerek yerine geçmesi sonucunun “Hakan” olması ile sonuçlanacaktır. Aynı işlemi self-invoking fonksiyonu içinde tanımlayarak denediğinizde konuyu daha net anlıyacağınızı umuyorum.


// x.js

function foo() {
 alert("Volkan")
}

// y.js
(function() {
 function foo() {
   alert("Hakan")
 }

 foo(); // Hakan

})()

foo(); // Volkan

http://jsfiddle.net/hyGa9/

İlgili Makaleler

Görselliği Zenginleştirilmiş Selectbox (Custom Selectbox)

Web tasarımı ile ilgilenen herkezin bir kerede olsa görsel olarak düzenlemeye çalışmış olduğunu düşündüğüm ve ama her seferinde hüsranla sonuçlanan, tarayıcılar içinde görsel olarak belirli bir standarta oturmamış olan SELECTBOX‘tan bahsediyorum.

Hazırladığım projenin amacı sayfamızda bulunan ama ısrarla görsel olarak mudahaleye cevap vermeyen selectboxları bir javascript dosyası yardımı ile görsel olarak biçimleyebilmek.

Evet yanlış duymadınız. Artık sayfamızda bulunan selectboxlar üzerinden görsel olarak mudahale şansınız olacak. Tabiki bu bir ilk değil. Web dünyasında aşağıda linklerini verdiğim siteler gibi daha bir çok örneğini görebilirsiniz.

Peki Volkan neden bu kastın, zaten alem yapmış neden Amerikayı baştan keşfetmek istiyorsun diyen çıkacaktır aranızda. Belki haklısınız! Belkide;

Biraz BEN yaptım, hazırladım diyerek kendimi iyi hissetmem haricinde Türkiye içinde bu tarzda uygulamaları hazırlayan ve dahada iyilerini hazırlayabilecek bir çok insan tanıyorum. Ama üretmenin yanında hep tüketen, takip eden insanlar olacağımıza birazda üreten ve takip edilen insanlar olmak hoşunuza gitmezmi? Açıkcası benim gidiyor ve fırsatlar oldukça bu tarzda uygulamaları yazmaya devam edicem.

Hazırlamış olduğum kod şu anda tam anlamı ile bitmiş ve optimize değil. İşlerimden kalan zamanlarda kodlamaya devam ediyorum. Yaptığım çalışmaya aşağıdaki linklerden ulaşabilirsiniz.

Kendileri deneme yapmak isteyen arkadaşlar Demo linkine tıklayıp proje ilgili dosyaları indirebilirler.

Sizlerden gelen görüşler doğrultusunda kodları iyileştirmeye ve geliştirmeye devam edicem. Bu proje ile ilgili gelişmeleri Projelerim bölümü altından izleyebilirsiniz.

Ajax Türkçe Karakter ve Cache Sorunu

Genel olarak ajax kullanarak yapılan data alış verişlerinde türkçe karakter problemi ile karşılaşırız. Bunun bir çok sebebi var. Nedenleri ve çözümleri hakkında çok yazılıp çizildi biliyorum fakat geçen gün karşılaştığım farklı bir sorundan bahsetmek istiyorum. Sorun ajax ile query string üzerinden gönderilen türkçe karakter.

query adında bir parametremiz ve bu parametrenin Çicek adında bir değeri olsun. Göndericeğimiz sayfanın ismide index.asp. Url olarak tam görünümü index.asp?query=Çiçek şeklinde olacaktır. Ajax üzerinden bu url gönderdiğimde Internet Explorer 6 – Internet Explorer 7 içinde query parametresinin değeri iek olarak görülüyordu. Firefox, Opera, Safari, Google Chrome içinde ise değer düzgün şekilde iletiliyordu. İlk olarak encoding ayarlarından şüphelendim. Database ve gönderdiğim sunucu sayfasının encoding ve karakter setini kontrol ettiğimde olması gerektiği gibi UTF-8 olduğunu gördüm.

Internette biraz araştırdıktan sonra sorunun javascript üzerinden gönderilen verinin encoding ayarları ile ilgili olduğunu anladım. Çözüm için javascript üzerinden gönderilen türkçe karakterlere sahip verinin sunucu sayfasına encoding yapılarak gönderilmesini sağlayan ve javascript içinde hazır bir fonksiyon olarak kullanılan encodeURIComponent() buldum. Göndericeğimiz değeri bu fonksiyon içinde gönderdiğimde problem ortadan kalkmıştı.

Örnek:

index.asp?query=<strong>encodeURIComponent("</strong><strong>Çiçek</strong><strong>")</strong>

Bu sorunu çözdükten sonra sayfaları incelemeye başladığımda Internet Explorer 6 – Internet Explorer 7 içinde sayfadaki verilerin cache lediğini farkettim. Yine biraz araştırdıktan sonra bu sorununda genel bir sorun olduğunu ve bunu düzeltmek içinde ufak bir trick kullanıldığını gördüm. Yapılan iş aslında çok basitti. Var olan url ile birlikte query srting üzerinden random bir sayı üretilerek gönderilen başka bir parametre göndermek sorunu çözüyordu. Bu iş kullandığım ve gayet güzel iş gören fonksiyonu aşağıda bulabilirsiniz.

function noCache(uri){
return uri.concat(.test(uri)  &amp;  , noCache=, (new Date).getTime(), ., Math.random()1234567);
}

Ajax içinde göndericeğimiz URL’i bu fonksiyon içinde gönderdiğimizde artık Cache problemide ortadan kalkacaktır.

noCache(index.asp?query=encodeURIComponent("Çiçek"))

olarak gönderdiğimizde çıktı olarak karşımıza

index.asp?query=Çiçek&amp;noCache=Random

Sayı şeklinde bir url verecektir. Kolay gelsin.