JQuery'sFunction и InternetExplorer - PullRequest
       1

JQuery'sFunction и InternetExplorer

2 голосов
/ 18 августа 2010

При адаптации метода isFunction в jQuery

isFunction: function( obj ) {
  return toString.call(obj) === "[object Function]";
}

InternetExlorer 8 возвращает следующую ошибку: «Объект не поддерживает это свойство или метод». Хорошая статья копание в этой функции не исправит это поведение. Чтобы проверить, определено ли obj , я изменил функцию в ссылке на статью MSDN :

isFunction: function( obj ) {
  return obj && toString.call(obj) === "[object Function]";
}

Есть еще идеи для решения?

Ответы [ 3 ]

9 голосов
/ 18 августа 2010

Вам необходимо вызвать метод toString непосредственно из объекта Object.prototype:

function isFunction (obj) {
    return Object.prototype.toString.call(obj) === "[object Function]";
}

alert(isFunction({})); // false
alert(isFunction(function{})); // true

В jQuery есть локальная переменная с именем toString, которая ссылается на метод Object.prototype.

Вызов только toString.call(obj); без объявления идентификатора toString в области видимости, работает в Firefox, Chrome и т. Д. Только потому, что объект Global наследуется от Object.prototype, но это не гарантируется спецификацией.

Object.prototype.isPrototypeOf(window); // false on IE

В статье, на которую вы ссылаетесь, говорится об изменении, которое было внесено в спецификацию ECMAScript 5-го издания для методов call и apply.

Эти методы позволяют вам вызывать функцию, передающую первый аргумент как значение this вызванной функции.

В ECMAScript 3, если этот аргумент был undefined или null, значение this вызванной функции будет ссылаться на глобальный объект, например:

function test () {  return this; }
test.call(null) === window; // true

Но это изменилось в ES5, теперь значение должно передаваться без изменений, и это заставило Object.prototype.toString вызвать исключение, поскольку ожидался аргумент объекта.

Спецификация этого метода изменилась, теперь, если значение this относится к undefined или null, будет возвращена строка "[object Undefined]" или "[object Null]", что решает проблему (вещь, которую я не думаю, это действительно хорошо, так как оба результата кажутся просто неправильными, undefined и null являются , а не объектами, они примитивы ... что заставило меня вспомнить typeof null == 'object' ... Более того, я думаю, что это портит в любом случае, в соответствии с концепцией внутреннего свойства [[Class]] ...

Теперь вы можете задаться вопросом, почему jQuery использует этот метод для проверки объекта функции вместо использования оператора typeof?

Ошибки реализации, например в Chrome / Safari / WebKit, typeof для объектов RegExp возвращает "function", потому что объекты RegExp, где было сделано , могут вызываться , например ::

typeof /foo/; // "function" in Chrome/Safari/WebKit

Оператор typeof возвращает "function", если объект реализует внутреннее свойство [[Call]], что делает объекты вызываемыми .

Это было первоначально введено реализациями Mozilla, вызов объекта RegExp эквивалентен вызову метода exec.

1 голос
/ 18 августа 2010

Какую цель пытается использовать функция isFunction? Предназначено ли оно для работы с хост-объектами (то есть узлами DOM, window и т. Д. В браузерах) или регулярными выражениями (которые, как указывает CMS в комментариях, могут вызываться и возвращать «функцию» с typeof в некоторых браузерах)? Если нет, все, что вам нужно, это

typeof obj == "function"

Если предполагается, что он имеет дело с методами хоста, то он имеет недостатки, поскольку нет необходимости, чтобы браузер возвращал «[Object Function]» для методов хоста. В IE есть много свойств вызываемого хоста, которые не возвращают «[Object Function]» или выдают ошибку. Например:

alert(Object.prototype.toString.call(document.createElement));

... дает "[объект объекта]" в IE.

0 голосов
/ 18 августа 2010

Я только что запустил это в консоли IE 8:

>>$.isFunction(undefined);
false

Работает нормально.

Сообщение в блоге, на которое вы ссылаетесь, относится к IE 9 .

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