如果JavaScript具有一流函数,为什么不在变量中调用此函数呢?

Lis*_*per 21 javascript

JavaScript据称具有一流的功能,所以这似乎应该是以下工作:

var f = document.getElementById;
var x = f('x');
Run Code Online (Sandbox Code Playgroud)

但它在所有浏览器上都失败了,每个浏览器都有不同的神秘错误消息.Safari说"类型错误".Chrome说"非法调用".Firefox说"无法转换JavaScript参数".

为什么?

Aln*_*tak 36

当您obj.method()使用Javascript 调用时,方法将obj作为this.document.getElementById('x')因此调用设置thisdocument.

但是,如果您刚刚写入f = document.getElementById,则现在有一个对该函数的新引用,但该引用不再"绑定" document.

因此,您的代码不起作用,因为当您f作为一个裸函数名称调用时,它最终绑定到全局对象(window).一旦函数的内部尝试使用this它,它发现它现在有一个window而不是一个document并且不出所料它不喜欢它.

可以f,如果你把它叫做这样的工作:

var x = f.call(document, 'x');
Run Code Online (Sandbox Code Playgroud)

哪些调用f但显式设置上下文document.

解决此问题的其他方法是使用Function.bind()仅在ES5中可用的方法:

var f = document.getElementById.bind(document);
Run Code Online (Sandbox Code Playgroud)

并且实际上只是创建自己的包装器的通用捷径,正确设置上下文:

function f(id) {
    return document.getElementById(id);
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*icz 21

因为在JavaScript函数中没有绑定到context(this).你可以使用bind():

var f = document.getElementById.bind(document);
Run Code Online (Sandbox Code Playgroud)

  • 为了澄清这个答案,`document.getElementById()`中的`this`是`document`,而你执行范围的`this`是全局范围,又称`this`是`window`对象. (4认同)