mannaxxx 1
mannaxxx
Agora Metin2 1
Agora Metin2
[DEV]AB 1
[DEV]AB
Sevdamsın 1
Sevdamsın
TuZaKK 1
TuZaKK
kaptanmikro1 1
kaptanmikro1
farkmt2official 2
farkmt2official
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
Bvural41 1
Bvural41
Hikaye Ekle

[NODE JS] Node.js'te this Baglamini Anlamak

Türkiye'de ilk Mobil & PC Aynı Anda Metin2 Oyna. Triarchonline kalıcı ve uzun ömürlü yapısı ile 24 Temmuz'da açılıyor. | 1-99 Mobil Metin2 Triarch HEMEN TIKLA!

nodejs.png


[NODE JS] Node.js'te this Baglamini Anlamak​


Selam arkadaslar, bugun JavaScript'in en kafa karistirici konularindan biri olan this baglamini Node.js perspektifinden inceleyecegiz. this konusu yillardir gelisitiricilerin kabusu olmustur ve ben de dahil bir cok kisi bu yuzden saatlerce debug yapmistir. Ama bir kere mantigi oturduktan sonra aslinda cok net kurallara dayanan bir sistem oldugunu gorursunuz.

Node.js'te this Nereye Isaret Eder?​


Tarayicida en ust seviyede this, window nesnesine isaret eder. Node.js'te ise durum farklidir. Bir modulun en ust seviyesinde this, module.exports nesnesine isaret eder (ki baslangicta bos bir nesnedir). Bu tarayicidakinden farkli bir davranistir ve yeni baslayanlar icin kafa karistirici olabilir.

Fonksiyonlarin icinde this'in ne olacagi, fonksiyonun nasil cagrildigina baglidir, nerede tanimlandigina degil. Bu kural cok onemli, tekrar edeyim: this fonksiyonun nerede yazildigina degil, nasil cagrildigina bakar. Bu kurali ezberleyin cunku this ile ilgili tum sorunlarin cozumu bu kuraldan gelir.

JavaScript:
// Node.js'te this - modül seviyesi
console.log('=== Modul Seviyesinde this ===');
console.log('this === module.exports:', this === module.exports); // true
console.log('this === global:', this === global); // false

// Fonksiyon icinde this
console.log('\n=== Fonksiyon Icinde this ===');

function normalFonksiyon() {
    // Strict mode olmadan: global
    // Strict mode ile: undefined
    console.log('Normal fonksiyon this:', this === global ? 'global' : this);
}

normalFonksiyon();

// Arrow function icinde this
const arrowFonksiyon = () => {
    // Arrow function kendi this'ini olusturmaz
    // Disaridaki this'i kullanir (lexical this)
    console.log('Arrow fonksiyon this:', this === module.exports ? 'module.exports' : this);
};

arrowFonksiyon();

// Nesne metodu olarak this
const kullanici = {
    ad: 'Ahmet',
    selamla: function() {
        console.log('\nNesne metodu this.ad:', this.ad); // 'Ahmet'
    },
    selamlaArrow: () => {
        console.log('Arrow metodu this.ad:', this.ad); // undefined!
    }
};

kullanici.selamla();
kullanici.selamlaArrow(); // DIKKAT: Arrow function'da this nesneyi gostermez!

// Metodu baska degiskene atamak
const bagsiSelamlama = kullanici.selamla;
// bagsiSelamlama(); // this kaybedilir! 'undefined' veya hata

// bind ile this baglamak
const bagliSelamlama = kullanici.selamla.bind(kullanici);
bagliSelamlama(); // Calisir! this hala kullanici nesnesi

this Sorunlari ve Cozumleri​


Node.js'te this ile en cok karsilasilan sorunlar callback'lerde, event handler'larda ve class metotlarinda yasanir. Bir sinifin metodunu callback olarak gecirdiginizde this baglami kaybolur. Bu cok yaygin bir hata ve ben bunu duzeltmek icin saatler harcadim.

JavaScript:
const EventEmitter = require('events');

// SORUN: Class metodunda this kaybetme
class Sunucu extends EventEmitter {
    constructor(port) {
        super();
        this.port = port;
        this.istekSayisi = 0;
    }

    // YANLIS: Normal fonksiyon callback'te this kaybolur
    baslat_yanlis() {
        // setTimeout icinde this kaybedilir
        setTimeout(function() {
            // console.log(this.port); // HATA! this artik Sunucu degil
        }, 100);
    }

    // DOGRU Yol 1: Arrow function kullan
    baslat_dogru1() {
        setTimeout(() => {
            console.log('Arrow ile port:', this.port); // Calisir!
        }, 100);
    }

    // DOGRU Yol 2: bind kullan
    baslat_dogru2() {
        setTimeout(function() {
            console.log('Bind ile port:', this.port);
        }.bind(this), 100);
    }

    // DOGRU Yol 3: self/that pattern (eski yontem)
    baslat_dogru3() {
        const self = this;
        setTimeout(function() {
            console.log('Self ile port:', self.port);
        }, 100);
    }

    // Event handler'da this
    eventOrnek() {
        // YANLIS
        // this.on('istek', this._istekIsle);
        // _istekIsle icinde this kaybedilir

        // DOGRU 1: Arrow function wrapper
        this.on('istek', (data) => this._istekIsle(data));

        // DOGRU 2: bind
        this.on('istek', this._istekIsle.bind(this));
    }

    _istekIsle(data) {
        this.istekSayisi++;
        console.log(`Istek #${this.istekSayisi}: ${data.yol}`);
    }
}

// Class field syntax (modern yaklasim)
class ModernSunucu {
    port = 3000;
    istekSayisi = 0;

    // Arrow function class field - this her zaman dogru!
    istekIsle = (data) => {
        this.istekSayisi++;
        console.log(`Modern istek #${this.istekSayisi}: ${data.yol}`);
    };

    baslat = () => {
        console.log(`\nModern sunucu ${this.port} portunda`);
    };
}

// Test
const sunucu = new Sunucu(3000);
sunucu.baslat_dogru1();

const modern = new ModernSunucu();
modern.baslat();

// Callback olarak gecirme - modern yaklasimda sorun yok
const fn = modern.istekIsle;
fn({ yol: '/api/test' }); // this dogru!

call, apply ve bind​


this baglamini kontrol etmek icin uc fonksiyon vardir: call, apply ve bind. call fonksiyonu hemen cagirirken this'i ayarlar ve argumanlari tek tek verir. apply de hemen cagirirken this'i ayarlar ama argumanlari dizi olarak verir. bind ise yeni bir fonksiyon dondurur ve this baglamini kalici olarak ayarlar. Ben genelde bind kullaniyorum cunku geri dondugu fonksiyonu daha sonra kullanabilirsiniz.

Tecrübeme gore this sorunlarindan kacmanin en kolay yolu arrow function kullanmaktir. Arrow function kendi this'ini olusturmaz, disaridaki this'i miras alir. Bu davranis callback'lerde, event handler'larda ve promise then'lerinde hayat kurtaricidir. Modern JavaScript'te artik neredeyse her yerde arrow function kullanabilirsiniz. Tek istisna nesne metotlari ve prototype metotlari, bunlarda normal fonksiyon kullanmaniz gerekir. Hadi sonraki konuya gecelim!
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst