Yazılım.
CevapSitesi.com Beta!
Çözüm Noktası
Facebook, Twitter, Google+ veya e-posta ile paylaşın.
| Sorular | Makaleler | Üyeler | Etiketler  | İletişim
Soru sormak ya da cevap vermek için;
giriş yapın veya üye olun.

Sosyal medya hesaplarınızla da giriş yapabilirsiniz.

Yazılım Makaleleri

0

JavaScript Fonksiyonları: Function Yapılandırıcısı

Daha önceki makalelerimizde de belirttiğimiz gibi fonksiyonlar birer nesnedir ve bundan dolayı her fonksiyon bir değer olarak kullanılabilir.

Fonksiyon nesneleri Function nesnesinden türetilir. Yani function ile bir tanımlama yaptığınızda oluşturulan şey Function nesnesinin bir örneğidir, dolayısıyla bir nesne / değerdir.

Function yapılandırıcısını kullanarak fonksiyonlar oluşturabiliriz.

Kullanımı:
new Function([[Parametre1,[Parametre2,[...]]],[Fonksiyon Gövdesi]]);

Kullanımdan anlaşılacağı gibi ilk parametreler eğer varsa fonksiyon parametrelerinin adlarını tanımlıyor. Son kullanılan parametre ise fonksiyonun gövdesini string olarak bildirmek için kullanılıyor. Tabi parametreler yoksa doğrudan fonksiyon gövdesini tek parametre olarak yazabilirsiniz. Veya hiç parametre veya fonksiyon gövdesi kullanmadan da tanımlayabilirsiniz.

Parametreli örnek:

var toplama = new Function("sayi1", "sayi2", "return sayi1 + sayi2;");


console.log(toplama(3, 5));

Çıktısı:

8

Bu örnekte tanımlanan fonksiyon şununla aynıdır:
function toplama(sayi1, sayi2) {
	return sayi1 + sayi2;
}

console.log(toplama(3, 5));

Parametresiz örnek:

var mesajYaz = new Function("console.log('Merhaba.');");

mesajYaz();

Çıktısı:

Merhaba.

Bu örnekte tanımlanan fonksiyon şununla aynıdır:

function mesajYaz() {
	console.log("Merhaba.");
}

mesajYaz()

Function Nesnesinin Özellik ve Metotları

Function nesnesi bazı yararlı özellik ve metotlara sahiptir. Bir fonksiyonu fonksiyon bildirimi veya fonksiyon ifadesi olarak tanımladığınızda da bu özellik ve metotları kullanabilirsiniz.

Function.arguments Özelliği:

(Bu özellik eskimiş bir özelliktir. Bunun yerine JavaScript Fonksiyonlari: arguments Nesnesi makalemizde açıklanan arguments değişkenini kullanın. Ancak yine de bir çok tarayıcıda çalışır.)

Function.arguments  özelliği, fonksiyona gelen parametreleri tutan dizi şeklinde bir değerdir.

Örnek:
function deneme(a, b) {
    console.log(deneme.arguments[0]);
    console.log(deneme.arguments[1]);
    console.log(deneme.arguments[2]);
}

deneme(1, 2);

Çıktısı:

1
2
undefined

Örnekte fonksiyona 3. parametre gönderilmediğinden  arguments[2]  , undefined  olmuştur.

Function.caller Özelliği:


(Bu özellik standart değildir ve standarda eklenecek özellikler listesinde de yer almamaktadır.)

caller özelliği fonksiyonu çağıran fonksiyonun referansını döndürür.

Örnek:

function deneme2() {
    console.log(deneme2.caller);
}
function deneme() {
    console.log(deneme.caller);
    deneme2();
}

deneme();

Çıktısı:

null
deneme()

Örnekte deneme fonksiyonu çağırılıyor, bu fonksiyon içinden de deneme2 fonksiyonu çağırılıyor. Her iki fonksiyon içinden de kendilerini çağıran fonksiyonları çıktıya yazmaları isteniyor. Çıktıda görüldüğü gibi deneme fonksiyonu herhangi bir fonksiyon içinden çağırılmadığı için callernull döndürülüyor.

Bazı tarayıcılarda deneme() şeklinde bir çıktı yerine yerine fonksiyonun tamamını da görebilirsiniz.

Function.length Özelliği:


Bu özellik, fonksiyona gelmesi beklenen / fonksiyon tanımında belirtilen özellik sayısını döndürür.

Örnek:

function deneme(a, b, c) {
    console.log(deneme.length);
}

deneme(1, 2);

Çıktısı:

3

Örnekte görüldüğü gibi beklenen / bildirilen parametre sayısı veriliyor. Gönderilen parametre sayısı değil.

Function.displayName Özelliği:

(Bu özellik standart değildir ve standarda eklenecek özellikler listesinde de yer almamaktadır.)

Bu özellik bir fonksiyona atandığında, konsol veya JavaScript durum izlemelerinde (profiler) fonksiyon bu isimle gösterilir.

Örnek:
function deneme() {
	console.log(deneme.displayName);
}

deneme()
deneme.displayName = "Deneme Fonksiyonu";
deneme();

Çıktısı:

undefined
Deneme Fonksiyonu

Function.name Özelliği:

Referansı verilen fonksiyonun adını döndürür.

Örnek:

function deneme() { } // Bir fonksiyon bildirimi

var f = function () { }; // Bir fonksiyon ifadesi (anonim, isimsiz)

var testF = function test() { }; // İsimli bir fonksiyon ifadesi

var nesne = {
    birFonksiyon: function () { } // Bir nesne içinde fonksiyon ifadesi.
    ,
    baskaFonksiyon: function baska() { } // Bir nesne içinde isimli fonksiyon ifadesi.
}

console.log(deneme.name);
console.log(f.name);
console.log(testF.name);
console.log(nesne.birFonksiyon.name);
console.log(nesne.baskaFonksiyon.name);
Çıktısı:

deneme
(an empty string)
test
(an empty string)
baska

Görüldüğü gibi bir nesne içinde veya dışında tanımlanmış fonksiyon ifadelerinde eğer isim tanımlanmışsa (örnekte test) isim döndürülüyor, aksi halde boş bir string döndürüyor.

((an empty string) ifadesi, Firefox hata ayıklayıcıda çıktının boş bir metin olduğunu bildiriyor.)

Eğer Edge tarayıcısında aynı örneği denerseniz, çıktı:

deneme

test
birFonksiyon
baska

şeklinde olacaktır (deneme metninden sonra bir boş satır var).

Function.prototype.call Metodu:


Bu yöntem, bir fonksiyonu çalıştırmak için kullanılır.

Kullanımı:

call(thisParametresi[,Parametre1[,Parametre2,[...]]]);

Bu kullanımdaki thisParametresi ile belirtilen ilk parametre, bir nesnenin kapsamını çağırılan fonksiyona geçirmek için kullanılır. Sonraki parametreler, fonksiyona gönderilecek parametrelerdir.

Örnek:
function tamAdOlustur(adi, soyadi) {
    this.tamAdi = adi + " " + soyadi;
}

function Kisi(adi, soyadi) {
    this.adi = adi;
    this.soyadi = soyadi;
    tamAdOlustur.call(this, adi, soyadi);
}

var ogretmen = new Kisi("Ahmet", "Geçe");

console.log(ogretmen.tamAdi);

Çıktısı:

Ahmet Geçe

Örnekte Kisi isimli yapılandırıcı fonksiyon içinden çağırılan tamAdOlustur fonksiyonu doğrudan değil call metodu ile çağırılmıştır. call yönteminde gönderilen ilk parametre olan this, oluşturulan örneğin kapsamını tamAdOlustur fonksiyona geçmektedir. Bundan dolayı tamAdOlustur fonksiyonunun içinde sanki Kisi fonksiyonunun içindeymiş gibi this kullanılabilmekte ve oluşturulan örneğin (nesnenin) tamAdi özelliğine bir değer atanmaktadır.

Örnek 2:

function Urun(adi, fiyati) {
	this.adi = adi;
	this.fiyati = fiyati;
}

function Giyecek(adi, fiyati) {
	Urun.call(this, adi, fiyati);
	this.kategori = "Giyecek";
}

