Локальная копия document.getElementsByTagName

Почему не работает следующий код?

var f = document.getElementsByTagName;
var x = f('div');

Я получаю "TypeError: Недопустимый вызов" в Chrome, "TypeError: Ошибка типа" в Safari. Я не получаю ошибку в Firefox, но она не работает. Я еще не удосужился протестировать IE или Opera.

4 ответа

Решение

В Javascript нет такой вещи, как "связанный метод" (заимствовать термин из Python, который, я надеюсь, вы уже знаете, или объяснение, возможно, должно быть более длинным). Когда вы получаете ссылку на "document.getElementsByTagName", вы просто получаете ссылку на функцию, а не на метод, связанный с объектом документа. Когда вы вызываете его, "this" устанавливается в окне, а не в документе, поэтому оно не работает.

Технически это даст вам то, что вы хотите, но, как вы, вероятно, видите, это бессмысленно:

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

(Это бессмысленно, потому что это менее читабельно и не так быстро, как вызов document.getElementsByTagName(). Использование замыкания также бессмысленно.)

Потому что в JavaScript методы получают свои this из объекта, для которого они вызваны, и вызов метода, хранящегося в отдельной переменной, делает это this быть глобальным контекстом (или windowв браузерах). это должно работать:

var f function ()
{
    return document.getElementsByTagName.apply(
        document
      , arguments
    );
}
var x = f('div');

Попробуй это:

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

var x = f('div');   

Вы пытаетесь вызвать функцию, используя круглые скобки. Проблема в том, что "f" в вашем коде - это переменная, а не функция.

Причина в том, что getElementsByTagName необходимо вызывать для объекта. Можно сказать, что внутри определения функции она использует this чтобы выяснить, в каком элементе искать теги. Когда вы копируете функцию и затем вызываете ее, ей будет предоставлена ​​новая область видимости, что означает, что this нет указывает на другой объект. Чтобы вызвать функцию в документе, попробуйте это:

var f = document.getElementsByTagName;
var x = f.call(document, "pre");
alert(x[0]);
Другие вопросы по тегам