[]
そして{}
javascriptで真実です。
しかし、私はそれらをfalseとして扱いたいと思っています.外部ライブラリや個別の関数を使用せず、条件の括弧の間に快適に収まるほど小さく、可能な限り少ない文字数でそれを行う方法を知りたいです.
言い換えると:
不明な変数 (任意の型である可能性があります) をチェックし、これらのいずれか
false
に該当する場合に返す最も簡潔な方法は何ですか? またはb)それはまたはですか?{}
[]
[]
そして{}
javascriptで真実です。
しかし、私はそれらをfalseとして扱いたいと思っています.外部ライブラリや個別の関数を使用せず、条件の括弧の間に快適に収まるほど小さく、可能な限り少ない文字数でそれを行う方法を知りたいです.
言い換えると:
不明な変数 (任意の型である可能性があります) をチェックし、これらのいずれか
false
に該当する場合に返す最も簡潔な方法は何ですか? またはb)それはまたはですか?{}
[]
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;
})();
x
チェックする変数がある場合:
!(!x || x.length === 0 || JSON.stringify(x) === '{}')
後ろから見てみましょうx
。 が空かどうかを確認します。
!x
x.length === 0
{}
オブジェクトです: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)
値がのインスタンス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の回答で定義されているような関数を使用することをお勧めします。