我知道几乎所有东西都被认为是JavaScript中的对象。我正在制作一个函数,专门要求它接受的参数采用以下格式:

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

因此,花括号内的这种类型的键值对不是其他类型的对象。如何对此进行具体验证?

最佳答案

更新:写完所有下面的内容,然后再作进一步考虑后,我建议您再看看Trevor's answer。我认为这比我的答案更值得那个美丽的绿色对勾,这就是原因。

我对您的面值提出了质疑,并坚持认为:如果您确实想按字面意思做,那么就可以使用$.isPlainObject()这样的函数。但这真的是您需要做的吗?请记住,$.isPlainObject()不是一个非常有效的函数。它枚举了对象的所有属性。就像我在下面指出的那样,它无法区分{}new Object()

除了所有这些,Trevor建议您仅检查所需的属性,在大多数情况下,大多数情况下,我认为他是对的。绝对更接近我在自己的代码中采用的方法:验证我需要的内容,忽略其余部分。

因此,请再看看他的答案并仔细考虑。 (如果您打勾号,我也不会感到生气!)

现在我原来的答案:

jQuery中有一个 $.isPlainObject() 函数。如果您不使用jQuery,则可以将此函数的源代码复制到您的应用程序中。打开jQuery source并搜索isPlainObject:

在任何情况下,都值得阅读此函数的源代码,以了解它并不像typeofinstanceOf检查那么简单:

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

此代码还使用了class2type对象:
// [[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();
});

(这些代码段不在上下文中;如果单独使用它们,则需要调整语法。)

当然,根据情况,您可能不需要所有这些检查。而且,如果您已经在使用jQuery,则只需调用$.isPlainObject()即可,而无需担心细节。

另请注意,无法将对象文字与使用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!

它们都从true返回$.isPlainObject(),我很确定您设计的任何其他测试都将无法分辨出哪个是哪个。

一个有趣的历史笔记:当John Resig在2009年将该功能添加到jQuery时,他最初将其称为$.isObjectLiteral()。由于这种歧义,在我的敦促下他将changed the name改为$.isPlainObject

10-07 14:43