1

[]そして{}javascriptで真実です。

しかし、私はそれらをfalseとして扱いたいと思っています.外部ライブラリや個別の関数を使用せず、条件の括弧の間に快適に収まるほど小さく、可能な限り少ない文字数でそれを行う方法を知りたいです.

言い換えると:

不明な変数 (任意の型である可能性があります) をチェックし、これらのいずれかfalseに該当する場合に返す最も簡潔な方法は何ですか? またはb)それはまたはですか?{}[]

4

3 に答える 3

4

The most concise way with an array is !arr.length. Of course, that assumes you haven't added any non-index properties to the array (which is a perfectly valid thing to do). And as Qantas 94 Heavy points out in the comments, an array that's empty can have its length set to a non-zero value without gaining any actual entries.

Objects are more tricky. What's an "empty" object? One with no properties at all? One with no enumerable properties? What about properties from its prototype, if any?

If no enumerable properties does it for you, in ES5 you can use !Object.keys(obj).length. If you can't count on ES5, you have to have a loop:

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

...which is obviously fairly ungainly.

You've said you don't want separate functions, but of course that's the best way to do this:

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 tests (source)

于 2013-10-20T10:23:38.773 に答える
3

xチェックする変数がある場合:

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

後ろから見てみましょうx。 が空かどうかを確認します。

  1. それはすでに間違っているかもしれません:!x
  2. それは配列であり、その長さはゼロです:x.length === 0
  3. それはまさに{}オブジェクトです:JSON.stringify(x) === '{}'

方法に注意してくださいJSON.stringify。最新のブラウザーの大部分で利用できますが、IE6、7 をサポートする必要がある場合は利用できません。caniuse/JSONで確認してください。

この条件のいずれかが真であると、変数xは空になります。

したがって、結果を反転して空でないかどうかを確認するには、or の ( ||) とアウターが必要です。!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)
于 2013-10-20T10:38:01.357 に答える
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)

全体として、||,&&および==演算子をいじって、一日中すべての場合に機能する短いものを見つけようとすることができますが、それが可能かどうかはわかりません。

要約すると、@TJ Crowderの回答で定義されているような関数を使用することをお勧めします。

于 2013-10-20T11:42:54.567 に答える