Я в строгом режиме ES5, поэтому решение
function isArguments(item) {
return item.callee !== undefined;
}
к сожалению не работает.
Я в строгом режиме ES5, поэтому решение
function isArguments(item) {
return item.callee !== undefined;
}
к сожалению не работает.
function isArguments( item ) {
return Object.prototype.toString.call( item ) === '[object Arguments]';
}
Ответ Уильяма прав, но некоторые объяснения могут быть полезными.
В ECMAScript 5 единственной характеристикой объектов Arguments является их внутренний [[Class]], как показано в §10.6 Аргумент Object:
Когда CreateArgumentsObject вызывается, следующие шаги: выполняется:
- Пусть obj является результатом создания нового объекта ECMAScript.
- Установить внутреннее свойство [[Class]] объекта obj на
"Arguments"
.- Возврат obj
[[Класс]] является внутренним свойством, общим для всех объектов, значением которого является String, который классифицирует объект. Это объясняется в §8.6.2 Внутренние свойства и методы объекта:
Значение внутреннего свойства [[Class]] определяется этим спецификация для каждого типа встроенного объекта.
Значение внутреннего свойства [[Class]] используется внутри различать различные типы объектов.
Кроме того, обратите внимание, что объекты хоста не будут проблематичными:
Значение внутреннего свойства [[Class]] объекта-хоста может быть любое значение String, кроме одного из
"Arguments"
, [...]
Поэтому, чтобы идентифицировать объект Arguments, вам нужно только проверить его класс.
Вы можете сделать это, используя §15.2.4.2 Object.prototype.toString
:
- Пусть O - результат вызова ToObject, передающего значение this в качестве аргумента.
- Пусть класс является значением внутреннего свойства [[Class]] для O.
- Возвращает значение String, которое является результатом объединения трех строк
"[object "
, class и"]"
.
Поэтому вы можете использовать Function.prototype.call
, чтобы вызвать этот метод со значением this
, установленным для объекта, который вы хотите проверить. Возвращаемая строка будет '[object Arguments]'
, если и только если это объект Arguments.
Object.prototype.toString.call(obj) == '[object Arguments]'
Обратите внимание, что это не является полностью надежным, потому что глобальный Object
мог быть затенен локальным или глобальное свойство Object
или его toString
могло быть изменено.
Однако нет лучшего способа:
Обратите внимание, что эта спецификация не предоставляет никаких средств для программы для доступа к этому значению, за исключением
Object.prototype.toString
(см. 15.2.4.2).
Генерация и сравнение строк для определения типа объекта немного нечеткая. Как и @bergi, я думаю, что Lodash делает это более удобным способом. Сжатый в одну функцию:
function isArguments(value) {
return !!value && typeof value == 'object' && Object.prototype.hasOwnProperty.call(value, 'callee') && !Object.prototype.propertyIsEnumerable.call(value, 'callee');
}