Лучший метод тестирования функции в JavaScript?

StackOverflow https://stackoverflow.com/questions/405164

  •  03-07-2019
  •  | 
  •  

Вопрос

Я провел немало исследований по этому поводу, но кажется, что используемые методы непоследовательны и разнообразны.

Вот некоторые методы, которые я использовал в прошлом:

/* 1: */  typeof myFunc === 'function'
/* 2: */  myFunc.constructor === Function
/* 3: */  myFunc instanceof Function

В рамках своего исследования я рассмотрел, как это удалось сделать некоторым известным библиотекам:

 /* jQuery 1.2.6: */  !!fn && typeof fn != "string" && !fn.nodeName && fn.constructor != Array && /^[\s[]?function/.test( fn + "" )
 /* jQuery 1.3b1: */  toString.call(obj) === "[object Function]"
/* Prototype 1.6: */  typeof object == "function"
      /* YUI 2.6: */  typeof o === 'function'

Я поражен тем, что используется так много разных методов, неужели не был согласован единый приемлемый тест?И я совершенно не понимаю, каковы были намерения при использовании jQuery 1.2.6, выглядит немного ОТТ...

Итак, мой вопрос остается: каков наилучший* способ тестирования функции?

Я также был бы признателен за некоторую информацию о некоторых из вышеперечисленных методов, особенно о jQuery 1.2.6.(Я вижу, что они делают, просто это кажется странным)

[*] Под «лучшим» я подразумеваю наиболее широко распространенный метод, совместимый с разными браузерами.


РЕДАКТИРОВАТЬ:Да, я знаю, что это обсуждалось раньше, но мне все же хотелось бы обсудить наиболее эффективный метод.Почему существует так много различных используемых методов?

В дискуссиях по SO до сих пор упоминался только оператор typeof (в основном), но никто не намекнул на эффективность альтернативных методов.

Это было полезно?

Решение

Лучший способ проверить, является ли объект функцией: typeof myFunc === 'function'.Если вы используете библиотеку, используйте функциональный тест этой библиотеки: jQuery.isFunction(myFunc).

Вещи может быть ошибочно сообщены как функции при использовании typeof.Это очень редко, но существует библиотека, которая устраняет эти несоответствия.jQuery решает эти проблемы:

  • Функция отчетов Firefox работает с typeof document.createElement("object")
  • Отчеты Safari функционируют с typeof document.body.childNodes
  • Более старые версии Firefox сообщали о регулярных выражениях как о функциях (в версии 3.0 это не так).
  • Некоторые IE встроены в глобальные функции (alert) и некоторые методы узлов (getAttribute), как сообщается, относятся к типу «объект».

С использованием instanceof скорее, чем typeof обходит некоторые из них.Например, document.createElement("object") instanceof Function является false в Фаерфоксе.

Рождение первого метода вы можете посмотреть в комментариях к оригинальный билет (#3618).Новый метод взят из набор изменений 5947 и, кажется, был изобретен Ресигом для решения Утечки памяти IE.Вероятно, он медленнее, но меньше и чище.

Здесь нет большой разницы между == и === с точки зрения того, как все работает, но строгая оценка немного быстрее и поэтому предпочтительнее.

Другие советы

Джон Ресиг, разработчик jQuery, похоже, сделал несколько странный выбор во внутреннем устройстве jQuery.

toString.call(obj) === "[object Function]"

выглядит довольно аккуратно, но я не могу придумать ни одной ситуации, в которой вышесказанное было бы правдой, где простой typeof подход потерпит неудачу, но, возможно, он знает что-то, чего не знают остальные пользователи.

typeof o === "function"

Я бы выбрал последнее, поскольку оно более ясно, если только у вас нет убедительных доказательств того, что оно не сработает.

Зачем использовать строгое равенство typeof поскольку оба операнда являются строками?Я упускаю из виду какую-то проблему?

В любом случае, я бы пошел по более простому пути typeof, который, кажется, сделан для этого и читаем. instanceof тоже читается, но, похоже, больше настаивает на том факте, что функция является объектом, что может не иметь отношения к проблеме.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top