Javascript 存储对'call'函数的引用
今天早些时候我注意到一些奇怪的事情。我似乎无法存储对函数的Javascript 存储对'call'函数的引用,javascript,Javascript,今天早些时候我注意到一些奇怪的事情。我似乎无法存储对函数的call属性的引用,然后执行它。例如: var log = console.log; log.call(console, 'This works'); var logCall = console.log.call; logCall(console, 'This does not'); 对我来说,这似乎是完全合法的Javascript,但第二次调用总是给我一个错误,即undefined不是一个函数。随便玩玩吧,你会得到同样的结果 那么
call
属性的引用,然后执行它。例如:
var log = console.log;
log.call(console, 'This works');
var logCall = console.log.call;
logCall(console, 'This does not');
对我来说,这似乎是完全合法的Javascript,但第二次调用总是给我一个错误,即undefined不是一个函数。随便玩玩吧,你会得到同样的结果
那么为什么Javascript阻止我以这种方式调用call
编辑:读了SimpleJ的答案后,我终于明白了。因此,我将更新这篇文章,介绍如何让上述内容发挥作用:
var log = console.log;
log.call(console, 'This works');
var logCall = console.log.call;
logCall.call(console.log, console, 'This works now too');
问题是console.log
接收到了正确的此
值,但是console.log.call
没有得到正确的此
值。如您所见,我基本上必须执行console.log.call.call
。很明显,您从未真正使用过这样的代码,我只是好奇。您需要保留与控制台的绑定。试试这个:
var logCall = console.log.call.bind(console.log);
// example: logCall(console, "foobar");
或
有关日志的绑定引用
编辑:
jsiddle:您需要保留与控制台的绑定。试试这个:
var logCall = console.log.call.bind(console.log);
// example: logCall(console, "foobar");
或
有关日志的绑定引用
编辑:
JSFIDLE:这是我最喜欢的JavaScript代码:
var bind = Function.bind;
var call = Function.call;
var bindable = bind.bind(bind);
var callable = bindable(call);
您可以使用bindable
函数获取对f.bind
的引用。类似地,您可以使用callable
函数获取对f.call的引用,如下所示:
var log = callable(console.log, console);
现在,您只需像调用任何其他函数一样调用log
函数:
log("Hello World!");
这是我最喜欢的JavaScript代码:
var bind = Function.bind;
var call = Function.call;
var bindable = bind.bind(bind);
var callable = bindable(call);
您可以使用bindable
函数获取对f.bind
的引用。类似地,您可以使用callable
函数获取对f.call的引用,如下所示:
var log = callable(console.log, console);
现在,您只需像调用任何其他函数一样调用log
函数:
log("Hello World!");
这就是所有的人。当您在变量中存储console.log.call时,它丢失了对console.log的引用,这意味着它不再知道在什么上执行参数。我预计您的第一个示例在某些浏览器中会失败,因为它与此
的工作方式有关(取决于所使用的浏览器如何定义console.log):。由于您正在“正常”调用函数(logCall()
),此
要么指向窗口
,要么是未定义的
<代码>函数.prototype.call
不知道要对哪个函数执行操作。是的。两个示例都不适用于ChromeFW,第一个示例适用于Chrome35。编辑:嗯,jsBin是有效的,但是如果我直接在控制台中执行它,jsBin就不起作用了“那么为什么Javascript阻止我以这种方式调用调用?”再次,了解这个是如何工作的:。这是一个非常常见的问题,有一个简单的解释。当您在变量中存储console.log.call时,它丢失了对console.log的引用,这意味着它不再知道在什么上执行参数。我预计您的第一个示例在某些浏览器中会失败,因为它与此
的工作方式有关(取决于所使用的浏览器如何定义console.log):。由于您正在“正常”调用函数(logCall()
),此
要么指向窗口
,要么是未定义的
<代码>函数.prototype.call
不知道要对哪个函数执行操作。是的。两个示例都不适用于ChromeFW,第一个示例适用于Chrome35。编辑:嗯,jsBin是有效的,但是如果我直接在控制台中执行它,jsBin就不起作用了“那么为什么Javascript阻止我以这种方式调用调用?”再次,了解这个是如何工作的:。这是一个非常常见的问题,有一个简单的解释。我的想法是一样的,但是当您尝试运行它时,这会产生TypeError:invally invocation
。。这是因为它是绑定调用。call
的第一个参数是一个上下文,应该是console
@SimpleJ:如果在console.log
上调用了.bind
,那么您是对的。但是它是在console.log.call
上调用的。要使它在任何地方都能工作,您可能需要编写console.log.call.bind(console.log,console)
@FelixKling我想他是想引用call
而不是log
。我的想法是一样的,但当您试图运行它时,这会产生TypeError:invalical调用
。。这是因为它是绑定调用。call
的第一个参数是一个上下文,应该是console
@SimpleJ:如果在console.log
上调用了.bind
,那么您是对的。但是它是在console.log.call
上调用的。要使它在任何地方都能工作,您可能需要编写console.log.call.bind(console.log,console)
@FelixKling我想他是想引用call
而不是log
。“callable(console.log,console);”比“console.log.bind(console);”更好吗?别忘了:@dandavis:即使console.log
不是函数
实例(在IE DOM中可能会发生这种情况),它也会起作用,但你是对的-它只是更令人困惑。@dandavis在5行代码中,你有三个有用的函数-bindable
,callable
和log
。此外,我觉得callable
函数比object.method.bind(object)
更具描述性。对我来说,这看起来很难看。“callable(console.log,console);”怎么比“console.log.bind(console);”更好呢?别忘了:@dandavis:即使console.log
不是函数
实例(在IE DOM中可能会发生这种情况),它也能工作,但是你是对的,这只会让人更困惑。@dandavis在5行代码中,你得到了三个有用的函数-bindable
、callable
和log
。此外,我觉得可调用