function Yiyecek(adi, fiyati) {
	Urun.call(this, adi, fiyati);
	this.kategori = "Yiyecek";
}

var elma = new Yiyecek("Elma", 4);
var pantolon = new Giyecek("Pantolon", 44);

Bu örnekte Urun  fonksiyonu, ortak özellikleri olan sınıflar için bu özelliklerle sınırlı olmak şartıyla bir ortak yapılandırıcı olarak kullanılıyor.

Bir nesne içinde tanımlanan fonksiyonu da nesneAdi.fonksiyonAdi.call şeklinde çağırabilirsiniz.

call metoduna gönderilen thisParametresi , eğer null veya undefined olursa global nesne ile (web sayfalarında window nesnesi) değiştirilir. Bu değer eğer temel tiplerden birisi olursa, örneğin bir sayı gönderirseniz, gönderilen değer nesneye dönüştürülür.

Function.prototype.apply Metodu:

Bu metot call ile aynı işi yapar.

Kullanımı:

apply(thisParametresi[,parametreDizisi]);

Görüldüğü gibi call ile aralarındaki fark parametrelerin bir dizi olarak gönderilmesidir. Bu, Function.arguments özelliği ve JavaScript Fonksiyonlari: arguments Nesnesi  makalemizde açıkladığımı arguments değişkeni ile beraber kullanıldığında kolaylık sağlar.

Birinci call örneğini apply ile yapalım:
function tamAdOlustur(adVeSoyadDizisi) {
    this.tamAdi = adVeSoyadDizisi[0] + " " + adVeSoyadDizisi[1];
}

function Kisi(adi, soyadi) {
    this.adi = adi;
    this.soyadi = soyadi;
    tamAdOlustur.apply(this, [adi, soyadi]);
}

var ogretmen = new Kisi("Ahmet", "Geçe");

console.log(ogretmen.tamAdi);

Çıktısı:

Ahmet Geçe

İsimsiz bir fonksiyonu call veya apply ile çağırmak isterseniz fonksiyonu parantez içine alın.

Örnek:

(function(a, b) { return a * b; }).call(this, 3, 5);

Function.prototype.bind Metodu:

bind metodu, çağırıldığında, fonksiyonun içinde kullanılacak this değeri belirtilen bir nesne veya fonksiyon kapsamı olan bir fonksiyon döndürür. Daha sonra bu dönen fonksiyonu kullanarak fonksiyonu istediğimiz nesnenin veya fonksiyonun kapsamında çalıştırabiliriz. Yeni fonksiyon içinde kullanılan this, bizim belirttiğimiz nesne veya fonksiyon kapsamına işaret eder.

Kullanımı:

bind(thisParametresi[,Parametre1[,Parametre2,[...]]]);

