Check if a value is an object in JavaScript

后端 未结 30 3280
臣服心动
臣服心动 2020-11-22 05:06

How do you check if a value is an object in JavaScript?

相关标签:
30条回答
  • 2020-11-22 05:39

    Let's define "object" in Javascript. According to the MDN docs, every value is either an object or a primitive:

    primitive, primitive value

    A data that is not an object and does not have any methods. JavaScript has 5 primitive datatypes: string, number, boolean, null, undefined.

    What's a primitive?

    • 3
    • 'abc'
    • true
    • null
    • undefined

    What's an object (i.e. not a primitive)?

    • Object.prototype
    • everything descended from Object.prototype
      • Function.prototype
        • Object
        • Function
        • function C(){} -- user-defined functions
      • C.prototype -- the prototype property of a user-defined function: this is not Cs prototype
        • new C() -- "new"-ing a user-defined function
      • Math
      • Array.prototype
        • arrays
      • {"a": 1, "b": 2} -- objects created using literal notation
      • new Number(3) -- wrappers around primitives
      • ... many other things ...
    • Object.create(null)
    • everything descended from an Object.create(null)

    How to check whether a value is an object

    instanceof by itself won't work, because it misses two cases:

    // oops:  isObject(Object.prototype) -> false
    // oops:  isObject(Object.create(null)) -> false
    function isObject(val) {
        return val instanceof Object; 
    }
    

    typeof x === 'object' won't work, because of false positives (null) and false negatives (functions):

    // oops: isObject(Object) -> false
    function isObject(val) {
        return (typeof val === 'object');
    }
    

    Object.prototype.toString.call won't work, because of false positives for all of the primitives:

    > Object.prototype.toString.call(3)
    "[object Number]"
    
    > Object.prototype.toString.call(new Number(3))
    "[object Number]"
    

    So I use:

    function isObject(val) {
        if (val === null) { return false;}
        return ( (typeof val === 'function') || (typeof val === 'object') );
    }
    

    @Daan's answer also seems to work:

    function isObject(obj) {
      return obj === Object(obj);
    }
    

    because, according to the MDN docs:

    The Object constructor creates an object wrapper for the given value. If the value is null or undefined, it will create and return an empty object, otherwise, it will return an object of a type that corresponds to the given value. If the value is an object already, it will return the value.


    A third way that seems to work (not sure if it's 100%) is to use Object.getPrototypeOf which throws an exception if its argument isn't an object:

    // 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({})
    
    0 讨论(0)
  • 2020-11-22 05:39

    For simply checking against Object or Array without additional function call (speed). As also posted here.

    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() - Note: use for Object literals only, as it returns false for custom objects, like new Date or new 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
    
    0 讨论(0)
  • 2020-11-22 05:40

    OK, let's give you this concept first before answering your question, in JavaScript Functions are Object, also null, Object, Arrays and even Date, so as you see there is not a simple way like typeof obj === 'object', so everything mentioned above will return true, but there are ways to check it with writing a function or using JavaScript frameworks, OK:

    Now, imagine you have this object that's a real object (not null or function or array):

    var obj = {obj1: 'obj1', obj2: 'obj2'};
    

    Pure JavaScript:

    //that's how it gets checked in angular framework
    function isObject(obj) {
      return obj !== null && typeof obj === 'object';
    }
    

    or

    //make sure the second object is capitalised 
    function isObject(obj) {
       return Object.prototype.toString.call(obj) === '[object Object]';
    }
    

    or

    function isObject(obj) {
        return obj.constructor.toString().indexOf("Object") > -1;
    }
    

    or

    function isObject(obj) {
        return obj instanceof Object;
    }
    

    You can simply use one of these functions as above in your code by calling them and it will return true if it's an object:

    isObject(obj);
    

    If you are using a JavaScript framework, they usually have prepared these kind of functions for you, these are few of them:

    jQuery:

     //It returns 'object' if real Object;
     jQuery.type(obj);
    

    Angular:

    angular.isObject(obj);
    

    Underscore and Lodash:

    //(NOTE: in Underscore and Lodash, functions, arrays return true as well but not null)
    _.isObject(obj);
    
    0 讨论(0)
  • 2020-11-22 05:42

    The Ramda functional library has a wonderful function for detecting JavaScript types.

    Paraphrasing the full function:

    function type(val) {
      return val === null      ? 'Null'      :
             val === undefined ? 'Undefined' :
             Object.prototype.toString.call(val).slice(8, -1);
    }
    

    I had to laugh when I realized how simple and beautiful the solution was.

    Example usage from Ramda documentation:

    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"
    
    0 讨论(0)
  • 2020-11-22 05:43

    I'm fond of simply:

    function isObject (item) {
      return (typeof item === "object" && !Array.isArray(item) && item !== null);
    }
    

    If the item is a JS object, and it's not a JS array, and it's not null…if all three prove true, return true. If any of the three conditions fails, the && test will short-circuit and false will be returned. The null test can be omitted if desired (depending on how you use 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

    0 讨论(0)
  • 2020-11-22 05:43

    With function Array.isArray:

    function isObject(o) {
      return o !== null && typeof o === 'object' && Array.isArray(o) === false;
    }
    

    Without function Array.isArray:

    Just surprised how many upvotes for wrong answers

    0 讨论(0)
提交回复
热议问题