Как вы проверяете, является ли значение объектом в JavaScript?
Проверьте, является ли значение объектом в JavaScript
Ответ 1
Попробуйте использовать typeof(var)
и/или var instanceof something
.
EDIT: этот ответ дает представление о том, как исследовать свойства переменных, но это не пуленепробиваемый рецепт (ведь там вообще нет рецепта!) для проверки того, является ли он объектом, далеким от него. Поскольку люди склонны искать что-то, чтобы копировать здесь, не делая никаких исследований, я бы очень рекомендовал, чтобы они обратились к другому, наиболее одобренному (и правильному!) Ответу.
Ответ 2
Если typeof yourVariable === 'object'
, это объект или ноль. Если вы хотите исключить null, просто сделайте его typeof yourVariable === 'object' && yourVariable !== null
.
Ответ 3
Пусть определите "объект" в Javascript. Согласно MDN docs, каждое значение является либо объектом, либо примитивом:
примитивное, примитивное значение
Данные, которые не являются объектами и не имеют каких-либо методов. JavaScript имеет 5 примитивных типов данных: string, number, boolean, null, undefined.
Какой примитив?
-
3
-
'abc'
-
true
-
null
-
undefined
Какой объект (т.е. не примитив)?
-
Object.prototype
- все происходит от
Object.prototype
-
Function.prototype
-
Object
-
Function
-
function C(){}
- пользовательские функции
-
-
C.prototype
- свойство прототипа определяемой пользователем функции: это не прототипC
-
new C()
- "new" - определение пользовательской функции
-
-
Math
-
Array.prototype
- массивы
-
{"a": 1, "b": 2}
- объекты, созданные с использованием литеральной нотации -
new Number(3)
- обертки вокруг примитивов - ... многое другое...
-
-
Object.create(null)
- все происходит от
Object.create(null)
Как проверить, является ли значение объектом
instanceof
сам по себе не будет работать, потому что он пропускает два случая:
// oops: isObject(Object.prototype) -> false
// oops: isObject(Object.create(null)) -> false
function isObject(val) {
return val instanceof Object;
}
typeof x === 'object'
не будет работать из-за ложных срабатываний (null
) и ложных негативов (функций):
// oops: isObject(Object) -> false
function isObject(val) {
return (typeof val === 'object');
}
Object.prototype.toString.call
не будет работать из-за ложных срабатываний для всех примитивов:
> Object.prototype.toString.call(3)
"[object Number]"
> Object.prototype.toString.call(new Number(3))
"[object Number]"
Поэтому я использую:
function isObject(val) {
if (val === null) { return false;}
return ( (typeof val === 'function') || (typeof val === 'object') );
}
@Даан ответ также работает:
function isObject(obj) {
return obj === Object(obj);
}
поскольку в соответствии с документами MDN:
Конструктор объекта создает обертку объекта для данного значения. Если значение равно null или undefined, оно создаст и вернет пустой объект, иначе он вернет объект типа, соответствующего данному значению. Если значение уже является объектом, оно вернет значение.
Третий способ, который, кажется, работает (не уверен, что он 100%) должен использовать Object.getPrototypeOf
, который генерирует исключение, если его аргумент не является объектом
// these 5 examples throw exceptions
Object.getPrototypeOf(null)
Object.getPrototypeOf(undefined)
Object.getPrototypeOf(3)
Object.getPrototypeOf('abc')
Object.getPrototypeOf(true)
// these 5 examples don't throw exceptions
Object.getPrototypeOf(Object)
Object.getPrototypeOf(Object.prototype)
Object.getPrototypeOf(Object.create(null))
Object.getPrototypeOf([])
Object.getPrototypeOf({})
Ответ 4
Официальный underscore.js использует эту проверку, чтобы выяснить, действительно ли что-то является объектом
// Is a given variable an object?
_.isObject = function(obj) {
return obj === Object(obj);
};
ОБНОВИТЬ
Обновленная библиотека underscore.js теперь использует следующее из-за предыдущей ошибки в V8 и незначительной оптимизации микро-скорости.
// Is a given variable an object?
_.isObject = function(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
Ответ 5
Object.prototype.toString.call(myVar)
вернется:
-
"[object Object]"
, если myVar - это объект -
"[object Array]"
, если myVar - это массив - и др.
Для получения дополнительной информации об этом и почему это хорошая альтернатива typeof, ознакомьтесь с этой статьей.
Ответ 6
Для простой проверки объекта или массива без дополнительного вызова функции (скорость). Также опубликовано здесь.
IsArray()
isArray = function(a) {
return (!!a) && (a.constructor === Array);
};
console.log(isArray( )); // false
console.log(isArray( null)); // false
console.log(isArray( true)); // false
console.log(isArray( 1)); // false
console.log(isArray( 'str')); // false
console.log(isArray( {})); // false
console.log(isArray(new Date)); // false
console.log(isArray( [])); // true
isObject() - Примечание: используйте только для литералов Object, поскольку он возвращает false для пользовательских объектов, таких как новая дата или новый объект YourCustomObject.
isObject = function(a) {
return (!!a) && (a.constructor === Object);
};
console.log(isObject( )); // false
console.log(isObject( null)); // false
console.log(isObject( true)); // false
console.log(isObject( 1)); // false
console.log(isObject( 'str')); // false
console.log(isObject( [])); // false
console.log(isObject(new Date)); // false
console.log(isObject( {})); // true
Ответ 7
Я люблю просто:
function isObject (item) {
return (typeof item === "object" && !Array.isArray(item) && item !== null);
}
Если элемент является JS-объектом, и он не является массивом JS, а не null
... если все три являются истинными, верните true
. Если какое-либо из трех условий выходит из строя, тест &&
будет иметь короткое замыкание и false
будет возвращен. При необходимости тест null
можно опустить (в зависимости от того, как вы используете null
).
DOCS:
http://devdocs.io/javascript/operators/typeof
http://devdocs.io/javascript/global_objects/object
Ответ 8
С функцией Array.isArray
:
function isObject(o) {
return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}
Без функции Array.isArray
:
Просто удивился, сколько откликов за неправильные ответы 😮
Только 1 ответ прошел мои тесты !!! Здесь я создал свою упрощенную версию:
function isObject(o) {
return o instanceof Object && o.constructor === Object;
}
Как по мне, так понятно и просто, и просто работает! Вот мои тесты:
console.log(isObject({})); // Will return: true
console.log(isObject([])); // Will return: false
console.log(isObject(null)); // Will return: false
console.log(isObject(/.*/)); // Will return: false
console.log(isObject(function () {})); // Will return: false
ОДИН БОЛЬШЕ ВРЕМЕНИ: не все ответы проходят этот тест !!! 🙈
В случае, если вам нужно проверить, что объект является экземпляром определенного класса, вы должны проверить конструктор с вашим конкретным классом, например:
function isDate(o) {
return o instanceof Object && o.constructor === Date;
}
простой тест:
var d = new Date();
console.log(isObject(d)); // Will return: false
console.log(isDate(d)); // Will return: true
В результате у вас будет строгий и надежный код!
В случае, если вы не будете создавать такие функции, как isDate
, isError
, isRegExp
и т.д., Вы можете рассмотреть возможность использования этих обобщенных функций:
function isObject(o) {
return o instanceof Object && typeof o.constructor === 'function';
}
он не будет работать правильно для всех тестовых случаев, упомянутых ранее, но он достаточно хорош для всех объектов (простых или построенных).
isObject
не будет работать в случае Object.create(null)
из-за внутренней реализации Object.create
которая Object.create
здесь, но вы можете использовать isObject
в более сложной реализации:
function isObject(o, strict = true) {
if (o === null || o === undefined) {
return false;
}
const instanceOfObject = o instanceof Object;
const typeOfObject = typeof o === 'object';
const constructorUndefined = o.constructor === undefined;
const constructorObject = o.constructor === Object;
const typeOfConstructorObject = typeof o.constructor === 'function';
let r;
if (strict === true) {
r = (instanceOfObject || typeOfObject) && (constructorUndefined || constructorObject);
} else {
r = (constructorUndefined || typeOfConstructorObject);
}
return r;
};
На npm v1 уже создан пакет, основанный на этой реализации! И это работает для всех ранее описанных тестовых случаев! 🙂
Ответ 9
Хорошо, давайте сначала дадим вам эту концепцию, прежде чем ответить на ваш вопрос, в JavaScript Функции - это Object, также null, Object, Arrays и даже Date, так что, как вы видите, не существует простого способа, как typeof obj === 'object', поэтому все, что упомянуто выше, вернет true, но есть способы проверить это с помощью написания функции или использования фреймворков JavaScript, хорошо:
Теперь представьте, что у вас есть этот объект, который является реальным объектом (не нулевым, не функцией или массивом):
var obj = {obj1: 'obj1', obj2: 'obj2'};
Чистый JavaScript:
//that how it gets checked in angular framework
function isObject(obj) {
return obj !== null && typeof obj === 'object';
}
или же
//make sure the second object is capitalised
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
или же
function isObject(obj) {
return obj.constructor.toString().indexOf("Object") > -1;
}
или же
function isObject(obj) {
return obj instanceof Object;
}
Вы можете просто использовать одну из этих функций, как указано выше, в своем коде, вызывая их, и она вернет true, если это объект:
isObject(obj);
Если вы используете JavaScript-фреймворк, они обычно готовят для вас такие функции, вот некоторые из них:
JQuery:
//It returns 'object' if real Object;
jQuery.type(obj);
Угловой:
angular.isObject(obj);
Подчеркни и Лодаш:
//(NOTE: in Underscore and Lodash, functions, arrays return true as well but not null)
_.isObject(obj);
Ответ 10
Боже ты мой! Я думаю, что это может быть короче, чем когда-либо, давайте посмотрим на это:
Краткий и окончательный код
function isObject(obj)
{
return obj != null && obj.constructor.name === "Object"
}
console.log(isObject({})) // returns true
console.log(isObject([])) // returns false
console.log(isObject(null)) // returns false
Ответ 11
Это зависит от того, что вы имеете в виду под "является объектом". Если вы хотите все, что не является примитивом, то есть вещи, на которые вы можете установить новые свойства, это должно сработать:
function isAnyObject(value) {
return value != null && (typeof value === 'object' || typeof value === 'function');
}
Он исключает примитивы (простые числа /NaN
/Infinity
, простые строки, символы, true
/false
, undefined
и null
), но должен возвращать true для всего остального (включая [ Объекты TG47, TG48 и TG49). Обратите внимание, что JS не определяет, какие "хостовые" объекты, такие как window
или console
, должны возвращаться при использовании с typeof
, поэтому их трудно покрыть такой проверкой.
Если вы хотите узнать, является ли что-то "простым" объектом, то есть оно было создано как литерал {}
или с помощью Object.create(null)
, вы можете сделать это:
function isPlainObject(value) {
if (Object.prototype.toString.call(value) !== '[object Object]') {
return false;
} else {
var prototype = Object.getPrototypeOf(value);
return prototype === null || prototype === Object.prototype;
}
}
Изменить 2018: поскольку Symbol.toStringTag
теперь позволяет настраивать выходные данные Object.prototype.toString.call(...)
, приведенная выше функция isPlainObject
может возвращать false
в некоторых случаях, даже когда объект начал свою жизнь как буквальный. Можно утверждать, что по соглашению объект с пользовательским строковым тегом больше не является простым объектом, но это еще больше запутало определение того, что такое простой объект даже в Javascript.
Ответ 12
Наиболее разумным способом проверки типа значения является оператор typeof
. Единственная проблема заключается в том, что она ужасно нарушена:
- Он возвращает
"object"
дляnull
, который относится к типу Null. - Он возвращает
"function"
для вызываемых объектов, которые относятся к типу объекта. - Он может возвращать (почти) все, что он хочет для нестандартных не вызываемых объектов. Например, IE, похоже, понравился
"unknown"
. Единственными запрещенными результатами являются"function"
и примитивные типы.
typeof
является надежным только для примитивов null
. Таким образом, способ проверить, является ли значение объектом, будет гарантировать, что строка, возвращаемая typeof
, не соответствует примитиву и что объект не является null
. Однако проблема заключается в том, что будущий стандарт может ввести новый примитивный тип, и наш код будет рассматривать его как объект. Новые типы не появляются часто, но, например, ECMAScript 6 вводит тип символа.
Поэтому вместо typeof
я рекомендую только подходы, результат которых зависит от того, является ли это значение объектом или нет. Следующее намеревается быть
Полный, но не исчерпывающий список правильных способов проверки, принадлежит ли значение типу объекта.
-
Object
конструкторКонструктор
Object
принуждает переданный аргумент к объекту. Если это уже объект, возвращается тот же объект.Следовательно, вы можете использовать его для принуждения значения к объекту и строго сравнить этот объект с исходным значением.
Следующая функция требует ECMAScript 3, в который вводится
===
:function isObject(value) { /* Requires ECMAScript 3 or later */ return Object(value) === value; }
Мне нравится этот подход, потому что он простой и самоописательный, и аналогичная проверка также будет работать для булевых, чисел и строк. Однако имейте в виду, что глобальный
Object
не затенен и не изменен. -
<сильные > Конструкторы
Когда вы создаете экземпляр конструктора, он может возвращать значение, отличное от только что созданного экземпляра. Но это значение будет проигнорировано, если оно не является объектом.
Следующая функция требует ECMAScript 3, который позволяет конструкторам возвращать не объекты. Перед тем, как ECMAScript 3 запустил ошибку, но операторы
try
тогда не существовали.function isObject(value) { /* Requires ECMAScript 3 or later */ return new function() { return value; }() === value; }
В то время как бит менее простой, чем предыдущий пример, он не полагается на какое-либо глобальное свойство и, следовательно, может быть самым безопасным.
-
this
значениеВ старых спецификациях ECMAScript требуется, чтобы значение
this
являлось объектом. В ECMAScript 3 введеноFunction.prototype.call
, что позволило вызвать функцию с произвольным значениемthis
, но принудительно к объекту.В ECMAScript 5 введен строгий режим, который устранил это поведение, но в неаккуратном режиме мы все еще можем (но, возможно, не должны) полагаться на него.
function isObject(value) { /* Requires ECMAScript 3 or later in sloppy mode */ return function() { return this === value; }.call(value); }
-
[[Prototype]]
У всех обычных объектов есть внутренний слот под названием [[Prototype]], значение которого определяет, из какого другого объекта он наследует. Значение может быть только объектом или
null
. Поэтому вы можете попытаться создать объект, который наследует от требуемого значения, и проверить, не сработало ли оно.Оба
Object.create
иObject.getPrototypeOf
требуют ECMAScript 5.function isObject(value) { /* Requires ECMAScript 5 or later */ try { Object.create(value); return value !== null; } catch(err) { return false; } }
function isObject(value) { /* Requires ECMAScript 5 or later */ function Constructor() {} Constructor.prototype = value; return Object.getPrototypeOf(new Constructor()) === value; }
-
Некоторые новые способы ECMAScript 6
В ECMAScript 6 вводятся некоторые новые косвенные способы проверки, является ли значение объектом. Они используют ранее увиденный подход, чтобы передать значение некоторому коду, для которого требуется объект, завернутый внутри оператора
try
, чтобы ловить ошибки. Некоторые скрытые примеры, не стоит комментироватьfunction isObject(value) { /* Requires ECMAScript 6 or later */ try { Object.setPrototypeOf({}, value); return value !== null; } catch(err) { return false; } }
Ответ 13
Боже мой, слишком много путаницы в других ответах.
Короткий ответ
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array)
Чтобы проверить это, просто запустите следующие операторы в консоли Chrome.
Случай 1.
var anyVar = {};
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // true
Случай 2
anyVar = [];
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // false
Случай 3
anyVar = null;
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array); // false
объяснение
Хорошо. Давайте разберемся
typeof anyVar == 'object'
возвращается true из трех кандидатов - [], {} and null
,
anyVar instanceof Object
сужает этих кандидатов до двух - [], {}
!(anyVar instanceof Array)
сужается только до одного - {}
Барабанная дробь, пожалуйста!
К этому вы, возможно, уже научились проверять массив в Javascript.
Ответ 14
Попробуйте это
if (objectName instanceof Object == false) {
alert('Not an object');
}
else {
alert('An object');
}
Ответ 15
var a = [1]
typeof a //"object"
a instanceof Object //true
a instanceof Array //true
var b ={a: 1}
b instanceof Object //true
b instanceof Array //false
var c = null
c instanceof Object //false
c instanceof Array //false
Меня попросили предоставить более подробную информацию. Наиболее чистым и понятным способом проверки, является ли наша переменная объектом, является typeof myVar
. Он возвращает строку с типом (например, "object"
, "undefined"
).
К сожалению, Array и null также имеют тип object
. Чтобы брать только реальные объекты, необходимо проверить цепочку наследования с помощью оператора instanceof
. Он устранит null, но Array имеет Object в цепочке наследования.
Итак, решение:
if (myVar instanceof Object && !(myVar instanceof Array)) {
// code for objects
}
Ответ 16
Готов к использованию функций для проверки
function isObject(o) {
return null != o &&
typeof o === 'object' &&
Object.prototype.toString.call(o) === '[object Object]';
}
function isDerivedObject(o) {
return !isObject(o) &&
null != o &&
(typeof o === 'object' || typeof o === 'function') &&
/^\[object /.test(Object.prototype.toString.call(o));
}
// Loose equality operator (==) is intentionally used to check
// for undefined too
// Also note that, even null is an object, within isDerivedObject
// function we skip that and always return false for null
Объяснение
-
В Javascript
null
,Object
,Array
,Date
иfunction
- все объекты. Хотя,null
бит изобретен. Итак, сначала лучше проверитьnull
, чтобы обнаружить его не null. -
Проверка
typeof o === 'object'
гарантирует, чтоo
является объектом. Без этой проверкиObject.prototype.toString
будет бессмысленным, так как он вернет объект на все, даже дляundefined
иnull
! Например:toString(undefined)
возвращает[object Undefined]
!После
typeof o === 'object'
check, toString.call(o) - отличный способ проверить, является лиo
объектом, производным объектом, напримерArray
,Date
илиfunction
. -
В функции
isDerivedObject
он проверяет, что функцияo
является функцией. Потому что, функция тоже объект, вот почему он там. Если он этого не сделал, функция вернется как false. Пример:isDerivedObject(function() {})
вернетfalse
, однако теперь он возвращаетtrue
. -
Всегда можно изменить определение того, что является объектом. Таким образом, можно соответствующим образом изменить эти функции.
Испытания
function isObject(o) {
return null != o &&
typeof o === 'object' &&
Object.prototype.toString.call(o) === '[object Object]';
}
function isDerivedObject(o) {
return !isObject(o) &&
null != o &&
(typeof o === 'object' || typeof o === 'function') &&
/^\[object /.test(Object.prototype.toString.call(o));
}
// TESTS
// is null an object?
console.log(
'is null an object?', isObject(null)
);
console.log(
'is null a derived object?', isDerivedObject(null)
);
// is 1234 an object?
console.log(
'is 1234 an object?', isObject(1234)
);
console.log(
'is 1234 a derived object?', isDerivedObject(1234)
);
// is new Number(1234) an object?
console.log(
'is new Number(1234) an object?', isObject(new Number(1234))
);
console.log(
'is new Number(1234) a derived object?', isDerivedObject(1234)
);
// is function object an object?
console.log(
'is (new (function (){})) an object?',
isObject((new (function (){})))
);
console.log(
'is (new (function (){})) a derived object?',
isObject((new (function (){})))
);
// is {} an object?
console.log(
'is {} an object?', isObject({})
);
console.log(
'is {} a derived object?', isDerivedObject({})
);
// is Array an object?
console.log(
'is Array an object?',
isObject([])
)
console.log(
'is Array a derived object?',
isDerivedObject([])
)
// is Date an object?
console.log(
'is Date an object?', isObject(new Date())
);
console.log(
'is Date a derived object?', isDerivedObject(new Date())
);
// is function an object?
console.log(
'is function an object?', isObject(function(){})
);
console.log(
'is function a derived object?', isDerivedObject(function(){})
);
Ответ 17
Немного поздно... для "простых объектов" (я имею в виду, например {'x': 5, 'y': 7}) У меня есть этот маленький фрагмент:
function isPlainObject(o) {
return ((o === null) || Array.isArray(o) || typeof o == 'function') ?
false
:(typeof o == 'object');
}
Он генерирует следующий вывод:
console.debug(isPlainObject(isPlainObject)); //function, false
console.debug(isPlainObject({'x': 6, 'y': 16})); //literal object, true
console.debug(isPlainObject(5)); //number, false
console.debug(isPlainObject(undefined)); //undefined, false
console.debug(isPlainObject(null)); //null, false
console.debug(isPlainObject('a')); //string, false
console.debug(isPlainObject([])); //array?, false
console.debug(isPlainObject(true)); //bool, false
console.debug(isPlainObject(false)); //bool, false
Это всегда работает для меня. Если будет возвращено "true", только если тип "o" - "объект", но не null, или массив или функция. :)
Ответ 18
lodash имеет isPlainObject, и это может быть то, что ищут многие, которые приходят на эту страницу. Он возвращает false, когда дает функцию или массив.
Ответ 19
Когда все остальное терпит неудачу, я использую это:
var isObject = function(item) {
return item.constructor.name === "Object";
};
Ответ 20
Это будет работать Это функция, которая возвращает истину, ложь или, возможно, ноль.
const isObject = obj => obj && obj.constructor && obj.constructor === Object;
console.log(isObject({})); // true
console.log(isObject([])); // false
console.log(isObject(new Function)); // false
console.log(isObject(new Number(123))); // false
console.log(isObject(null)); // null
Ответ 21
Поскольку кажется, что существует правильное решение этой проблемы, я оставлю свои 2 цента (этот ответ соответствует спецификации и дает правильные результаты при любых обстоятельствах):
Тестирование на примитивы:
undefined
null
boolean
string
number
function isPrimitive(o){return typeof o!=='object'||null}
Объект не является примитивом:
function isObject(o){return !isPrimitive(o)}
Или альтернативно:
function isObject(o){return o instanceof Object}
function isPrimitive(o){return !isObject(o)}
Тестирование любого массива:
const isArray=(function(){
const arrayTypes=Object.create(null);
arrayTypes['Array']=true;
arrayTypes['Int8Array']=true;
arrayTypes['Uint8Array']=true;
arrayTypes['Uint8ClampedArray']=true;
arrayTypes['Int16Array']=true;
arrayTypes['Uint16Array']=true;
arrayTypes['Int32Array']=true;
arrayTypes['Uint32Array']=true;
arrayTypes['BigInt64Array']=true;
arrayTypes['BigUint64Array']=true;
arrayTypes['Float32Array']=true;
arrayTypes['Float64Array']=true;
return function(o){
if (!o) return false;
return !isPrimitive(o)&&!!arrayTypes[o.constructor.name];
}
}());
Тестирование объекта, исключая: Date
RegExp
Boolean
Number
String
Function
любой массив
const isObjectStrict=(function(){
const nativeTypes=Object.create(null);
nativeTypes['Date']=true;
nativeTypes['RegExp']=true;
nativeTypes['Boolean']=true;
nativeTypes['Number']=true;
nativeTypes['String']=true;
nativeTypes['Function']=true;
return function(o){
if (!o) return false;
return !isPrimitive(o)&&!isArray(o)&&!nativeTypes[o.constructor.name];
}
}());
Ответ 22
Функциональная библиотека Ramda имеет замечательную функцию для обнаружения типов JavaScript.
Перефразируя полную функцию:
function type(val) {
return val === null ? 'Null' :
val === undefined ? 'Undefined' :
Object.prototype.toString.call(val).slice(8, -1);
}
Мне пришлось смеяться, когда я понял, насколько простым и красивым было решение.
Пример использования из документации Ramda:
R.type({}); //=> "Object"
R.type(1); //=> "Number"
R.type(false); //=> "Boolean"
R.type('s'); //=> "String"
R.type(null); //=> "Null"
R.type([]); //=> "Array"
R.type(/[A-z]/); //=> "RegExp"
R.type(() => {}); //=> "Function"
R.type(undefined); //=> "Undefined"
Ответ 23
var isObject = function(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
!!obj
является сокращением для проверки того, является ли объект правдоподобным (чтобы отфильтровать значение null/ undefined)
Ответ 24
if(typeof value === 'object' && value.constructor === Object)
{
console.log("This is an object");
}
Ответ 25
Если вы хотите проверить, является ли prototype
для object
исключительно из Object
. Фильтрует String
, Number
, Array
, Arguments
и т.д.
function isObject(n) {
if (n == null) return false;
return Object.prototype.toString.call(n) === '[object Object]';
}
Ответ 26
Что я люблю использовать, это
function isObject (obj) {
return typeof(obj) == "object"
&& !Array.isArray(obj)
&& obj != null
&& obj != ""
&& !(obj instanceof String) }
Я думаю, что в большинстве случаев дата должна передать проверку как объект, поэтому я не фильтрую даты
Ответ 27
Я нашел "новый" способ сделать именно этот тип проверки типов из этого SO-вопроса: Почему instanceof возвращает false для некоторых литералов?
я создал функцию для проверки типа следующим образом:
function isVarTypeOf(_var, _type){
try {
return _var.constructor === _type;
} catch(ex) {
return false; //fallback for null or undefined
}
}
то вы можете просто сделать:
console.log(isVarTypeOf('asdf', String)); // returns true
console.log(isVarTypeOf(new String('asdf'), String)); // returns true
console.log(isVarTypeOf(123, String)); // returns false
console.log(isVarTypeOf(123, Number)); // returns true
console.log(isVarTypeOf(new Date(), String)); // returns false
console.log(isVarTypeOf(new Date(), Number)); // returns false
console.log(isVarTypeOf(new Date(), Date)); // returns true
console.log(isVarTypeOf([], Object)); // returns false
console.log(isVarTypeOf([], Array)); // returns true
console.log(isVarTypeOf({}, Object)); // returns true
console.log(isVarTypeOf({}, Array)); // returns false
console.log(isVarTypeOf(null, Object)); // returns false
console.log(isVarTypeOf(undefined, Object)); // returns false
console.log(isVarTypeOf(false, Boolean)); // returns true
это проверено на Chrome 56, Firefox 52, Microsoft Edge 38, Internet Explorer 11, Opera 43
изменить
если вы также хотите проверить, равна ли переменная null или undefined, вы можете использовать это вместо:
function isVarTypeOf(_var, _type){
try {
return _var.constructor === _type;
} catch(ex) {
return _var == _type; //null and undefined are considered the same
// or you can use === if you want to differentiate them
}
}
var a = undefined, b = null;
console.log(isVarTypeOf(a, undefined)) // returns true
console.log(isVarTypeOf(b, undefined)) // returns true
console.log(isVarTypeOf(a, null)) // returns true
обновление от комментария inanc: вызов принят: D
Если вы хотите потерять объекты сравнения, вы можете попробовать таким образом:
function isVarTypeOf(_var, _type, looseCompare){
if (!looseCompare){
try {
return _var.constructor === _type;
} catch(ex){
return _var == _type;
}
} else {
try{
switch(_var.constructor){
case Number:
case Function:
case Boolean:
case Symbol:
case Date:
case String:
case RegExp:
// add all standard objects you want to differentiate here
return _var.constructor === _type;
case Error:
case EvalError:
case RangeError:
case ReferenceError:
case SyntaxError:
case TypeError:
case URIError:
// all errors are considered the same when compared to generic Error
return (_type === Error ? Error : _var.constructor) === _type;
case Array:
case Int8Array:
case Uint8Array:
case Uint8ClampedArray:
case Int16Array:
case Uint16Array:
case Int32Array:
case Uint32Array:
case Float32Array:
case Float64Array:
// all types of array are considered the same when compared to generic Array
return (_type === Array ? Array : _var.constructor) === _type;
case Object:
default:
// the remaining are considered as custom class/object, so treat it as object when compared to generic Object
return (_type === Object ? Object : _var.constructor) === _type;
}
} catch(ex){
return _var == _type; //null and undefined are considered the same
// or you can use === if you want to differentiate them
}
}
}
таким образом, вы можете сделать так, как комментарий inanc:
isVarTypeOf(new (function Foo(){}), Object); // returns false
isVarTypeOf(new (function Foo(){}), Object, true); // returns true
или
Foo = function(){};
Bar = function(){};
isVarTypeOf(new Foo(), Object); // returns false
isVarTypeOf(new Foo(), Object, true); // returns true
isVarTypeOf(new Bar(), Foo, true); // returns false
isVarTypeOf(new Bar(), Bar, true); // returns true
isVarTypeOf(new Bar(), Bar); // returns true
Ответ 28
Если вы уже используете AngularJS, у него есть встроенный метод, который проверяет, является ли его объектом (без принятия значения null).
angular.isObject(...)
Ответ 29
Рассмотрим - typeof bar === "object"
чтобы определить, является ли bar
объектом
Несмотря на то, что typeof bar === "object"
является надежным способом проверки, является ли bar объектом, в коде JavaScript неожиданным является то, что null также считается объектом!
Поэтому, к удивлению большинства разработчиков, следующий код записывает в консоль true (не false):
var bar = null;
console.log(typeof bar === "object");//logs true!
Пока кто-то знает об этом, проблему можно легко избежать, также проверив, имеет ли значение null значение bar:
console.log((bar !== null) && (typeof bar === "object"));//logs false
console.log((bar !== null) && (typeof bar === "object"));//logs false
Чтобы быть полностью тщательным в нашем ответе, следует отметить еще две вещи:
Во-первых, приведенное выше решение вернет false, если bar является функцией. В большинстве случаев это желаемое поведение, но в ситуациях, когда вы также хотите вернуть true для функций, вы можете изменить приведенное выше решение так:
console.log((bar !== null) && ((typeof bar === "object") || (typeof bar === "function")));
Во-вторых, вышеприведенное решение вернет true, если bar является массивом (например, если var bar = [];
). В большинстве случаев это желаемое поведение, так как массивы действительно являются объектами, но в ситуациях, когда вы также хотите использовать false для массивов, вы можете изменить приведенное выше решение так:
console.log((bar !== null) && (typeof bar === "object") && (toString.call(bar) !== "[object Array]"));
Тем не менее, есть еще одна альтернатива, которая возвращает false для нулей, массивов и функций, но true для объектов:
console.log((bar !== null) && (bar.constructor === Object));
Или, если вы используете jQuery:
console.log((bar !== null) && (typeof bar === "object") && (! $.isArray(bar)));
ES5 делает случай массива довольно простым, включая собственную проверку нуля:
console.log(Array.isArray(bar));
Ответ 30
Прочитав и опробовав много реализаций, я заметил, что очень немногие люди пытаются проверять такие значения, как JSON
, Math
, document
или объекты с цепочками прототипов длиннее 1 шага.
Вместо того, чтобы проверять typeof
нашей переменной и затем взламывать крайние случаи, я подумал, что было бы лучше, если бы проверка оставалась максимально простой, чтобы избежать необходимости проводить рефакторинг, когда добавляются новые примитивы или собственные объекты, которые регистрируются как typeof
из "объекта".
В конце концов, оператор typeof
скажет вам, является ли что-то объектом JavaScript, но определение объекта JavaScript слишком широко для большинства реальных сценариев (например, typeof null === 'object'
).
Ниже приведена функция, которая определяет, является ли переменная v
объектом, по сути, повторяя две проверки:
- Запускается цикл, который продолжается до тех пор, пока строковой версией
v
является'[object Object]'
.
Я хотел, чтобы результат функции был точно таким же, как в журналах ниже, так что это единственная "объектность" -criteria, с которой я закончил. Если это не удается, функция сразу возвращает false. v
заменяется следующим прототипом в цепочке наv = Object.getPrototypeOf(v)
, но также оценивается непосредственно после. Когда новое значениеv
равноnull
, это означает, что каждый прототип, включая корневой прототип (который вполне мог быть единственным прототипом внутри цепочки), прошел проверка в цикле while, и мы можем вернуть true. В противном случае начинается новая итерация.
function isObj (v) {
while ( Object.prototype.toString.call(v) === '[object Object]')
if ((v = Object.getPrototypeOf(v)) === null)
return true
return false
}
console.log('FALSE:')
console.log('[] -> ', isObj([]))
console.log('null -> ', isObj(null))
console.log('document -> ', isObj(document))
console.log('JSON -> ', isObj(JSON))
console.log('function -> ', isObj(function () {}))
console.log('new Date() -> ', isObj(new Date()))
console.log('RegExp -> ', isObj(/./))
console.log('TRUE:')
console.log('{} -> ', isObj({}))
console.log('new Object() -> ', isObj(new Object()))
console.log('new Object(null) -> ', isObj(new Object(null)))
console.log('new Object({}) -> ', isObj(new Object({foo: 'bar'})))
console.log('Object.prototype -> ', isObj(Object.prototype))
console.log('Object.create(null) -> ', isObj(Object.create(null)))
console.log('Object.create({}) -> ', isObj(Object.create({foo: 'bar'})))
console.log('deep inheritance -> ', isObj(Object.create(Object.create({foo: 'bar'}))))