2015-07-02 44 views
6

Bu sormak için garip bir soru, ama NodeJS'yi öğreniyorum ve bir sorum var. Java'da bir nesneden bir yöntem çağırdığımda, this örneği aynı kalır (bu örnekte olduğu gibi).nodejs - Bu "bu" nedir?

Bu, doğruyu döndürür (teoride, bu benim başımın üst kısmındaki koddur). Ancak, NodeJS'de benzer bir şey yapmaya çalıştığımda başarısız olur.

var MyObject = function() { 
    this.other = new OtherObject(); 
    this.other.on("error", this.onError); 
    console.log(this); //This returns the MyObject object 
} 

MyObject.prototype.onError = function (e) { 
    console.log(this); //This returns the OtherObject object, where I thought it would return the MyObject object. 
} 

sorum neden bu kadar ve bu benim parçası yanlış yapılıyor eğer, nasıl doğru onError yönteminden MyObject örneğinde diğer değişkenleri referans verebilir mi?

+0

AFAIK, 'JavaScript içinde this' oldukça zordur. Fonksiyon olarak çağrıldığında, tanımlanan fonksiyonun nerede olduğu değil, arayan kişiye işaret eder. – walther

+1

@ walther - * bu * javascript'te hiç de zor değildir. Bu çağrı veya * bind * kullanımı ile ayarlanır, bu kadar. Diğer dillerden farklı olsa da, anlamak gerçekten zor değil. – RobG

+0

@RobG, bu kesinlikle zor kısmıdır - diğer diller bunu farklı yapar ve bazı geliştiricilerin cehennemi karıştırır. Gerçekten açık olsaydı, böyle bir soru asla ortaya çıkmazdı (ve bu ilk ve son zaman değil). – walther

cevap

6

JavaScript'te "yöntemler" yalnızca bir nesnenin parçası olarak işlev görür.

size karşı this.onError geçiyoruz harf içinde yerine

(o çağrılır nesne olduğu için) obj nesnesi olacak OnError içinde

var obj = new MyObject(); 
obj.onError(); 

Bunu yaparsanız EventEmitter bu fonksiyonu EventEmitter (OtherObject) ile çağırır.

Bu sorunu önlemek için anonim işlevi kullanın. Eğer nesneye bu geri bağlayıcı Bu şekilde

var MyObject = function() { 
    var self = this; 
    this.other = new OtherObject(); 
    this.other.on("error", function (e) { self.onError(e); }); 
} 

daha basit bir yolu yoktur

+1

Bunu çok iyi açıkladığınız için ve harika kullanım örneği için teşekkür ederiz! – duper51

+1

Daha da temiz bir çözüm için bağlama yöntemi https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind – B3rn475

+0

@RobG'yi kullanın. Bu arada sabit – B3rn475

0

bekliyoruz - Eğer bağlama işlevini kullanabilirsiniz.

var EventEmitter = require('events').EventEmitter; 

var MyObject = function() { 
    this.other = new EventEmitter(); 
    this.other.on("error", this.onError.bind(this)); 
    console.log(1, this instanceof MyObject); // 1, true 
}; 

MyObject.prototype.onError = function (e) { 
    console.log(2, this instanceof MyObject); // 2, true 
}; 

MyObject.prototype.callError = function (e) { 
    console.log(3, this instanceof MyObject); // 3, true 
    this.other.emit('error', e); 
}; 

var mo = new MyObject(); 

mo.callError(new Error(1)); 

Demo