2015-01-01 193 views
1

爲什麼this.name返回undefined?爲什麼this.name未定義?

function EventEmitter() { 
    var events = {}; 
    this.name = "Google" 
    this.on = function(name, fn) { 
    events[name] = events[name] || []; 
    events[name].push(fn); 
    } 
    this.trigger = function(name, args) { 
    events[name] = events[name] || []; 
    args = args || []; 
    events[name].forEach(function(fn) { 
     fn.apply(this, args); 
    }); 
    } 
} 

var my_event_emitter = new EventEmitter(); 
my_event_emitter.on('curtain_dropped', function() { 
    console.log(this.name); 
}); 
my_event_emitter.trigger('curtain_dropped', [true]); 

當我打電話fn.apply(this, args)EventEmitterthis不是實例是my_event_emitter

回答

3

的forEach都有自己的內容。使用的3種方式之一新的上下文綁定,如:

events[name].forEach(function(fn) { 
    fn.apply(this, args); 
}.bind(this)); 

您也可以通過(如2對Arg的的forEach)上下文。回調的參數是(value,index,originalArray,context);

events[name].forEach(function(fn) { 
    fn.apply(this, args); 
},this); 
+1

有時'bind'不是最好的選擇。關閉比「綁定」更好。無論如何,這是一種可能的方法,它會起作用! –

+0

你能否告訴我如何通過修改示例將上下文作爲第四個參數傳遞給我。 – Shane

+0

當然,請參閱編輯。 –

2

否; this是您的forEach回調被調用的上下文。
默認情況下,這是全局對象。

你需要第二個參數傳遞給forEach()告訴它應該在其回調什麼this

2

由於下面的代碼行:

events[name].forEach(function(fn) { 
    fn.apply(this, args); 
}); 

當你調用apply,你給錯了this參考,因爲你是forEach閉包內。

如果你想提供thisEventEmitter實例的引用,您需要將其存儲在一個變量,並使用它的閉包:

function EventEmitter() { 
    var events = {}; 
    var that = this; // <-- Current instance reference! 
    this.name = "Google" 
    this.on = function(name, fn) { 
    events[name] = events[name] || []; 
    events[name].push(fn); 
    } 
    this.trigger = function(name, args) { 
    events[name] = events[name] || []; 
    args = args || []; 
    events[name].forEach(function(fn) { 
     fn.apply(that, args); // Provide "that" instead of "this" 
    }); 
    } 
}