检查未定义

时间:2013-03-15 02:35:19

标签: javascript

我完全糊涂了。我知道这已被问了一百万次。我看过像这样的问题:

Test if something is not undefined in JavaScript

现在的问题是,在进行检查时,我发现了一些你可以做的事情。

我需要检查一个对象是否是一个数组,为此我检查是否存在“length”属性。现在我会用什么?

 if (obj.length)

 if (obj.length === undefined)

 if (typeof obj.length === "undefined")

if (obj.length == null)

或其他什么?

我理解===没有进行任何类型转换,而if语句只是想要一个“truthy”或“falsey”值,这意味着如果长度为0,obj.length将返回false ,但那不是我们想要的。我们现在想要定义它。这就是我去打字测试的原因。但哪种方式最好?

以下是我做过的一些测试。 2,3和4工作。

enter image description here

对不起介于两者之间的东西。我是在这个页面的控制台中做的。

6 个答案:

答案 0 :(得分:4)

简短回答:

if (obj instanceof Array) {
    // obj is an array
}

或者,如果您不知道是否定义了obj

if ((typeof obj !== "undefined") && (obj instanceof Array)) {
    // obj is an array
}

讨论你的不正确的原因:

如果obj.anyProperty未定义,

ReferenceError将抛出obj。这会影响你提出的所有四件事。

对于空数组,

if (obj.length)将评估为false,这不是您想要的。因为长度为0(假值),所以它将错误地不准确。如果另一个对象具有length属性,这也可能会出现问题。

if (obj.length === undefined) 通常会工作,但它不受欢迎,因为undefined可以重新定义。有人可以通过编写undefined = obj.length来破坏您的代码。这也可能造成漏报; obj可能碰巧有一个名为“length”的属性,它会错误地将其称为数组。

if (typeof obj.length === "undefined")工作正常,但可以检测到与上述相同的错误否定。

if (obj.length == null)可以正常工作,但有与上面相同的错误。在双等号(==)中,它与nullundefined匹配。

答案 1 :(得分:2)

我会做`

obj instanceof Array

检查obj是否为数组

http://jsfiddle.net/Tcjk4/

答案 2 :(得分:2)

对于它的价值,这里是jQuery checks whether something is an array

的方式
isArray: Array.isArray || function( obj ) {
    return jQuery.type(obj) === "array";
},

如果可用,则使用ES5的Array.isArray,或者在旧浏览器中使用自定义检查。 jQuery使这个函数可以$.isArray访问。

jQuery.typebasically增强版typeof,可以解决JavaScript语言和浏览器错误的一些限制。 typeof为任何类似对象('object'{},甚至[])返回null$.type返回内部JavaScript {{3}对象的属性。

实际上,这种确定类型[[Class]]的方法:

  

instanceofconstructor看起来都很无辜,看起来很棒   检查对象是否为数组的方法。

     

在多帧DOM中编写脚本时会出现问题   环境。简而言之,在一个iframe中创建了Array个对象   不要与在另一个内创建的数组共享[[Prototype]]   iframe中。他们的构造函数是不同的对象,所以两者   instanceofconstructor检查失败:

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]  

// Boom!
arr instanceof Array; // false  

// Boom!
arr.constructor === Array; // false

答案 3 :(得分:1)

更多评论而非回答。

虽然类似object instanceof Array的测试在大多数情况下都会起作用(在涉及帧或窗口间通信的情况下可能会失败),但最好还是考虑一下你真正需要测试的内容并相应地设计测试。显式测试对象是否是数组几乎总是不必要的。

在这种情况下,您似乎只想使用length属性迭代对象的数字属性。

如果是这种情况,您需要做的就是读取length属性的值并使用它。无论属性是缺失,还是尚未分配值,或者值为undefined0,您都不希望执行循环。幸运的是,您可以一次性完成所有这些测试(如果值为Null'',也可以跳过处理,这似乎也是合理的):

if (obj.length) {
  // iterate over numeric properties of obj
}

这将使该方法通用,因此它可以应用于具有合适长度属性和一些数字属性的任何Object(例如jQuery对象或HTMLCollection对象)。

如果您需要阵列的其他功能(例如推或切片),您也可以测试它们。

如果你使用测试作为逻辑分支(例如,如果它是一个数组做一件事,如果它是一个普通对象做其他事情)那么你应该考虑这是否是一个明智的事情。

答案 4 :(得分:0)

var sizeArrayOrObject = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (typeof obj.key === 'undefined') size++;
    }
    return size;
};

sizeArrayOrObject([]);  // 0
sizeArrayOrObject([5,6]);  // 2

sizeArrayOrObject({});  // 0
sizeArrayOrObject({id:8});  // 1

答案 5 :(得分:0)

使用underscore.js http://underscorejs.org/#isObject

<强> _。IsArray的(对象) 如果object是一个数组,则返回true。

(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true

<强> _。则IsObject(值) 如果value是Object,则返回true。请注意,JavaScript数组和函数是对象,而(普通)字符串和数字则不是。

_.isObject({});
=> true
_.isObject(1);
=> false