JavaScript中的“Falsy或empty”:如何将{}和[]视为false

时间:2013-10-20 10:17:55

标签: javascript

[]{}在javascript中非常简洁。

但我想将它们视为虚假,我很想知道如何以尽可能少的字符来实现它:没有外部库或单独的函数,并且小到足以在条件的括号之间舒适地适应。

换句话说:

  

检查未知变量(可以是任何类型)的最简洁方法是什么?如果 适用于这些,则返回false:a)它已经是假的;或b)它是{}还是[]

3 个答案:

答案 0 :(得分:3)

数组最简洁的方法是!arr.length。当然,假设您没有向数组添加任何非索引属性(这是完全有效的事情)。正如Qantas 94 Heavy在注释中指出的那样,一个空的数组可以将其length设置为非零值,而不会获得任何实际条目。

对象更棘手。什么是“空”对象?一个没有属性?一个没有可枚举的属性?如果有原型的属性怎么样?

如果没有可用的属性,在ES5中您可以使用!Object.keys(obj).length。如果你不能指望ES5,你必须有一个循环:

var empty = true;
var key;
for (key in obj) {
    // Add an `obj.hasOwnProperty(key)` check here if you want to filter out prototype properties
    empty = false;
    break;
}

......这显然相当笨拙。

你说你不想要单独的功能,但当然这是最好的方法:

var isFalsey = (function() {
    var toString = Object.prototype.toString;

    function isFalsey(x) {
        var key;

        if (!x) {
            return true;
        }
        if (typeof x === "object") {
            if (toString.call(x) === "[object Array]") {
                return !x.length; // Assumes no non-element properties in the array
            }
            for (key in x) {
                // Add an `x.hasOwnProperty(key)` check here if you want to filter out prototype properties
                return false;
            }
            return true;
        }

        return false;
    }

    return isFalsey;
})();

Example with testssource

答案 1 :(得分:3)

鉴于您要检查变量x

!(!x || x.length === 0 || JSON.stringify(x) === '{}')

我们从后面开始,让我们检查x是否为空:

  1. 它可能已经是假的:!x
  2. 它是数组,其长度为零:x.length === 0
  3. 正是{}对象:JSON.stringify(x) === '{}'
  4. 小心使用JSON.stringify方法。它适用于大多数现代浏览器,但如果您需要支持IE6,7则不适用。您应该查看caniuse/JSON

    任何此条件为真都会导致变量x为空。

    所以我们需要或者(||)和外部!来反转结果以检查x是否为空。

    修改

    进行第3次检查的更简洁方法是@David备注(JSON.stringify不适用于包含{a: function(){ console.log("test"); }}等方法的对象:

    (function (x){ for (key in x) { return 0; } return 1; })(x)
    

    结果表达式是:

    !(!x || x.length === 0 || (function (x){ for (key in x) { return 0; } return 1; })(x))
    

    修改

    如果您只想支持现代浏览器,请使用ecmascript 5功能:

    // Given x is defined
    !(!x || typeof x === 'object' && !Object.keys(x).length)
    

答案 2 :(得分:0)

如果您知道该值是Array的实例或任何其他原语(而不是一般对象),那么您可以在对象之前放置+符号并比较检查是否它是假的,就像这样:

> +[] == false
true
> +[1,2] == false
false
> +[] == false
true
> +true == false
false
> +'hello' == false
false
> +25 == false
false
> +false == false
true

如您所见,处理对象的一般实例更为复杂:

> +{} == false
false
> +{'a': 'b'} == false
false

或者如果你知道有问题的值是肯定而不是原语,并且你使用的是ES 5,那么你可以使用Object.keys来获取对象的所有键。一个数组然后检查变成这样:

> +empty_obj == false || Object.keys(empty_obj) == false
true
> +obj == false || Object.keys(obj) == false
false

但如果它是原始的,你就有麻烦了:

> +true == false || Object.keys(true) == false
TypeError: Object.keys called on non-object
    at Function.keys (native)
    at repl:1:27
    at REPLServer.self.eval (repl.js:110:21)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
    at Interface._ttyWrite (readline.js:760:14)
    at ReadStream.onkeypress (readline.js:99:10)
    at ReadStream.EventEmitter.emit (events.js:98:17)

总而言之,您可以使用||&&==运算符来尝试找到一些在所有情况下都可以全天使用的短片,但我是不确定是否可能。

因此,总之,我建议只使用像@ T.J中定义的函数。克劳德的答案。