如果 JavaScript 有一流的函数,为什么在变量中调用这个函数不起作用?

IT技术 javascript
2021-01-31 02:47:33

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

var f = document.getElementById;
var x = f('x');

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

为什么?

3个回答

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

但是,如果您只是编写,f = document.getElementById您现在有一个对该函数的新引用,但该引用不再“绑定”到document.

所以你的代码不起作用,因为当你f作为一个裸函数名调用时,它最终绑定到全局对象 ( window)。一旦函数的内部结构尝试使用this它,它就会发现它现在有 awindow而不是 adocument并且不出所料它不喜欢它。

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

var x = f.call(document, 'x');

它调用f但明确地将上下文设置为document.

解决此问题的其他方法是使用Function.bind()ES5 及更高版本中可用的方法:

var f = document.getElementById.bind(document);

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

function f(id) {
    return document.getElementById(id);
}

因为在 JavaScript 中,函数没有绑定到上下文 ( this)。您可以使用bind()

var f = document.getElementById.bind(document);
为了澄清这个答案,thisin document.getElementById()is document,而this您执行范围的位置是全局范围,也this就是window对象。
2021-04-07 02:47:33

使用 ES6 的扩展运算符,您还可以尝试:

function f(){
    return document.getElementById(...arguments);
};

巴贝尔给出了这个:

function f() {
    var _document;
    return (_document = document).getElementById.apply(_document, arguments);
};