Bu metodun kullanımı görüldüğü gibi call metodu ile aynı, apply metodu ile benzerdir (apply'de thisParametresi zorunlu değil). bind metodunun call  ve apply'den farkı bir fonksiyon döndürmesidir. call ve apply ise fonksiyonu çalıştırırlar.

Örnek:

var genislik = 10;
var sekil = {
    genislik: 3,
    genislikYaz: function () { console.log(this.genislik) }
}

sekil.genislikYaz(); // 3 yazar

var genislikYazFonksiyonu = sekil.genislikYaz;
genislikYazFonksiyonu(); // 10 yazar

genislikYazFonksiyonu = sekil.genislikYaz.bind(sekil);
genislikYazFonksiyonu(); // 3 yazar

Çıktısı:

3
10
3

Örnekte nesne dışında tanımlanan genislik değişkeni (var genislik = 10 satırı) global nesne olan window nesnesinin bir özellik / değişken değeri olacaktır. Bir nesne veya yapılandırıcı bir fonksiyon içinde kullanılmayan thiswindow nesnesini işaret eder. Bu şekilde console.log(this.genislik)  yazmak window nesnesine bağladığımız genislik değişkeninin değerini yazacaktır.

sekil  nesnesinin genislikYaz  yöntemi çağırıldığında (sekil.genislikYaz()   şeklinde)  console.log(this.genislik)  ifadesi, sekil nesnesinin genislik  değerini yani 3 değerini yazmaktadır. Ancak sekil.genislikYaz  fonksiyonunu bir değişkene atayıp çalıştırdığımızda sadece fonksiyonu atamış olduğumuzdan, bu değişken aracılığıyla fonksiyon çalıştırıldığında (ilk genislikYazFonksiyonu()  ifadesi) fonksiyon içindeki this , window  nesnesine işaret edeceğinden 10 değerini yazmaktadır.

İşte bu durumda nesne içindeki fonksiyonun referansını almak yerine, bind metoduyla thisParametresi olarak sekil nesnesini gönderip fonksiyonun bir kopyasını alarak çalıştırdığımızda fonksiyon içindeki this sekil nesnesine işaret etmekte ve 3 sonucunu almaktayız.

bind metoduna thisParametresi haricinde gönderilen parametre değerleri, dönen fonksiyonda sabitlenir ve atadığımız değişken vasıtasıyla fonksiyonu çağırdığımızda her zaman bu parametreler bind sırasında belirtiğimiz değerlere sahip olacaktır. Fonksiyonu, atandığı değişkeni kullanarak çağırırken bind sırasında bildirilmeyen parametreleri kullanabiliriz.

Örnek:
function parametreleriYaz(a, b, c, d) {
	console.log(a, b, c, d);
}

var parametreleriYazan = parametreleriYaz.bind(window, 1, 2);

parametreleriYazan(3, 4);

Çıktısı:

1 2 3 4

Görüldüğü gibi bind sırasında verilen 1 ve 2 parametrelerini parametreleriYazan değişkeni vasıtasıyla fonksiyonu çağırdığımızda belirtmedik. Diğer parametreleri bildirdik. bind ile dönen fonksiyonda, bind ile verilen parametre değerleri sabit olarak kabul edilir ve bu fonksiyonu sonradan çağırdığımızda varsayılan değer olarak kalıyorlar. Fonksiyonu çağırdığımızda verilen parametreler, bu parametrelerden sonraki parametreler olarak kabul edilir.

Function.prototype.isGenerator Metodu:


(Bu metod henüz standart olmamıştır.)

isGenerator metodu, fonksiyonun bir üretici fonksiyon (generator function, * ile tanımlanmış, yield kullanan fonksiyonlar) olup olmadığını test etmek için kullanılır. Üretici fonksiyonlar ileride açıklanacaktır.

Function.prototype.toSource Metodu:


(Bu metod henüz standart olmamıştır.)

toSource metodu, bir nesnenin kaynak kodunu string  olarak döndürür. Fonksiyonlar da birer nesne olduğundan bu metot ile fonksiyonun kaynak kodunu string olarak elde edebiliriz. Ancak yerleşik fonksiyonlarda fonksiyonunun yerleşik kod (native code) olduğunu bildiren bir string alırız.

Örnek:

function deneme(a, b) {
    console.log(a, b);
}

var nesne = {
    x: 10,
    yaz: function() { console.log(this.x) }
};

console.log(deneme.toSource());
console.log(nesne.toSource());
console.log(String.split.toSource()); // String.split yerleşik bir fonksiyondur.

Çıktısı:

function deneme(a, b) {
            console.log(a, b);
        }
({x:10, yaz:(function () { console.log(this.x) })})

function split() {
    [native code]
}

Function.prototype.toString Metodu:


toString metodu, nesnelerin string bir ifadesini verir. Eğer kullanılan nesne kendi tanımladığımız bir fonksiyon ise kaynağını string olarak alırız. Ancak yerleşik JavaScript fonksiyonları ve nesneler için fonksiyonun yerel kod olduğunu veya nesnenin tipini bildiren bir ifade ile karşılaşırız. Bu metodu fonksiyonun string halini almak için kullanabiliriz.

Örnek:
function deneme(a, b) {
	console.log(a, b);
}
var nesne = {
	x: 10,
	yaz: function() { console.log(this.x) };
};
console.log(deneme.toString());
console.log(nesne.toString());
console.log(String.split.toString()); // String.split yerleşik bir fonksiyondur.

Çıktısı:

function deneme(a, b) {
            console.log(a, b);
        }
[object Object]

function split() {
    [native code]
}



JavaScript Fonksiyonları ile İlgili Makaleler: