简体   繁体   English

使用数组中的参数调用函数 - apply()而不使用上下文参数?

[英]Call function with parameters from array - apply() without the context parameter?

Is there any method that invokes a function but sets the context this to the "default" value that it has when I invoke the function by doing fn() ? 是否有一个调用的功能,但将上下文的任何方法this为“默认”值,它具有当调用通过执行函数fn()

This method should accept an array and pass the single elements as arguments to the function, much like apply() does: 这个方法应该接受一个数组并将单个元素作为参数传递给函数,就像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);

EDIT: To clarify this, I do care about the value that this will have inside the called function - it needs to be the "normal" context it has when doing emitter.emit() , not the global object or anything else. 编辑:为了澄清这一点,我不关心这个值this将有调用的函数里面-它必须是“正常”的情况下这样做时,它具有emitter.emit()而不是全局对象或其他任何东西。 Otherwise, this will break things sometimes. 否则,这有时会破坏事情。

You can pass null or undefined if you don't care about the context. 如果您不关心上下文,则可以传递nullundefined Inside the function, this will then refer to the global object when in non-strict mode and to null respectively undefined in strict-mode . 在函数内部, this 会再是指全局对象时,在非严格模式null分别undefined严格模式

A "default" context for a function is hard to define 函数的“默认”上下文很难定义

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

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

Which one of these is the "right" context? 其中哪一个是“正确”的背景?

In your case you might consider a utility function 在您的情况下,您可能会考虑实用功能

/* you might call it something else */
emitter.emit_all = function (event, args) {
    return this.emit.apply(this, [event].concat(args));
}

Just set the first parameter to the global object (ie window in a browser) 只需将第一个参数设置为全局对象(即浏览器中的window

In ES3 browsers you could pass null instead and it would be automatically be changed to the global object, but that behaviour has been removed in the ES5 specifications . 在ES3浏览器中,您可以传递null ,它会自动更改为全局对象,但在ES5规范中已删除该行为。


EDIT it sounds like you just need a new function: 编辑听起来你只需要一个新功能:

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

at which point you can just call: 在这一点上你可以打电话:

emitter.emitArgs('event', args);

( EDIT thanks to @Esalija for [].concat ) 编辑感谢@Esalija为[].concat

This is solved by the native Function "arguments" variable. 这由本机Function“arguments”变量解决。

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');

To maintain the "this" context you could bind the emit method in the constructor, though this would create per instance "own" object properties increasing memory consumption and practically perform all prototype chain lookups (for bound methods) on object creation regardless if you needed them or not. 要维护“this”上下文,你可以在构造函数中绑定emit方法,尽管这会创建每个实例“自己的”对象属性,增加内存消耗,并且实际上对对象创建执行所有原型链查找(对于绑定方法),无论您是否需要他们与否。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM