Как проверить, является ли значение объектом в JavaScript?
javascript
object
types
javascript-objects
Дэнни Фокс
источник
источник
null
является ли объект).Ответы:
ОБНОВЛЕНИЕ :
Этот ответ неполон и дает вводящие в заблуждение результаты . Например,
null
также считается типobject
в JavaScript, не говоря уже о нескольких других крайних случаях. Следуйте приведенной ниже рекомендации и перейдите к другому «наиболее одобренному (и правильному!) Ответу» .Оригинальный ответ :
Попробуйте использовать
typeof(var)
и / илиvar instanceof something
.РЕДАКТИРОВАТЬ: Этот ответ дает представление о том, как исследовать свойства переменной, но это не пуленепробиваемый рецепт (ведь рецепта нет вообще!) Для проверки, является ли это объект, вдали от него. Поскольку люди, как правило, ищут что-то для копирования, не проводя никаких исследований, я настоятельно рекомендую обратиться к другому, наиболее одобренному (и правильному!) Ответу.
источник
typeof
является оператором, поэтому нет необходимости()
.typeof
возвращает «объект» для нуля, который не является объектом иinstanceof
не работает для объектов, созданных с использованиемObject.create(null)
.Если
typeof yourVariable === 'object'
это объект или ноль. Если вы хотите исключить ноль, просто сделайте этоtypeof yourVariable === 'object' && yourVariable !== null
.источник
yourVariable !== null
лучше практиковаться?typeof null == 'object'
не будет исправлено в ES6 . Они сказали:This proposal has been rejected. It was implemented in V8 but it turned out that it broke a lot of existing sites. In the spirit of One JavaScript this is not feasible.
typeof
поскольку в нем есть несколько особых случаев, которые не обязательно имеют смысл. Если вы пытаетесь провести различие между массивами и объектами, которые не являются массивами, то вы определенно не хотите их использоватьtypeof
.Object.prototype.toString.call(yourVar)
, будучи вашим, что нужно проверять. В случае массивовObject.prototype.toString.call([1,2])
возвращается[object Array]
Давайте определим «объект» в Javascript . Согласно документам MDN , каждое значение является либо объектом, либо примитивом:
Что за примитив?
3
'abc'
true
null
undefined
Что за объект (то есть не примитив)?
Object.prototype
Object.prototype
Function.prototype
Object
Function
function C(){}
- пользовательские функцииC.prototype
- свойство prototype пользовательской функции: это неC
s prototypenew C()
- «новая» - определяемая пользователем функцияMath
Array.prototype
{"a": 1, "b": 2}
- объекты, созданные с использованием буквенной нотацииnew Number(3)
- обертки вокруг примитивовObject.create(null)
Object.create(null)
Как проверить, является ли значение объектом
instanceof
само по себе не сработает, потому что пропускает два случая:typeof x === 'object'
не будет работать из-за ложных срабатываний (null
) и ложных срабатываний (функций):Object.prototype.toString.call
не сработает из-за ложных срабатываний для всех примитивов:Поэтому я использую:
Ответ @ Даана также, кажется, работает:
потому что, согласно документам MDN :
Третий способ, который, кажется, работает (не уверен, что он равен 100%) - использовать метод,
Object.getPrototypeOf
который выдает исключение, если его аргумент не является объектом:источник
obj === Object(obj)
возвращаетtrue
для массивов.var x = []; console.log(x === Object(x)); // return true
getPrototypeOf
не работает, например, с отозванными прокси, которые являются объектами, но не бросают({}).toString.apply(obj) === '[object Object]'
различие между массивами и объектами, которые не являются массивамиunderscore.js предоставляет следующий метод, чтобы узнать, действительно ли что-то является объектом:
ОБНОВИТЬ
Из-за предыдущей ошибки в V8 и незначительной оптимизации микро-скорости этот метод выглядит следующим образом начиная с underscore.js 1.7.0 (август 2014 г.):
источник
return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
null
тоже. Должен быть принятый ответ.Object.prototype.toString.call(myVar)
вернусь:"[object Object]"
если myVar является объектом"[object Array]"
если myVar это массивДля получения дополнительной информации об этом и почему это хорошая альтернатива typeof, ознакомьтесь с этой статьей .
источник
typeof [] === 'object'
->true
. Вот для чего вам нужен этот метод.Object.prototype.toString.call(3)
->"[object Number]"
.Object.prototype.toString.call(new Number(3))
->"[object Number]
"getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
Для простой проверки по объекту или массиву без дополнительного вызова функции (скорость). Как и размещено здесь .
IsArray ()
isObject () - Примечание: используйте только для литералов объекта, так как он возвращает false для пользовательских объектов, таких как new Date или new YourCustomObject.
источник
isObject
работает только с объектными литералами. Если я создаю пользовательский тип, создаю экземпляр типа и проверяю его, он возвращаетfalse
Boolean(a)
длиннее, но гораздо более интуитивно понятен. Только не используйтеnew Boolean(a)
: ( вот почему )!{
символа. В случае массива, если вам не нужно поддерживать IE <9, вы можете использовать,Array.isArray()
чтобы определить, является ли что-то массивом. Он проходит все предоставленные вами тесты.Я люблю просто:
Если элемент является объектом JS, и это не массив JS, и это не так
null
... если все три окажутся истинными, вернитеtrue
. Если какое-либо из этих трех условий не выполнено,&&
тест замкнется иfalse
будет возвращен.null
Тест может быть опущен при желании ( в зависимости от того, как вы используетеnull
).DOCS:
http://devdocs.io/javascript/operators/typeof
http://devdocs.io/javascript/global_objects/object
http://devdocs.io/javascript/global_objects/array/isarray
http://devdocs.io/javascript/global_objects/null
источник
new Date()
возвращает объект. С логической точки зрения массив не является объектом - хотя JavaScript обрабатывает и сообщает о них как таковые. Однако на практике бесполезно видеть их равными, потому что это не так. Например, у объекта нетlength
атрибута и нет методов типа push (). И иногда вы можете захотеть дать функции перегруженные параметры, где вам нужно различать массив или объект, особенно если другие параметры зависят от того, какой из них был задан.length
свойство , ни методы , какpush
,Object.create(Array.prototype)
тривиальные контрпример объект , не являющийся массив , который имеет их. Что делает массивы особенными, так это то, что они являются экзотическими объектами с пользовательским [[DefineOwnProperty]] существенным внутренним методом, но они по-прежнему являются объектами.length
свойства (я имел в виду, что у литералов объектовlength
по умолчанию нет атрибутов). Я написал, что массивы не являются объектами с логической точки зрения. Я говорю о программной логике. Иногда необходимо проверить, является ли массив «реальным» массивом и определенно не «реальным» объектом. Вот для чегоArray.isArray()
. Представьте, что у вас есть функция, которая принимает объект или массив объектов. Проверка на наличие специального атрибута или метода - грязное решение. Родной путь всегда лучше.typeof null
это"object"
не"undefined"
.С функцией
Array.isArray
:Без функции
Array.isArray
:Просто удивился, сколько откликов за неправильные ответы 😮
Только 1 ответ прошел мои тесты !!! Здесь я создал свою упрощенную версию:
Как по мне, это понятно и просто, и просто работает! Вот мои тесты:
ОДИН БОЛЬШЕ ВРЕМЕНИ: не все ответы проходят этот тест !!! 🙈
В случае, если вам нужно проверить, что объект является экземпляром определенного класса, вы должны проверить конструктор с вашим конкретным классом, например:
простой тест:
В результате у вас будет строгий и надежный код!
В случае , если вы не будете создавать такие функции , как
isDate
,isError
,isRegExp
и т.д. , вы можете рассмотреть возможность использования этой обобщенной функции:он не будет работать правильно для всех тестовых случаев, упомянутых ранее, но он достаточно хорош для всех объектов (простых или построенных).
isObject
не будет работать в случаеObject.create(null)
из-за внутренней реализации,Object.create
которая описана здесь, но вы можете использоватьisObject
в более сложной реализации:На npm v1 уже создан пакет, основанный на этой реализации! И это работает для всех ранее описанных тестовых случаев! 🙂
источник
isDate
для yourDateObject с целью написания надежного кода, иначе у вас будет хрупкийisObject
метод.Date
в моем комментарии было неправильно выбрано, потому что да, ответ действительно обсуждаетсяDate
. НоDate
это только один из бесконечных возможных классов, и точка имеет место для любого другого класса. Пример:class Foo() { }; var x = new Foo(); isObject(x)
возвращаетсяfalse
. Я не знаю точно, каков вариант использования OP, но легко представить себе сценарии, в которых необходимость знать обо всех возможных классах и проверять конкретно каждый из них будет невозможна.Боже мой! Я думаю, что это может быть короче, чем когда-либо, давайте посмотрим на это:
Короткий и Финальный код
Разъяснения
Типы возврата
Тип JavaScript объектов (в том числе
null
) возвращает"object"
Проверка их конструкторов
Проверка их
constructor
свойства возвращает функцию с их именами.Представляем Function.name
Function.name
возвращает только для чтения имя функции или"anonymous"
для замыканий.источник
Object.create(null)
и почему вы все равно это сделаете ...?Хорошо, давайте сначала дадим вам эту концепцию, прежде чем ответить на ваш вопрос, в JavaScript функциями являются Object, также null, Object, Arrays и даже Date, поэтому, как вы видите, не существует простого способа, как typeof obj === 'object', поэтому все упомянутое выше вернет истину , но есть способы проверить это с помощью написания функции или использования фреймворков JavaScript, хорошо:
Теперь представьте, что у вас есть настоящий объект (не нуль, не функция или массив):
Чистый JavaScript:
или
или
или
Вы можете просто использовать одну из этих функций, как указано выше, в своем коде, вызывая их, и она вернет true, если это объект:
Если вы используете JavaScript-фреймворк, они обычно подготовили для вас такие функции, вот некоторые из них:
JQuery:
Угловой:
Подчеркни и Лодаш:
источник
Это зависит от того, что вы имеете в виду под «является объектом». Если вы хотите все, что не является примитивом , то есть вещи, на которые вы можете установить новые свойства, это должно помочь:
Это исключает примитивы (простые числа /
NaN
/Infinity
, простые строки, символы,true
/false
,undefined
иnull
) , но должен возвращать верно для всего остального ( в том числеNumber
,Boolean
иString
объектов). Обратите внимание, что JS не определяет, какие "хостовые" объекты, такие какwindow
илиconsole
, должны возвращаться при использовании с нимиtypeof
, поэтому их трудно покрыть такой проверкой.Если вы хотите узнать, является ли что-то «простым» объектом, то есть оно было создано как литерал
{}
или с помощьюObject.create(null)
, вы можете сделать это:Редактировать 2018 : поскольку
Symbol.toStringTag
теперь позволяет настраивать выходные данныеObject.prototype.toString.call(...)
,isPlainObject
вышеприведенная функция может возвращатьсяfalse
в некоторых случаях, даже если объект начал свою жизнь как литерал. Можно утверждать, что по соглашению объект с пользовательским строковым тегом больше не является простым объектом, но это еще больше запутало определение того, что такое простой объект даже в Javascript.источник
instanceof Object
одинаковы, два одинаковых функциональных литерала не являются строго равными, они передаются по ссылке и т. Д.Боже мой, слишком много путаницы в других ответах.
Короткий ответ
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array)
Чтобы проверить это, просто запустите следующие операторы в консоли Chrome.
Дело 1.
Случай 2
Случай 3
объяснение
Хорошо. Давайте разберемся
typeof anyVar == 'object'
возвращается три из трех кандидатов -[], {} and null
,anyVar instanceof Object
сужает этих кандидатов до двух -[], {}
!(anyVar instanceof Array)
сужается только до одного -{}
Барабанная дробь, пожалуйста!
К этому вы, возможно, уже научились проверять массив в Javascript.
источник
false
(по желанию), когдаanyVar
является функцией.Наиболее разумным способом проверки типа значения представляется
typeof
оператор. Единственная проблема в том, что он ужасно сломан:"object"
дляnull
, который принадлежит типу Null."function"
для вызываемых объектов, которые относятся к типу Object."unknown"
. Единственными запрещенными результатами являются"function"
и примитивные типы.typeof
надежен только для неnull
примитивов. Таким образом, способ проверить, является ли значение объектом, - это убедиться, что возвращаемая строкаtypeof
не соответствует примитиву, и что объект не являетсяnull
. Однако проблема в том, что будущий стандарт может ввести новый примитивный тип, и наш код будет считать его объектом. Новые типы появляются не часто, но, например, ECMAScript 6 ввел тип Symbol.Поэтому вместо
typeof
я рекомендую только подходы, результат которых зависит от того, является ли значение объектом или нет. Следующее намеревается бытьПолный, но не исчерпывающий список правильных способов проверить, принадлежит ли значение типу Object.
Object
конструкторObject
Конструктор принуждает переданный аргумент к объекту. Если это уже объект, возвращается тот же объект.Следовательно, вы можете использовать его для приведения значения к объекту и строгого сравнения этого объекта с исходным значением.
Следующая функция требует ECMAScript 3, который представил
===
:Мне нравится этот подход, потому что он прост и информативен, и аналогичная проверка также будет работать для логических значений, чисел и строк. Тем не менее, имейте в виду, что он зависит от того, что глобальный
Object
мир не скрывается и не изменяется.Конструкторы
Когда вы создаете экземпляр конструктора, он может возвращать значение, отличное от только что созданного экземпляра. Но это значение будет игнорироваться, если это не объект.
Следующая функция требует ECMAScript 3, который позволял конструкторам возвращать не-объекты. До ECMAScript 3 это вызвало ошибку, но тогда
try
еще не было операторов.Хотя этот пример немного проще, чем в предыдущем примере, он не зависит от какого-либо глобального свойства и, следовательно, может быть самым безопасным.
this
ценностьСтарые спецификации ECMAScript требовали, чтобы
this
значение было объектом. Введен ECMAScript 3Function.prototype.call
, который позволяет вызывать функцию с произвольнымthis
значением, но принудительно вызывать объект.ECMAScript 5 ввел строгий режим, который убрал это поведение, но в небрежном режиме мы все еще можем (но, возможно, не должны) полагаться на него.
[[Прототип]]
Все обычные объекты имеют внутренний слот с именем [[Prototype]], значение которого определяет, от какого другого объекта он наследуется. Значение может быть только объектом или
null
. Следовательно, вы можете попытаться создать объект, который наследуется от желаемого значения, и проверить, сработало ли оно.И то
Object.create
и другоеObject.getPrototypeOf
требует ECMAScript 5.Некоторые новые способы ECMAScript 6
ECMAScript 6 представляет некоторые новые косвенные способы проверки, является ли значение объектом. Они используют ранее замеченный подход, чтобы передать значение некоторому коду, который требует объекта, заключенного в
try
оператор для отлова ошибок. Некоторые скрытые примеры, не стоит комментироватьПоказать фрагмент кода
Показать фрагмент кода
Примечание: я намеренно пропустил некоторые подходы, такие как
Object.getPrototypeOf(value)
(ES5) иReflect
методы (ES6), потому что они вызывают важные внутренние методы, которые могут делать неприятные вещи, например, еслиvalue
это прокси. Из соображений безопасности мои примеры приведены толькоvalue
без прямого доступа к нему.источник
Попробуй это
источник
Object.prototype instanceof Object
-> ложь.Object.create(null) instanceof Object
-> ложь.new Date() instanceof Object
=> верноГотовы использовать функции для проверки
объяснение
В JavaScript
null
,Object
,Array
,Date
иfunction
s являются все объекты. Хотя,null
это немного надумано. Итак, лучше проверитьnull
сначала, чтобы обнаружить, что это не нуль.Проверка на
typeof o === 'object'
гарантии, чтоo
это объект. Без этой проверкиObject.prototype.toString
было бы бессмысленно, так как она возвращала бы объект навсегда, даже дляundefined
иnull
! Например:toString(undefined)
возвращается[object Undefined]
!После
typeof o === 'object'
проверки toString.call (o) является отличным методом, чтобы проверить,o
является ли объект, производный объект, напримерArray
,Date
илиfunction
.В
isDerivedObject
функции он проверяет,o
является ли функция. Потому что функционируют также как объект, поэтому он здесь. Если этого не произошло, функция вернется как false. Пример:isDerivedObject(function() {})
вернетсяfalse
, однако теперь возвращаетсяtrue
.Всегда можно изменить определение того, что является объектом. Таким образом, можно изменить эти функции соответственно.
тесты
источник
Если вы хотели бы проверить, если
prototype
дляobject
исключительно исходит отObject
. ФильтруетString
,Number
,Array
,Arguments
и т.д.Или как функция стрелки с одним выражением (ES6 +)
источник
return Object.prototype.toString.call(n) === '[object Object]'
null
чек, потому чтоObject.prototype.toString.call(null) === '[object Null]'
Меня попросили предоставить более подробную информацию. Самый простой и понятный способ проверить, является ли наша переменная объектом
typeof myVar
. Возвращает строку с типом (например"object"
,"undefined"
).К сожалению, либо Array и null также имеют тип
object
. Для получения только реальных объектов необходимо проверить цепочку наследования с помощьюinstanceof
оператора. Это исключит ноль, но Array имеет Object в цепочке наследования.Итак, решение таково:
источник
/./ instanceof Object //true
Немного поздно ... для "простых объектов" (я имею в виду, например, {'x': 5, 'y': 7}) у меня есть небольшой фрагмент:
Он генерирует следующий вывод:
Это всегда работает для меня. If будет возвращать «true» только в том случае, если тип «o» равен «объект», но не имеет значения null, массива или функции. :)
источник
У lodash есть isPlainObject , который может быть тем, что многие ищут на этой странице. Возвращает false, когда дают функцию или массив.
источник
_.isObject
что соответствует тому, что JS считает объектом. Но мне обычно нужно различать, например, литерал объекта и массив, что и_.isPlainObject
позволяет мне делать.Это будет работать Это функция, которая возвращает истину, ложь или, возможно, ноль.
источник
null
в качестве результата для финального теста, а неfalse
. См. Когда я должен внести изменения в код?Поскольку кажется, что существует правильное решение этой проблемы, я оставлю свои 2 цента (этот ответ соответствует спецификации и дает правильные результаты при любых обстоятельствах):
Тестирование на примитивы:
undefined
null
boolean
string
number
Объект не является примитивом:
Или в качестве альтернативы:
Тестирование для любого массива:
Тестирование на объект, исключая:
Date
RegExp
Boolean
Number
String
Function
любой массивисточник
Когда все остальное терпит неудачу, я использую это:
источник
item.constructor === Object
?null
выдает исключениеUncaught TypeError: Cannot read property 'constructor' of null(…)
indexOf
или из-заconstructor.name
?Ramda функциональная библиотека имеет замечательную функцию для определения типов JavaScript.
Перефразируя полную функцию :
Мне пришлось смеяться, когда я понял, насколько простым и красивым было решение.
Пример использования из документации Ramda :
источник
После прочтения и попробовать много реализаций, я заметил , что очень немногие люди пытается проверить ценности , как
JSON
,Math
,document
или объекты с цепочкой прототипов более чем на 1 шаг.Вместо того, чтобы проверять
typeof
нашу переменную и затем взламывать крайние случаи, я подумал, что было бы лучше, если бы проверка оставалась максимально простой, чтобы избежать необходимости проводить рефакторинг, когда добавляются новые примитивы или собственные объекты, которые регистрируются какtypeof
объект ».В конце концов,
typeof
оператор скажет вам, является ли что-то объектом JavaScript , но определение объекта в JavaScript слишком широкое для большинства реальных сценариев (напримерtypeof null === 'object'
). Ниже приведена функция, которая определяет,v
является ли переменная объектом, фактически повторяя две проверки:v
является'[object Object]'
.Я хотел, чтобы результат функции был точно таким же, как в журналах ниже, так что это единственный критерий «объектности», с которым я закончил. Если это не удается, функция сразу возвращает false.
v
заменяется следующим прототипом в цепочкеv = Object.getPrototypeOf(v)
, но также непосредственно оценивается после. Когда новое значение равноv
isnull
, это означает, что каждый прототип, включая корневой прототип (который вполне мог быть единственным прототипом в цепочке), прошел проверку в цикле while, и мы можем вернуть true. В противном случае начинается новая итерация.источник
источник
value
этоnull
это вызовет ошибку ...false
для объектаObject.assign({}, {constructor: null})
.Если явно хотите проверить, является ли данное значение
{}
.источник
!!obj
это сокращение для проверки, еслиobj
это правда (отфильтроватьnull
)источник
Это старый вопрос, но мы решили оставить это здесь. Большинство людей проверяют,
{}
означает ли переменная пару ключ-значение, а не то, что является структурой подчеркивания, которую JavaScript использует для данной вещи, потому что, честно говоря, в основном все в JavaScript является объектом. Так что убираю это с пути. Если вы делаете ...В большинстве случаев нам нужно знать, есть ли у нас объект ресурса из API или наш вызов базы данных, возвращенный из ORM. Затем мы можем проверить, не является ли, не является
Array
, неnull
является typeof'function'
и является лиObject
источник
true
дляnew Date()
new Date()
Что мне нравится использовать это
Я думаю, что в большинстве случаев Дата должна пройти проверку как Объект, поэтому я не фильтрую даты
источник
я нашел «новый» способ сделать именно такую проверку типов из этого SO вопроса: почему instanceof возвращает false для некоторых литералов?
Исходя из этого, я создал функцию для проверки типа следующим образом:
тогда вы можете просто сделать:
это проверено на Chrome 56, Firefox 52, Microsoft Edge 38, Internet Explorer 11, Opera 43
редактировать:
если вы также хотите проверить, является ли переменная нулевой или неопределенной, вы можете использовать это вместо:
обновление от комментария Инанка: вызов принят: D
если вы хотите потерять сравниваемые объекты, вы можете попробовать это следующим образом:
таким образом, вы можете сделать так же, как комментарий Inanc:
или
источник
instanceof
для проверки объектов. Тем не менее, это не точная наука.new Foo()
возвращаетFoo
объект, такой же , какnew String()
возвращаетString
объект, илиnew Date()
возвращаетDate
объект, вы можете сделатьFoo = function(){}; isVarTypeOf(new Foo(), Foo);
также