Лучший метод тестирования для функции в JavaScript? - PullRequest
2 голосов
/ 01 января 2009

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

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

/* 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 (в основном), но никто не намекал на эффективность альтернативных методов.

Ответы [ 3 ]

5 голосов
/ 01 января 2009

Лучший способ проверить, является ли объект функцией, это 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 в Firefox.

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

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

2 голосов
/ 01 января 2009

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

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

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

typeof o === "function"

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

1 голос
/ 01 января 2009

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

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

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