Функция псевдонима в javascript
Возможный дубликат:
Если Javascript имеет первоклассные функции, почему это не работает?
Когда я пытаюсь сделать функцию псевдонима для document.getElementById
, как показано ниже:
f = document.getElementById;
Но когда я пытаюсь позвонить:
var e_fullname = f("fullname");
Ошибка: Could not convert JavaScript argument
И ниже ОК:
var e_fullname = f.call(document, "funname");
Можете ли вы сказать мне, почему?
Ответы
Ответ 1
Существует четыре способа вызова функции:
- Вызов функции:
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);
Ответ 2
getElementById
- это метод документа. Чтобы вызвать его, интерпретатор должен иметь сам объект функции, объект для его вызова (документ в вашем случае) и аргументы.
Когда вы выполняете f = document.getElementById
, вы копируете тело функции, но не объект, чтобы вызвать его.
Когда вы это сделаете:
f.call(document, "funname");
Вы предоставляете как объект для его вызова, так и аргументы.
Если вы хотите иметь возможность напрямую звонить f, вам нужно каким-то образом получить объект "document". Самый простой способ:
var f = function(name){return document.getElementById(name)}
Это создает замыкание, которое содержит значение документа для вас.
Вы также можете использовать bind(), чтобы сделать то же самое.
Ответ 3
Вы можете использовать bind
Создает новую функцию, которая при вызове имеет для этого ключевого слова значение предоставленное значение, с заданной последовательностью аргументов, предшествующих любому при появлении новой функции.
var f = document.getElementById.bind(document);
Он был введен в ES5, поэтому имейте в виду, что браузеры еще не поддерживают эту версию ECMAScript!
В качестве альтернативы вы можете использовать proxy
метод jQuery, добавленный в версию 1.4
var f = $.proxy(document.getElementById, document);
Или вы можете delcare f
как функцию своего собственного (это более подробное решение).
var f = function() { return document.getElementById(arguments); }