şükela:  tümü | bugün
  • ing. vinçle kaldırmak, çekmek, çıkarmak.
  • javascript'te fonksiyon ve değişken tanımlarının, interpreter tarafından kodun yukarısına taşınmasına verilen ad.

    myfunc();
    var x = 1;

    yazıldığında bu

    var x
    myfunc();
    x = 1

    oluyor. çok fazla bi kullanımı yok aslında, daha ziyade artist programcılar tarafından ilginç bulmacaların yazılmasına yarıyor.

    1. ne döndürür?
    (function f(){
    function f(){ return 1; }
    return f();
    function f(){ return 2; }
    })();

    2. ne alert edilir?
    if (!("a" in window)) {
    var a = 1;
    }
    alert(a);

    3. ne döner?
    var foo = 1;
    function bar() {
    if (!foo) {
    var foo = 10;
    }
    alert(foo);
    }
    bar();
  • ben yazıyorum ankara ekrana düşüyor götüm karacı yazılımcıların ara sıra kullanması gereken hede hüdü.
  • madencilikte "dikey nakliyat" anlamına gelir
  • js interpreter, initialization ve declaration'a farkli muamele uygular, soyle ki, hoisting, sadece declaration'lar icin gecerlidir.

    js interpreter, bir scope (misal function) icinde herhangi bir yerde var ile tanimlanmis fakat init'lenmemis bir degisken gorurse, bunu once basa alir (en tepeye), sonra kodu isler. yani kodu duzenler bir bakima. bu durumda, degiskenler, scope icinde herhangi bir yerde tanimlandiklari surece (tanimlandiklar derken declare edildikleri) kullanilabilirler. buna hoisting(kaldirmak, yukari almak) denir.

    ayni durum initialization icin gecerli degildir, yani scope'un en asagisinda

    var x = 5;

    seklinde bir initialization yapip, yukarida bir yerde x'i kullanirsaniz, x'in undefined olarak tanimlandigini gorursunuz.

    best practice, her zaman degiskenleri scope basinda declare etmekten gecer.
  • javascript'te bu çok yanlış anlaşılıyor.

    tanımladığınız değişkenlerin ve fonksiyonların üste taşınması gibi bir şey söz konusu değil, yapılan şey interpreter'ın önce tanımladığınız şeyler için "hafızada yer açması".

    yani mesela:

    console.log(sozluk)

    var sozluk = "ekşi olan"

    gibi bir kodu çalıştırdığınızda konsola "undefined" düşer zira js engine orada bir sozluk değişkeni olduğunu gördü ama yukarı taşımadığı için tanımlandığı satıra gelene kadar bir değere sahip olmaz.

    tabi bu değişkenler için geçerli, fonksiyonlara kodun herhangi bir yerinden erişebilirsiniz.
  • şu iki durum karıştırılmamalıdır:

    1. durum:

    a = 2;
    var a;
    console.log( a ); // 2

    2. durum:

    console.log( a ); // undefined
    var a = 2;
  • javascripti diger dillerden ayiran en onemli kavramlardan biridir. hoisting anlamak icin interpreter tarafindan bir javascript kod nasil okunur onu anlamak lazim. su sekilde bir kod blogumuz oldugunu dusunelim;

    console.log(a);
    var a = 2;
    function b(){};

    javascript interpreter boyle bir kod ile karsilastiginda bu kodu iki asamadan gecirecektir. "ınitialization" yani hazirlik asamasi, "execution" yani calistirma asamasi. bu her asamada kodun uzerinden satir satir yukaridan asagi iki kere gececektir. ıste "hoisting" bu iki tur sirasinda sanki tum degisken tanimlarini en yukari tasiyormus gibi bir iluzyon yaratir.

    peki ilk turdaki "ınitialization" yani hazirlik asamasi icin interpreter satir satir ne yapar? ılk turda derleyicinin aradigi sey "elimizde neler var?" sorusuna cevap bulmak, asla ve asla eylemlerle ve yapilacak isle ilgilenmez. ilk satirdaki "console.log(a)" ile karsilasinca umrunda olmaz, cunku burada bir fonksiyon cagirilmistir, yani "ben buyum" demek yerine bu satir bir eylem barindirir, "ekrana a degerini yaz" der. bu asamada interpreterin bu satir ile isi olmaz dogrudan bir sonraki satira gecer. bir sonraki satirda "var a = 2;" iste burada derleyicinin ilgisini ceken sey "var a" kismi ama esitligin diger tarafindaki "degiskene 2 degerini ata" eylemi ile de isi olmaz. tek ilgilendigi sey "var a". bunu gorur gormez hafizada bir yer acar, o yeri "a" adinda bir referans ile gosterir. referansin gosterdigi alani ise "undefined" degeri ile doldurur. artik elimizde bir adres var ama bos bir hafiza alanini gosteriyor demektir bu. bir sonraki satira gecer, bu satirda ilgilendigi tek kisim "function b" fonksiyon tanimlamasidir. hemen hafizada bu fonksiyon icin yer acar. ama fonksiyonlar icin farkli birsey yapar, hafiza alanini bos birakmak yerine icine fonksiyonu yerlestirir. tum satirlari dolastiktan sonra da bu ilk turu tamamlar, ikinci tura gecer.

    peki ikinci turdaki "execution" asamasinda bu interpreter ne yapiyor? en bastan tekrar baslar. sadece eylemlerle ilgilenir, artik is yapma zamani gelmistir. "console.log(a);" satirini gorunce hemen fonksiyonu cagirir ve cagirirken de fonksiyona "benim elimde'a' adinda bir referans var, git onun gosterdigi hafiza alaninda degeri al ve konsola bas" der. hemen gider "a" refeansinin gosterdigi hafiza alanina, bakar ve icinde "undefined" degerini gorur, konsola basar. iste burada a referansinin gosterdigi degeri basabilmesi, yani ilk asamada bu "a" referansini olusturmus olmasi sanki tum degisken tanimlarinin en uste tasindigi iluzyonu yaratir. bu durum icin "hoisting" yani "yukari cekme, kaldirma" kelimesi kullanilmasi da bu iluzyonda ve bu sekilde anlasilmasinda etkili olmustur elbette. daha sonra interpreter bir sonraki satira gecer "var a = 2;", bu satirda a referans degeri ve onun gosterdigi hafiza alani zaten ilk turda ayarlanmisti. ama bu turda interpreter bu hafiza alanina 2 degerini kaydeden esitlik fonksiyonunu calistirir. boylece a referansi ve gosterdigi alanda 2 var ama artik cok gec, cunku bu deger zaten bir onceki satirda "undefined" olarak basmis olduk, ve bir daha da basilmayacak. bir referans yani a referansina deger atanmadan, hatta a tanimlanmadan o degeri ekrana bastik ama hicbir hata almamis olsu. ekrana da basti ama "undefined" olarak. ıste bu "hoisting" olayinin anahtari. bir sonraki satirda fonksiyon tanimlamasi ile bu interpreter ikinci turuda ilgilenmez, ilk turda bunun icin tum hafiza alanlari acilmisti zaten.

    bu "hoisting" olayini anlamis olmak javascript programlama dili ile bilgisayar ile konusmanin disinda bilgisayarin hislerini dusuncelerini de anlamis olmak demektir. bilgisayarin hislerinden anlayan bir programci ise karmasik durumlarda cok daha iyi hata ayiklama yapar. cunku akisa tamamen hakim olmak, interpreter tarafindan saklanan o gizli mantigi biliyor olmak hem hatanin hem de gizli performans kayiplarinin kokusunu almayi saglar. ornegin javascript de bir fonksiyon yazmanin temelde iki yolu varidir, "function statement" ve "function expression".

    ornegin "function statement" ve "hoisting" ornegi yazarsak;

    b();
    function b(){};

    burada "b" fonksiyonu cagirildigi satir o fonksiyonun tanimlanmasindan once olmasina ragmen "hoisting" nedeniyle kodumuz gayet guzel calisacaktir. ama ayni kodu bir de farkli bicimde "function expression" ile yazarsak ne olur;

    b();
    var b = function(){};

    bu kodda "b is not a function" diye bir hata aliriz. cunku bu durumda fonksiyon bir objedir ve b referans degeri ile gosterilir. "hoisting" olayi da "b" referansini bir fonksiyonmus gibi degil de referans tarafindan gosterilen bir objeymis gibi ele alacaktir. yani b referansini yaratacak ama bu referansin gosterdigi alanda "undefined" olacaktir. peki bu "hoisting" olayinin guvenilmez durumu var da biz niye "function statement" yerine "function expression" kullaniyoruz? iste o konu cok daha genis bir odaya yani performans kismina aciliyor ve cok daha genis aciklamasi var.

    tum bunlar nedeniyle "hoisting" javascript gelistiriciler icin bilinmesinin yaninda iyice anlasilmasi gereken bir konu, cunku hem javascriptin temeli hem de bunu bilmeyen bir yazilimcinin kodu "function expression" kullandigi taktirde hataya acik olacaktir. ayni zamanda bu yazilimci yaptigi iste performansi ne sekilde etkiledigini bilmeyecektir. bu da iyi yazilimci ile sadece kod yazan ama aslinda bilgisayarin duygusundan dusuncesinden anlamayan yazilimciyi ayiran bir durumu ortaya koyar. bilgisayara sadece kodlarinizi derlesin diye yazmayin, o yazdiginiz kodlarin bilgisayara ne hissettirdigini, o kodu nasil okudugunu da anlamaya calisin ki daha kaliteli bir kod ortaya koyun.