24 Mayıs 2011 Salı

Javascript Programlama Dili - Bölüm 3

Yahoo! Javascript mimarı Douglas Crockford'un Javascript eğitim videolarını izleyerek aldığım notları sizlerle paylaşmaya devam ediyorum.
Fonksiyonlar

Fonksiyonlar herhangi bir değer gibi değişkenlerde saklanabilir, diğer fonksiyonlara parametre olarak gönderilebilir ve return ile döndürülebilir.

Fonksiyonlar Object'ten miras alır ve isim/değer çiftleri barındırabilir.

Aşağıdaki iki ifade tamamen aynı anlama gelmektedir.
function yaz() { }
var yaz = function() {};

Fonksiyonlar, herhangi bir deyimin yazılabileceği her yerde (örneğin, başka bir fonksiyonun içinde) tanımlanabilirler.

İç içe fonksiyonlar yazıldığında, içteki fonksiyon, dıştaki fonksiyonun tüm değişkenlerine ve parametrelerine erişebilir.

Dıştaki fonksiyonun işletilmesi tamamlandıktan sonra dahi, içteki fonksiyon dıştaki fonksiyonun üyelerine erişebilir. Örneğin;
function fade(id) {
var dom = document.getElementById(id), level = 1;
function step() {
var h = level.toString(16);
dom.style.backgroundColor = '#FFFF' h h;
if (level < 15) {
level = 1;
setTimeout(step, 100);
}
}
setTimeout(step, 100);
}

Yukarıdaki fade isimli fonksiyon id'si parametre olarak gönderilen nesnenin arkaplan rengini sarıdan beyaza çevirir. Bu fonksiyon çalıştığında, önce dom ve level isimli iki değişken tanımlanır, sonra step isimli fonksiyon tanımlanır (çalıştırılmaz, sadece tanımlanır), daha sonra setTimeout deyimi ile 100 milisaniye sonra step fonksiyonunun çalıştırılması gerektiği sisteme bildirilir. Sonra da fade isimli fonksiyonun çalışması sona erer. Ancak, 100 milisaniye sonra sistem step isimli fonksiyonu çalıştırmaya başlar. Bu fonksiyon çalışmaya başladığında fade fonksiyonunun çalışması çoktan sona ermiş olmasına rağmen, fade fonksiyonunun level ve dom isimli değişkenler step fonksiyonunun içinde kullanılır.

Fonksiyonlar değer olarak kullanılabildiği için, nesnelerin fonksiyonları olabilir. Nesnelerin içindeki fonksiyonlara metot denir.

Fonksiyonlara gerektiğinden fazla parametre gönderilirse (örneğin, 3 parametreli bir fonksiyona 5 parametre gönderilirse), fazladan gönderilen parametreler görmezden gelinir. Gerektiğinden az parametre gönderilirse, eksik kalan parametrelere undefined değeri verilir. Her iki durumda da hata oluşmaz.
Fonksiyonların Çağrılma Biçimleri

Fonksiyonlar 4 farklı biçimde çağrılabilir:
Fonksiyon biçimi
fonksiyonNesnesi(parametreler)
Metot biçimi
nesne.metotAdi(parametreler)
nesne[“metotAdi”](parametreler)
Kurucu (constructor) biçimi
new fonksiyonNesnesi(parametreler)
Apply biçimi
fonksiyonNesnesi.apply(nesne,[parametreler])
this

Bir fonksiyon, fonksiyon biçiminde çağrıldığında this, global nesnedir (Bundan daha sona bahsedilecektir).

Bir fonksiyon metot biçiminde çağrıldığında this, fonksiyonun sahibi olan nesnedir.

Bir fonksiyon kurucu biçiminde (new operatörü ile) çağrıldığında, yeni bir nesne oluşturulur ve bu nesne this'e atanır. Eğer return ile bir değer döndürülmüyorsa, undefined yerine this döndürülür.

Özetle, this, fonksiyona gönderilen gizli bir parametredir. Bu parametrenin değeri ise fonksiyonun çağrılış şekline göre değişir:
Çağrılış Şekli this
Fonksiyon Global nesne
Metot Metoda sahip olan nesne
Kurucu Yeni oluşturulan nesne

arguments

Bir fonksiyon çağrıldığında, fonksiyonun parametreleri haricinde, arguments isminde başka bir gizli parametre daha vardır. Bu parametre, çağrılırken gönderilen tüm parametreleri içeren, dizi benzeri bir nesnedir.
function topla() {
var i, n = arguments.length, toplam = 0;
for (i = 0; i < n; i = 1) {
toplam = arguments[i];
}
return toplam;
}
Prototiplere Ekleme Yapma
Object.prototype
Array.prototype
Function.prototype
Number.prototype
String.prototype
Boolean.prototype

Javascript'te string'lerin başındaki ve sonundaki beyaz boşlukları silmek için herhangi bir fonksiyon yoktur. Ancak bunu biz yazabiliriz.
String.prototype.trim = function() {
return this.replace(/^\s*(\S*(\s \S )*)\s*$/, “$1”);
}

Böylece artık tüm string'ler trim isimli bir fonksiyona sahip olur.
var ad = ' Sinan ', soyad = ' İlyas ';
var yeniAd = isim.trim();
var yeniSoyad = soyad.trim();
typeof

Değerlerin tiplerini öğrenmek için başına typeof operatörü koyulabilir.
if (typeof deger === 'string') { ... }Tip typeof
object 'object'
function 'function'
array 'object'
number 'number'
string 'string'
boolean 'boolean'
null 'object'
undefined 'undefined'

new

new Boolean(), new String(), new Number() deyimlerinin kullanılması tavsiye edilmez. Çünkü örneğin, new Boolean() denildiğinde, boolean değer içeren yeni bir nesne oluşturulmuş olur. “Boolean değer” ile “boolean değer içeren nesne” birbirinden farklı şeylerdir. Bunun nasıl bir hataya yol açabileceği aşağıdaki örnekten görülebilir:
var nesne = new Boolean(false);
document.write(nesne);
if (nesne) {
document.write('true');
}
else {
document.write ('false');
}

Bu örnekte önce false, sonra true yazar. Çünkü document.write(nesne) denildiğinde nesnenin içindeki değer (false) yazdırılır. Ama if (nesne) denildiğinde, nesnenin içerdiği değer ne olursa olsun, tüm nesneler true kabul edildiği için, true yazdırılır.
Global Nesne

Global nesne, tüm global değişkenlerin ve javascript'in kendi nesnelerinin sahibidir. Web tarayıcılarında global nesne window'dur.

Global değişkenlerin kullanılması tavsiye edilmez. Çünkü bir uygulamanın içindeki fonksiyonlar birbiriyle çakışabilir, ya da birlikte çalışan uygulamalar birbiriyle çakışabilir. Global namespace'in kullanımı en aza indirilmelidir.

Düzgün bir şekilde tanımlanmamış tüm değişkenler global kabul edilir. Bu durum, encapsulation hakkında bilgi sahibi olmayan veya önemsemeyen kişiler için işleri kolaylaştırabilir, ama uygulamaları daha az güvenilir hale getirir.

Global değişkenleri ve uygulamaların diğer zayıf yönlerini bulma konusunda http://www.JSLint.com adresindeki JSLint programı kullanılabilir.
Namespace

Her nesne ayrı bir namespace'tir. Değişken ve fonksiyonlarınızı düzenlemek için bir namespace olarak nesne kullanınız. Böylece kendi yazdığınız kodların, kullandığınız hazır script'lerle vs. çakışması ihtimalini ortadan kaldırmış olursunuz. Namespace olarak kullanacağınız nesnenin adını büyük harflerle yazmanız tavsiye edilir, çünkü bu kazara diğer nesnelerle karıştırılarak kullanma ihtimalinizi azaltır.
var YAHOO = {}; // Namespace
YAHOO.Popup = function () {
// Popup ile ilgili global değişkenler ve fonksiyonlar
...
};

Fonksiyonlar değişkenler için kapsam belirlediği için, YAHOO.Popup fonksiyonunun içinde tanımlanan hiçbir değişken ve fonksiyon, bu fonksiyonun dışında geçerli değildir.
Kod Yazım Standartları

Javascript çok esnek bir dil olduğundan dolayı, kodlama stili konusunda disiplinli olmak gerekir. Douglas Crockford’un tavsiye ettiği Javascript kod yazım standartlarına şu adresten ulaşabilirsiniz:

http://javascript.crockford.com/code.html (İngilizce)
Noktalı Virgül

Derleyici bir hata gördüğünde hemen hata vermez. Önce en yakındaki satır sonuna gider, oraya bir noktalı virgül yerleştirir ve tekrar dener. Eğer yine hata varsa, o zaman hata verir. Ancak yine de gerekli olan her yere noktalı virgülleri koymak gerekir.
JSLint

JSLint Javascript ile yazılmış bir programdır. Yazdığınız Javascript kodlarını inceler ve yazdığınız kodların sağlamlığını ve taşınabilirliğini arttırmanız için size tavsiyelerde bulunur, yaptığınız hataları bulmanıza yardımcı olur. JSLint’e aşağıdaki adresten ulaşabilirsiniz:

http://www.JSLint.com

Douglas Crockford’un bu konuda bir uyarısız var: JSLint duygularınızı incitebilir! Çünkü çok katı kuralları var. Ancak eğer programın tavsiyelerini dinlerseniz, programlarınız çok daha iyi hale gelir.

Hiç yorum yok:

Yorum Gönder