javascript - 如何检查参数是否为对象?

标签 javascript jquery

我知道在 JavaScript 中几乎所有东西都被视为对象。我正在制作一个函数,它特别要求它接受的参数采用这种格式:

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

所以这种类型的花括号内的键值对对象不是其他类型的对象。具体如何验证?

最佳答案

更新:在写完以下所有内容并进行进一步思考后,我建议您再看一下 Trevor's answer .我认为它比我的答案更值得那个漂亮的绿色复选标记,这就是原因。

我从表面上接受了你的问题并提出了它:如果你真的想按照你所说的去做,像 $.isPlainObject() 这样的函数是可行的方法。但这真的是您需要做的吗?请记住,$.isPlainObject() 不是一个非常有效的函数;它枚举了所有对象的属性。正如我在下面指出的,它无法区分 {}new Object()

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

所以请再看看他的回答,仔细考虑一下。 (如果您移动复选标记,我不会生气!)

现在我的原始答案:

有一个 $.isPlainObject() jQuery 中的函数。如果您不使用 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!

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

有趣的历史记录:当 John Resig 在 2009 年将此函数添加到 jQuery 时,他最初打算将其命名为 $.isObjectLiteral()。在我的催促下,他 changed the name$.isPlainObject 因为这种歧义。

关于javascript - 如何检查参数是否为对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15825287/

相关文章:

javascript - 如何在异步等待操作中测试 catch 语句

javascript - 使用 jQuery 将 HTML 附加到 iframe

javascript - Promise.all 在 fetch 解决之前返回

javascript - 单击父复选框时选中所有选中的框

javascript - Express 4 FormData多部分解析POST请求

javascript - 如何隐藏滚动(溢出:hidden)?

仅针对特定类的一个元素的 JQuery 事件

javascript - 如何使用 jquery javascript 在 Canvas 上添加文本区域

javascript - 菜单出现在桌面浏览器的移动 View 上,但不出现在实际手机上

Jquery第一次出现树遍历 parent / sibling