Проверьте, является ли значение объектом в 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

http://devdocs.io/javascript/global_objects/array/isarray

http://devdocs.io/javascript/global_objects/null

Ответ 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 объектом, по сути, повторяя две проверки:

  1. Запускается цикл, который продолжается до тех пор, пока строковой версией v является '[object Object]'.
    Я хотел, чтобы результат функции был точно таким же, как в журналах ниже, так что это единственная "объектность" -criteria, с которой я закончил. Если это не удается, функция сразу возвращает false.
  2. 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'}))))