JavaScript 据称具有一流的功能,所以这似乎应该可以工作:
var f = document.getElementById;
var x = f('x');
但它在所有浏览器上都失败了,每个浏览器都有不同的神秘错误消息。Safari 显示“类型错误”。Chrome 显示“非法调用”。Firefox 提示“无法转换 JavaScript 参数”。
为什么?
JavaScript 据称具有一流的功能,所以这似乎应该可以工作:
var f = document.getElementById;
var x = f('x');
但它在所有浏览器上都失败了,每个浏览器都有不同的神秘错误消息。Safari 显示“类型错误”。Chrome 显示“非法调用”。Firefox 提示“无法转换 JavaScript 参数”。
为什么?
当您obj.method()
在 Javascript 中调用时,该方法将obj
作为this
. document.getElementById('x')
因此调用设置this
为document
。
但是,如果您只是编写,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);
使用 ES6 的扩展运算符,您还可以尝试:
function f(){
return document.getElementById(...arguments);
};
巴贝尔给出了这个:
function f() {
var _document;
return (_document = document).getElementById.apply(_document, arguments);
};