2

是否有任何方法可以调用函数但将上下文设置为this当我调用函数时它具有的“默认”值fn()

这个方法应该接受一个数组并将单个元素作为参数传递给函数,就像 apply() 一样:

emitter = new EventEmitter();
args = ['foo', 'bar'];

// This is the desired result:
emitter.emit('event', args[0], args[1], ...);

// I can do this using apply, but need to set the context right
emitter.emit.apply(emitter, 'event', args);

// How can I trim the context from this?
emitter.emit.???('event', args);

编辑:为了澄清这一点,我确实关心this被调用函数内部的值 - 它需要是它在执行时具有的“正常”上下文emitter.emit(),而不是全局对象或其他任何东西。否则,这有时会破坏事情。

4

3 回答 3

5

null如果undefined你不关心上下文,你可以通过。在函数内部,将在非严格模式下this 引用全局对象,在严格模式null分别undefined引用。

函数的“默认”上下文很难定义

function f() { return this };
a = { b: f }
c = a.b;

console.log(f());   # window
console.log(a.b()); # a
console.log(c());   # window

其中哪一个是“正确”的上下文?

在您的情况下,您可能会考虑实用功能

/* you might call it something else */
emitter.emit_all = function (event, args) {
    return this.emit.apply(this, [event].concat(args));
}
于 2012-07-18T07:23:21.973 回答
4

只需将第一个参数设置为全局对象(即window在浏览器中)

在 ES3 浏览器中,您可以null改为传递,它会自动更改为全局对象,但该行为已在 ES5 规范中删除


编辑听起来你只需要一个新功能:

EventEmitter.prototype.emitArgs = function(event, args) {
    this.emit.apply(this, [event].concat(args));
}

此时您可以致电:

emitter.emitArgs('event', args);

编辑感谢@Esalija [].concat

于 2012-07-18T07:23:03.917 回答
0

这是由本机函数“参数”变量解决的。

var EventEmitter = window.EventEmitter = function(){
    //this.emit = this.emit.bind(this);//bind emit to "this"
    return this;
};
EventEmitter.prototype.isMe = function(obj){
    return obj === this;
};
EventEmitter.prototype.emit = function(eventName){
    var input = Array.prototype.slice.call(arguments, 1);
    console.log("this:%O, Emitting event:%s, with arguments:%O", this, eventName,input);
};

emitter = new EventEmitter();
emitter.emit('magicEvent', 'Zelda Con', 'Zork Meetup', 'etc');

为了维护“this”上下文,您可以在构造函数中绑定 emit 方法,尽管这会为每个实例创建“自己的”对象属性,从而增加内存消耗,并且实际上在对象创建时执行所有原型链查找(对于绑定方法),无论您是否需要他们与否。

于 2014-03-29T08:26:42.870 回答