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
。此外,我觉得
可调用