如何检查值是否是JavaScript中的对象?


当前回答

if(typeof value === 'object' && value.constructor === Object)
{
    console.log("This is an object");
}

其他回答

一个基于Matt Fenwick对其完整答案的第三个选项的NodeJS控制台实验。只要稍微调整一下就能判断真假。

以下对象测试返回false。

> if(Object.getPrototypeOf('v') === Object.prototype){console.log(true);}else{console.log(false);}
false
undefined
> if(Object.getPrototypeOf(1) === Object.prototype){console.log(true);}else{console.log(false);}
false
undefined
> if(Object.getPrototypeOf(false) === Object.prototype){console.log(true);}else{console.log(false);}
false
undefined
> if(Object.getPrototypeOf(['apple']) === Object.prototype){console.log(true);}else{console.log(false);}
false
undefined

对象将返回true。

> if(Object.getPrototypeOf({'this':10}) === Object.prototype){console.log(true);}else{console.log(false);}
true
undefined

简单的工作解决方案:

function isObject(value) {
    return !(value instanceof Date) && !Array.isArray(value) && !Object.is(value, null) && !Object.is(value, undefined) && !(value instanceof Function)
}

好的,在回答问题之前,让我们先给你这个概念,在JavaScript中,函数是Object,也可以是null、Object、Array甚至Date,所以正如你所看到的,没有一种简单的方法像typeof obj==“Object”,所以上面提到的一切都会返回true,但是有一些方法可以通过编写函数或使用JavaScript框架来检查它,好的:

现在,假设您有一个真正的对象(不是null、函数或数组):

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

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

您可以简单地在代码中使用上述函数之一,方法是调用它们,如果它是一个对象,则返回true:

isObject(obj);

如果您使用的是JavaScript框架,他们通常会为您准备这些类型的函数,其中很少:

jQuery:

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

角度:

angular.isObject(obj);

Undercore和Lodash:

//(NOTE: in Underscore and Lodash, functions, arrays return true as well but not null)
_.isObject(obj);

我从这个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上进行了测试

编辑:如果您还想检查变量是否为空或未定义,则可以使用以下方法:

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

财务评论更新:接受挑战: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
        }
    }
}

这样,你就可以像finance的评论一样:

isVarTypeOf(new (function Foo(){}), Object); // returns false
isVarTypeOf(new (function Foo(){}), Object, true); // returns true

or

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

可随时使用的检查功能

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和函数都是对象。虽然,null有点做作。因此,最好先检查空值,以检测它是否为空。检查o==“object”的类型可确保o是一个对象。如果不进行此检查,Object.prototype.toString将毫无意义,因为它将返回任何对象,即使是未定义和null!例如:toString(undefined)返回[object undefined]!在typeofo=='object'检查之后,toString.call(o)是一个很好的方法来检查o是一个对象,还是一个派生对象,如Array、Date或函数。在isDerivedObject函数中,它检查o是否为函数。因为,函数也是一个对象,这就是它存在的原因。若并没有这样做,函数将返回false。示例:isDerivedObject(function(){})将返回false,但现在返回true。人们总是可以改变对象的定义。因此,可以相应地更改这些函数。


测验

函数isObject(o){返回null!=o&&typeof o==“对象”&&Object.pr原型.toString.call(o)==“[对象对象]”;}函数isDerivedObject(o){回来isObject(o)&&空!=o&&(类型o==“对象”| |类型o===“函数”)&&/^\[object/.test(object.protype.toString.call(o));}//测试//null是对象吗?控制台日志('是空的对象吗?',isObject(空));控制台日志('是否为null派生对象?',isDerivedObject(空));//1234是一个对象吗?控制台日志('1234是对象吗?',isObject(1234));控制台日志('1234是派生对象吗?',isDerivedObject(1234));//新编号(1234)是对象吗?控制台日志('新编号(1234)是对象吗?',isObject(新编号(1234)));控制台日志('新编号(1234)是派生对象吗?',isDerivedObject(1234));//函数对象是对象吗?控制台日志('是(new(function(){}))对象吗?',isObject((new(函数(){})));控制台日志(“(new(function(){}))是派生对象吗?”,isObject((new(函数(){})));//{}是对象吗?控制台日志(“是{}对象吗?”,isObject({}));控制台日志(“{}是派生对象吗?”,isDerivedObject({}));//Array是对象吗?控制台日志('数组是对象吗?',isObject([]))控制台日志('数组是派生对象吗?',isDerivedObject([]))//Date是对象吗?控制台日志('日期是对象吗?',isObject(新日期()));控制台日志('日期是派生对象吗?',isDerivedObject(新日期()));//函数是对象吗?控制台日志('函数是对象吗?',isObject(函数(){}));控制台日志('函数是派生对象吗?',isDerivedObject(函数(){}));