JavaScript函数上下文不正确

时间:2015-06-02 11:59:34

标签: javascript

我注意到javascript中有一个奇怪的东西。请考虑以下内容:

var fn = ''.toUpperCase.call
console.log(typeof fn); // "function"
fn(); // Uncaught TypeError: `fn` is not a function

以上内容在我的Chrome开发者控制台上执行。版本为43.0.2357.81 m

typeof运算符清楚地表明fn是一个函数,但错误表明不是。

我注意到Function.apply至少显示了一些有意义的错误消息。

那么,什么时候是函数,而不是函数?

3 个答案:

答案 0 :(得分:19)

Javascript中的上下文总是通过调用函数的方式来建立。

var fn = ''.toUpperCase.call

这将call函数的原型实现分配给fn。如果您现在拨打fn(),则该呼叫没有上下文。 call将尝试调用与之关联的函数对象。但是,该上下文是在呼叫时建立的。由于您在通话时没有给它任何上下文,call的某些内部组件会抛出错误。

你必须这样做:

fn.call(''.toUpperCase)

是的,您call call函数,建立一个上下文,即toUpperCase字符串函数。在这种特定情况下,这将导致toUpperCase内的另一个错误,因为未绑定到特定上下文。您还需要明确地建立该上下文:

var fn = ''.toUpperCase.call
fn.call(''.toUpperCase.bind(''))

另见How does the "this" keyword work?

答案 1 :(得分:2)

deceze's answer是正确的,我只是想从不同的角度来解释它。

您的fn是对Function.prototype.call的引用,需要使用函数作为其this引用进行调用,在这种情况下,call的上下文为{{ 1}},通过String.prototype.toUpperCase

继承

最重要的是,''.toUpperCase也必须使用特定的上下文调用,字符串为大写。

以下是编写您想要的内容的另一种方法,可以帮助您了解正在发生的事情。



String.prototype.toUpperCase




在您的示例中, var str = 'aaa'; var upper = ''.toUpperCase; var fn = upper.call; // Now we have to specify the context for both upper and fn console.log( fn.call(function() { return upper.call(str)}) ); // AAA正在尝试调用fn(),但它未指定上下文,通常默认为call对象,但在这种情况下它只是它是window,它会在Chrome中触发一个奇怪的错误(正如您所发现的那样),但Firefox更清楚这个问题,

  

TypeError:在不兼容的未定义

上调用Function.prototype.call

答案 2 :(得分:1)

  

那么,什么时候是函数,而不是函数?

该函数是一个函数,但您没有正确执行它,如注释和@deceze的答案所述

  

我注意到javascript中有一个奇怪的东西。

您似乎对您在测试环境中获得的消息感到困惑,消息并不严格正确。

  

未捕获的TypeError:fn不是函数

当前稳定版本的chrome(我的linux安装上的40.0.2214.91,chrome无法在我的硬件上运行而不进行设置更改),chrome是您测试的环境,给出了一个看似更正确的错误消息感。

Uncaught TypeError: undefined is not a function

那么,你是在问/想要提出一个严肃的问题,还是只是在一个铬版本的错误中点了一点乐趣?