Вам необходимо вызвать метод 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
.