admin管理员组

文章数量:1425864

I know just about everything is considered an object in JavaScript. I am making a function which specifically requires the argument it accepts to be in this format:

{
   a: 'b',
   c: 'd'
}

So this type of key value pair inside curly braces sort of object not the other type of objects. How to validate for this specifically?

I know just about everything is considered an object in JavaScript. I am making a function which specifically requires the argument it accepts to be in this format:

{
   a: 'b',
   c: 'd'
}

So this type of key value pair inside curly braces sort of object not the other type of objects. How to validate for this specifically?

Share Improve this question edited Apr 5, 2013 at 3:21 Phil 165k25 gold badges262 silver badges267 bronze badges asked Apr 5, 2013 at 3:12 user967451user967451 4
  • 3 This has been answered many many times: {}.toString.call(obj) == "[object Object]". – elclanrs Commented Apr 5, 2013 at 3:13
  • possible duplicate of How do I get the name of an object's type in JavaScript? – bfavaretto Commented Apr 5, 2013 at 3:22
  • @elclanrs For some reason, the Chrome console doesn't like the dot in {}.toString – Phil Commented Apr 5, 2013 at 3:22
  • 1 Try: ({}).toString or Object.prototype.toString. – elclanrs Commented Apr 5, 2013 at 3:23
Add a ment  | 

6 Answers 6

Reset to default 2

Update: After writing all of the below and later giving it further thought, I'd like to suggest that you take another look at Trevor's answer. I think it is more deserving of that beautiful green checkmark than my answer, and here's why.

I took your question at face value and ran with it: If you really want to do literally what you said, a function like $.isPlainObject() is the way to go. But is that really what you need to do? Keep in mind that $.isPlainObject() is not a very efficient function; it enumerates through all your object's properties. And as I noted below, it can't distinguish between {} and new Object().

Instead of all that, Trevor suggests simply checking for the properties you need, and for most cases, most of the time, I think he's right. It's definitely closer to the approach I take in my own code: validate what I need, ignore the rest.

So do take another look at his answer and carefully consider it. (And I won't be offended if you move the checkmark!)

Now my original answer:

There's a $.isPlainObject() function in jQuery. If you're not using jQuery, you can copy the source code for this function into your app. Open the jQuery source and search for isPlainObject:.

It's worth reading the source for this function in any case, to see that it isn't as simple as an typeof or instanceOf check:

isPlainObject: function( obj ) {
    // Must be an Object.
    // Because of IE, we also have to check the presence of the constructor property.
    // Make sure that DOM nodes and window objects don't pass through, as well
    if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
        return false;
    }

    try {
        // Not own constructor property must be Object
        if ( obj.constructor &&
            !core_hasOwn.call(obj, "constructor") &&
            !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
            return false;
        }
    } catch ( e ) {
        // IE8,9 Will throw exceptions on certain host objects #9897
        return false;
    }

    // Own properties are enumerated firstly, so to speed up,
    // if last one is own, then all properties are own.

    var key;
    for ( key in obj ) {}

    return key === undefined || core_hasOwn.call( obj, key );
},

type: function( obj ) {
    if ( obj == null ) {
        return String( obj );
    }
    return typeof obj === "object" || typeof obj === "function" ?
        class2type[ core_toString.call(obj) ] || "object" :
        typeof obj;
},

isWindow: function( obj ) {
    return obj != null && obj == obj.window;
},

And there is also the class2type object that this code uses:

// [[Class]] -> type pairs
class2type = {},

// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
    class2type[ "[object " + name + "]" ] = name.toLowerCase();
});

(These code snippets are out of context; you'd need to tweak the syntax if you were using them standalone.)

Of course depending on the circumstances, you may not need all of these checks. And if you're using jQuery already, you can just call $.isPlainObject() and not sweat the details.

Also note that it is not possible to distinguish an object literal from an object created with new Object:

var obj1 = { a:'b', c:'d' };

var obj2 = new Object();
obj2.a = 'b';
obj2.c = 'd';

console.log( $.isPlainObject(obj1) );  // prints true
console.log( $.isPlainObject(obj2) );  // also prints true!

They both return true from $.isPlainObject(), and I'm pretty sure that any other test you devise will be unable to tell which is which either.

A funny historical note: When John Resig added this function to jQuery back in 2009, he was originally going to call it $.isObjectLiteral(). At my urging he changed the name to $.isPlainObject because of this ambiguity.

In the situation you've described, I wouldn't worry about making sure it's not an array or some other kind of object. Just make sure the properties you need are there, and if they're missing, sound the alarm.

function needAandC(params) {
    if (params.a === undefined || params.c === undefined)
        throw new Error('Ahhh.');

    // You've got what you need, don't worry what else is there.
}

by using typeof

var obj = {x: 1, y: 2};
if (typeof obj == 'object') console.log('im an object');

This checks whether value is an object and wether it has properties a and c:

var value = {a: 1, c: 2};
if (typeof value === "object" && "a" in value && "c" in value)
{
    ...
}

Pitfalls:

  • typeof of Arrays is 'object'

    typeof [] === 'object' //true
    
  • Array is an instance of Object

    Array instanceof Object //true
    
  • typeof null is 'object'

    typeof null === 'object' //true
    

You can do this which checks if:

  • arg is truthy. Since null is falsy, it's weeded here.
  • typeof arg is 'object'. AFAIK, only arrays and objects pass on this one.
  • finally, if arg is not instance of Array

    if(arg && typeof arg === 'object' && !(arg instanceof Array){...}
    

It also depends on what exactly you want to assert. As for most mon case - parameter (or contract) validation, I recently noticed NPM team (https://github./npm/cli) relies on https://github./iarna/aproba function, which freakishly lightweight and simple:

validate("O", [ val ]); // if val is not object, throws an exception

What the function does:

var isObject = ( typeof val === 'object' && val !== null && !Array.isArray( val ) 
  &&  !( val instanceof Error ) && !isArguments( val ) );

function isArguments (thingy) {
  return thingy != null && typeof thingy === 'object' && thingy.hasOwnProperty('callee')
}

本文标签: javascriptHow to check if an argument is an objectStack Overflow