第10章 ブール値
目次
書籍を購入する
(広告、ブロックしないでください。)

第10章 ブール値

プリミティブなブール型は、truefalseの値で構成されます。

> typeof false
'boolean'
> typeof true
'boolean'

ブール値への変換

値は次のようにブール値に変換されます。

ブール値に変換後

undefined

false

null

false

ブール値

入力と同じ(変換なし)

数値

0NaNfalse

その他の数値 → true

文字列

''false

その他の文字列 → true

オブジェクト

true(常に!)

ブール値への手動変換

任意の値をブール値に変換するには3つの方法があります。

Boolean(value)

(コンストラクタではなく、関数として呼び出されます)

value ? true : false

!!value

単一の「not」は否定されたブール値に変換されます。否定されていない変換には2回使用します。

より記述的であるため、Boolean()を好みます。いくつかの例を以下に示します。

> Boolean(undefined)
false
> Boolean(null)
false

> Boolean(0)
false
> Boolean(1)
true
> Boolean(2)
true

> Boolean('')
false
> Boolean('abc')
true
> Boolean('false')
true

真偽値

JavaScriptがブール値を期待する場合は、どのような種類の値でも提供でき、自動的にブール値に変換されます。そのため、JavaScriptには2種類の値の集合があります。1つの集合はfalseに変換され、もう1つの集合はtrueに変換されます。これらの集合は、偽値(falsy values)真値(truthy values)と呼ばれます。前述の表から、以下のすべてが偽値です。

  • undefinednull
  • ブール値:false
  • 数値:0NaN
  • 文字列:''

その他のすべての値(空のオブジェクト、空の配列、new Boolean(false)を含むすべてのオブジェクト)は真値です。undefinednullは偽値であるため、if文を使用して変数xに値があるかどうかを確認できます。

if (x) {
    // x has a value
}

注意点として、上記のチェックでは、undefinednullだけでなく、すべての偽値を「値を持たない」と解釈します。しかし、その制限を受け入れられるのであれば、コンパクトで確立されたパターンを使用できます。

落とし穴:すべてのオブジェクトは真値です

すべてのオブジェクトは真値です。

> Boolean(new Boolean(false))
true
> Boolean([])
true
> Boolean({})
true

これは、valueOf()メソッドとtoString()メソッドを実装することで結果を制御できる数値や文字列へのオブジェクトの変換とは異なります。

> Number({ valueOf: function () { return 123 } })
123
> String({ toString: function () { return 'abc' } })
'abc'

歴史:なぜオブジェクトは常に真値なのか?

ブール値への変換は、歴史的な理由から異なります。ECMAScript 1では、オブジェクトがその変換(例:toBoolean()メソッドによる)を設定できるようにすることは決定されませんでした。その理由は、ブール演算子||&&がオペランドの値を保持するためです。したがって、これらの演算子を連鎖させると、同じ値の真偽値が複数回チェックされる可能性があります。このようなチェックはプリミティブに対しては安価ですが、オブジェクトがブール値への変換を設定できる場合、オブジェクトに対してはコストが高くなります。ECMAScript 1は、オブジェクトを常に真値にすることで、そのコストを回避しました。

論理演算子

このセクションでは、AND(&&)、OR(||)、NOT(!)論理演算子の基本について説明します。

2項論理演算子:AND(&&)とOR(||)

2項論理演算子は次のとおりです。

値を保持する

常にオペランドのいずれかを変更せずに返します。

> 'abc' || 123
'abc'
> false || 123
123
短絡評価

最初のオペランドですでに結果が決まっている場合、2番目のオペランドは評価されません。例(console.logの結果はundefinedです):

> true || console.log('Hello')
true
> false || console.log('Hello')
Hello
undefined

これは演算子としては珍しい動作です。通常、演算子が呼び出される前にすべてのオペランドが評価されます(関数の場合と同様です)。

論理AND(&&)

最初のオペランドをfalseに変換できる場合、それを返します。そうでない場合は、2番目のオペランドを返します。

> true && false
false
> false && 'def'
false
> '' && 'def'
''
> 'abc' && 'def'
'def'

論理OR(||)

最初のオペランドをtrueに変換できる場合、それを返します。そうでない場合は、2番目のオペランドを返します。

> true || false
true
> true || 'def'
true
> 'abc' || 'def'
'abc'
> '' || 'def'
'def'

パターン:デフォルト値の提供

値(パラメータ、関数の結果など)が非値(undefinednull)または実際の値のいずれかになる場合があります。前者の場合にデフォルト値を提供したい場合は、OR演算子を使用できます。

theValue || defaultValue

上記の式は、theValueが真値の場合はtheValueを、そうでない場合はdefaultValueを評価します。通常の注意点が適用されます。theValueundefinednull以外の偽値を持つ場合もdefaultValueが返されます。そのパターンを使用する3つの例を見てみましょう。

例1:パラメータのデフォルト値

関数saveText()のパラメータtextはオプションであり、省略された場合は空文字列にする必要があります。

function saveText(text) {
    text = text || '';
    ...
}

これは、デフォルト演算子としての||の最も一般的な使用方法です。オプションパラメータで、オプションパラメータの詳細を参照してください。

例2:プロパティのデフォルト値

オブジェクトoptionsには、プロパティtitleが存在する場合と存在しない場合があります。存在しない場合は、タイトルの設定時に'Untitled'の値を使用する必要があります。

setTitle(options.title || 'Untitled');

例3:関数の結果のデフォルト値

関数countOccurrencesは、regexstr内で一致する回数をカウントします。

function countOccurrences(regex, str) {
    // Omitted: check that /g is set for `regex`
    return (str.match(regex) || []).length;
}

問題は、match()String.prototype.match:キャプチャグループまたはすべてのマッチする部分文字列を返すを参照)が配列またはnullを返すことです。||のおかげで、後者の場合にデフォルト値が使用されます。したがって、どちらの場合でもプロパティlengthに安全にアクセスできます。

論理NOT(!)

論理否定演算子!は、オペランドをブール値に変換してから否定します。

> !true
false
> !43
false
> !''
true
> !{}
false

等値演算子、順序演算子

次の演算子については、別の場所で説明します。

Boolean関数

関数Booleanは2つの方法で呼び出すことができます。

Boolean(value)

通常の関数として、valueをプリミティブなブール値に変換します(ブール値への変換を参照)。

> Boolean(0)
false
> typeof Boolean(false)  // no change
'boolean'
new Boolean(bool)

コンストラクタとして、Booleanプリミティブのラッパーオブジェクトを参照)の新しいインスタンスを作成します。これはboolを(ブール値に変換した後)ラップするオブジェクトです。例:

> typeof new Boolean(false)
'object'

前者の呼び出し方が一般的です。

次へ:第11章 数値