3

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

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

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

4

6 回答 6

2

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

我从表面上接受了你的问题,然后就跑了:如果你真的想按照你所说的去做,那么像这样的函数$.isPlainObject()就是要走的路。但这真的是你需要做的吗?请记住,这$.isPlainObject()不是一个非常有效的功能;它枚举所有对象的属性。正如我在下面提到的,它无法区分{}new Object()

而不是所有这些,Trevor 建议简单地检查您需要的属性,并且在大多数情况下,大多数时候,我认为他是对的。它肯定更接近我在自己的代码中采用的方法:验证我需要的内容,忽略其余部分。

因此,请再看看他的答案并仔细考虑。(如果您移动复选标记,我不会被冒犯!)

现在我原来的答案:

jQuery中有一个$.isPlainObject()函数。如果您不使用 jQuery,您可以将此函数的源代码复制到您的应用程序中。打开jQuery 源代码并搜索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()。在我的催促下,由于这种含糊其辞,他改名为$.isPlainObject

于 2013-04-05T03:16:42.237 回答
1

通过使用 typeof

var obj = {x: 1, y: 2};
if (typeof obj == 'object') console.log('im an object');
于 2013-04-05T03:14:19.570 回答
1

这将检查是否value是 anobject以及它是否具有属性ac

var value = {a: 1, c: 2};
if (typeof value === "object" && "a" in value && "c" in value)
{
    ...
}
于 2013-04-05T03:16:38.233 回答
1

陷阱:

  • typeof数组是“对象”

    typeof [] === 'object' //true
    
  • Array是一个实例Object

    Array instanceof Object //true
    
  • typeof null是“对象”

    typeof null === 'object' //true
    

您可以这样做检查是否:

  • arg是真实的。既然null是假的,就在这里除草。
  • typeof arg是“对象”。AFAIK,只有数组和对象传递这个。
  • 最后,如果arg不是的实例Array

    if(arg && typeof arg === 'object' && !(arg instanceof Array){...}
    
于 2013-04-05T03:20:17.110 回答
1

在您描述的情况下,我不会担心确保它不是数组或其他类型的对象。只需确保您需要的属性在那里,如果它们丢失,请发出警报。

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.
}
于 2013-04-05T03:35:30.230 回答
0

它还取决于您要断言的确切内容。至于最常见的情况 - 参数(或合约)验证,我最近注意到 NPM 团队(https://github.com/npm/cli)依赖于https://github.com/iarna/aproba函数,它非常轻量级和简单的:

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

该函数的作用:

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')
}
于 2018-12-05T17:18:25.223 回答