可能重复:
If Javascript has first-class functions, why doesn’t this work?
当我尝试为document.getElementById
创建别名函数时,如下所示:
f = document.getElementById;
但是,当我试着打电话时:
var e_fullname = f(“fullname”);
出现错误:Could not convert JavaScript argument
以下就可以了:
var e_fullname = f.call(document, “funname”);
你能告诉我为什么吗?
答案 0 :(得分:24)
调用函数有四种方法:
f(p1, p2)
obj.f(p1, p2)
f.apply(obj, [p1, p2])
,f.call(obj, p1, p2)
new f(p1, p2)
在所有这些情况下,f
只是函数对象(具有[[Call]]
内部属性的对象)的引用(指针)。在所有这些情况下它的行为不同的是调用函数的方式,这很重要。
因此,f
只是对getElementById
对象的引用,document.getElementById
和someOtherHTMLElement.getElementById
之间没有区别;该函数不会阻止对引用它的对象的引用。
如果要绑定某个“所有者”对象,请使用bind
方法:
var f = document.getElementById.bind(document);
答案 1 :(得分:6)
getElementById
是文档上的方法。要调用它,解释器需要具有函数体本身,调用它的对象(在您的情况下为文档)和参数。
执行f = document.getElementById
时,您正在复制函数体,而不是要调用它的对象。
执行此操作时:
f.call(document, “funname”);
你提供了调用它的对象和参数。
如果你想能够直接调用f,你需要以某种方式获取存储在那里的“文档”对象。最简单的是:
var f = function(name){return document.getElementById(name)}
这会创建一个闭包,它为您保留文档的值。
您也可以使用bind()来做同样的事情。
答案 2 :(得分:1)
您可以使用bind
创建一个新函数,在调用时,将其关键字设置为 提供的值,在任何前面有给定的参数序列 在调用新函数时提供。
var f = document.getElementById.bind(document);
它是在ES5中引入的,因此请注意尚未支持此版本ECMAScript的浏览器!
作为替代方案,您可以使用jQuery的proxy
方法,在1.4
版本中添加
var f = $.proxy(document.getElementById, document);
或者你可以将f
作为其自身的功能(这是一个更详细的解决方案)。
var f = function() { return document.getElementById(arguments); }