Подтвердить что ты не робот

Функция псевдонима в javascript

Возможный дубликат:
Если Javascript имеет первоклассные функции, почему это не работает?

Когда я пытаюсь сделать функцию псевдонима для document.getElementById, как показано ниже:

f = document.getElementById;

Но когда я пытаюсь позвонить:

var e_fullname = f("fullname");

Ошибка: Could not convert JavaScript argument

И ниже ОК:

var e_fullname = f.call(document, "funname");

Можете ли вы сказать мне, почему?

4b9b3361

Ответ 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); }