Check if a value is an object in JavaScript

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

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

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

    Ready to use functions for checking

    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
    

    Explanation

    • In Javascript, null, Object, Array, Date and functions are all objects. Although, null is bit contrived. So, it's better to check for the null first, to detect it's not null.

    • Checking for typeof o === 'object' guarantees that o is an object. Without this check, Object.prototype.toString would be meaningless, since it would return object for everthing, even for undefined and null! For example: toString(undefined) returns [object Undefined]!

      After typeof o === 'object' check, toString.call(o) is a great method to check whether o is an object, a derived object like Array, Date or a function.

    • In isDerivedObject function, it checks for the o is a function. Because, function also an object, that's why it's there. If it didn't do that, function will return as false. Example: isDerivedObject(function() {}) would return false, however now it returns true.

    • One can always change the definition of what is an object. So, one can change these functions accordingly.


    Tests

    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(){})
    );

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

    When everything else fails, I use this:

    var isObject = function(item) {
       return item.constructor.name === "Object";
    }; 
    
    0 讨论(0)
  • 2020-11-22 05:52

    For the purpose of my code I found out this decision which corresponds with some of the answers above:

    ES6 variant:

    const checkType = o => Object.prototype
                        .toString
                        .call(o)
                        .replace(/\[|object\s|\]/g, '')
                        .toLowerCase();
    

    ES5 variant:

    function checkType(o){
       return Object.prototype
                        .toString
                        .call(o)
                        .replace(/\[|object\s|\]/g, '')
                        .toLowerCase();
    }
    

    You can use it very simply:

    checkType([]) === 'array'; // true
    checkType({}) === 'object'; // true
    checkType(1) === 'number'; // true
    checkType('') === 'string'; // true
    checkType({}.p) === 'undefined'; // true
    checkType(null) === 'null'; // true
    

    and so on..

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

    Since there seems a lot of confusion about how to handle this problem correctly, I'll leave my 2 cents (this answer is spec compliant and produces correct results under all circumstances):

    Testing for primitives: undefined null boolean string number

    function isPrimitive(o){return typeof o!=='object'||null}
    

    An object is not a primitive:

    function isObject(o){return !isPrimitive(o)}
    

    Or alternatively:

    function isObject(o){return o instanceof Object}
    function isPrimitive(o){return !isObject(o)}
    

    Testing for any Array:

    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];
        }
    }());
    

    Testing for object excluding: Date RegExp Boolean Number String Function any Array

    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];
        }
    }());
    
    0 讨论(0)
  • 2020-11-22 05:53
    if(typeof value === 'object' && value.constructor === Object)
    {
        console.log("This is an object");
    }
    
    0 讨论(0)
  • 2020-11-22 05:54

    It depends on what you mean with "is an object". If you want everything that is not a primitive, i.e. things that you can set new properties on, this should do the trick:

    function isAnyObject(value) {
        return value != null && (typeof value === 'object' || typeof value === 'function');
    }
    

    It excludes the primitives (plain numbers/NaN/Infinity, plain strings, symbols, true/false, undefined and null) but should return true for everything else (including Number, Boolean and String objects). Note that JS does not define what "host" objects, such as window or console, should return when used with typeof, so those are hard to cover with a check like this.

    If you want to know whether something is a "plain" object, i.e. it was created as a literal {} or with Object.create(null), you might do this:

    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;
        }
    }
    

    Edit 2018: Because Symbol.toStringTag now allows customizing the output of Object.prototype.toString.call(...), the isPlainObject function above might return false in some cases even when the object started its life as a literal. Arguably, by convention an object with a custom string tag isn't exactly a plain object any more, but this has further muddied the definition of what a plain object even is in Javascript.

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