質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

1785閲覧

alert(new Boolean(Boolean(false)));の実行結果がfalseとなる理由

jhenk

総合スコア12

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2019/02/16 08:12

編集2019/02/16 11:59

前提・実現したいこと

JavaScript プリミティブ型 (基本データ型)というサイトを読んでいます。

発生している問題・エラーメッセージ

上のサイトの「ラッパーオブジェクトのインスタンスと論理値」セクションには次のようなコードがありました。

js

1alert(new Boolean(new Boolean(false))); 2alert(new Boolean(Boolean(false)));

上下ソースの動きはこのようになると考えていました。

上のソース

  1. new Boolean(false)が評価

falseのラッパーオブジェクトがかえる
0. new Boolean(new Boolean(false))が評価
⇒手順1のラッパーオブジェクトはfalseを持っているが、このオブジェクト自体は空じゃないのでtrueと評価される

A. 出力はtrueになる

下のソース

  1. Boolean(false)が評価

falseがプリミティブ値としてかえる
0. new Boolean(Boolean(false))が評価
new Boolean(Boolean(false))falseを持っているラッパーオブジェクトになるので、trueと評価される

A. 出力はtrueになる

しかし, 実際に下のソースをFirefox最新版のコンソールで実行したら、falseが出力されました。

該当のソースコード

下の動きがわからない。

js

1alert(new Boolean(new Boolean(false))); 2alert(new Boolean(Boolean(false)));

試したこと

まず、下のソースを段階的に観察するために, 各時点での値をコンソールで出力してみました

  • Boolean(false)

false
ここは考えたとおり、プリミティブな真偽値が返ってきています

  • new Boolean(false)

Boolean { false }(ラッパーオブジェクト)
ここも考えたとおり、falseを持っているラッパーオブジェクトが返ってきています

  • !!new Boolean(Boolean(false))

true
でも、ここでfalseが・・・。と思いきや、trueが返ってきてしまいました。

  • Boolean(new Boolean(Boolean(false)))

true
何かの手違いだと思い、Boolean関数で真偽値に変換すると、やはりfalseが・・・。
と思いきや、ここでもtrueが返りました。

これらの結果の最後2つをみていただくと、new Boolean(Boolean(false))NOT論理演算子で真偽値に変換したものと, Boolean関数で真偽値に変換したもの, どっちもtrueとなっているので、alert(new Boolean(Boolean(false)));の結果はtrueでないとおかしいと感じます。
これはalert()が特殊な型変換をしている(?)のだと考えましたが、どのようなことをしているんでしょうか?

ご回答よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

Boolean.prototype.toString

ラッパーオブジェクトの Boolean.prototype.toString 処理が考慮から抜けているのでは。

JavaScript

1new Boolean(false).toString() === "false"; // true

Re: jhenk さん

投稿2019/02/16 08:49

think49

総合スコア18164

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jhenk

2019/02/16 09:13 編集

回答ありがとうございます。 すみません、他の回答者の方へコメントを書いているうちに新しい回答が来ており, 通知に気づきませんでした。 今回は - 「`alert()`の出力は引数を文字列として評価したもの」を知らなかったこと - 「`Boolean.prototype.toString`は真偽値に型変換した後に実行される」と思っていたこと が質問と混乱の原因でした。 `false`の入った`Booleanオブジェクト`を文字列として評価すると, 確かに"false"となりますね。 `alert`をしらべたら[HTML Standard](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#optionally-truncate-a-simple-dialog-string)に文字列に変換することが書いてありました。調査不足でした・・・。 >To optionally truncate a simple dialog string s, return either s itself or some string derived from s that is shorter. ならば参考サイトのように, 勝手な文字列への型変換がされてしまう`alert()`で型変換の挙動を見ているのは不適切では, という疑問が沸きましたが, 実際問題になることも少ないからこれで良い, ということでしょうか。 仕様も参考にさせていただきます。ご回答ありがとうございました!
think49

2019/02/16 09:30

> https://www.yunabe.jp/docs/javascript_primitive_types.html#%E3%83%A9%E3%83%83%E3%83%91%E3%83%BC%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%A8%E8%AB%96%E7%90%86%E5%80%A4 ここの話なら、「Object型をString型に変換する時のルール」が書かれていないのが問題だと思います。 この説明だけ読んでも、 alert(new Boolean(Boolean(false))); //false の原理は理解できません。 > 勝手な文字列への型変換がされてしまう`alert()`で型変換の挙動を見ているのは不適切では はい。Boolean型をString型に変換する事はあまり考えられないので、不適当だと私も思います。 ここは論理値として扱ったケースを想定すべきでしょう。 alert(Boolean(new Boolean(Boolean(false)))); // "true" プリミティブラッパーオブジェクトをBoolean型に変換すれば、どの場合も必ず、true に変換されます(この挙動は改変できません)。
jhenk

2019/02/16 10:22

> ここの話なら、「Object型をString型に変換する時のルール」が書かれていないのが問題だと思います。 私もそう思います。最初は読者により深い理解を促すためにわざと含ませたもの, だと思ったのですが、一通り読んで見ると, 記事の各所に誤字や誤った結果が書かれていたので、書き手のミスだと考えを改めました。 > ここは論理値として扱ったケースを想定すべきでしょう。 なるほど。`alert()`で正しい型変換の挙動を見るとしたら、`Boolean関数`を使う方法がありましたね。うっかり忘れていました。 > プリミティブラッパーオブジェクトをBoolean型に変換すれば、どの場合も必ず、true に変換されます 真偽値への変換は、「空文字列、(-, +)0, NaN, null, undefined, false」以外はすべて`true`に変換され、ラッパーオブジェクトも例外ではない、ということですね。 とてもすっきりと理解できました。お付き合いいただき、ありがとうございました!
think49

2019/02/16 10:41

> 真偽値への変換は、「空文字列、(-, +)0, NaN, null, undefined, false」以外はすべて`true`に変換され、ラッパーオブジェクトも例外ではない、ということですね。 そうですね。内部的には if文でも使われるので、覚えておいて損はないです。 http://www.ecma-international.org/ecma-262/9.0/#sec-toboolean ちなみに、String型への変換規則は下記URLにあります。 http://www.ecma-international.org/ecma-262/9.0/#sec-tostring 慣れない内は、これらの変換表を見ながら確認すると間違いないと思います。
guest

0

ベストアンサー

alertは、引数を文字列として評価します(この場では、真理値としての評価は関係しません)。

new Booleanで作ったオブジェクトは、文字列として評価すると、trueあるいはfalseという文字列になります。

投稿2019/02/16 08:20

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jhenk

2019/02/16 08:37 編集

`new Boolean(new Boolean(false))` の結果を真偽値にすると`true`に、 `new Boolean(Boolean(false))` の真偽値は`true`になると理解しています。 この2つを文字列として評価すると"true"となりませんか? 後者のケースでだけ`true`(真偽値)が文字列に変換すると`false`(文字列)になるのには、文字列として評価するときに何が影響しているんでしょうか? --- 追記: あせってコメントしてしまいましたが、 >真理値としての評価は関係しない というところが理解できていないような気がするので、もう少し考えて見ます。
maisumakun

2019/02/16 08:40 編集

new Boolean(false)は、真理値としてはtrueですが、文字列にすれば「false」です。
maisumakun

2019/02/16 08:47

もっと簡単な値、例えば数値でも、「真理値としての値(0あるいはNaNならfalse)」と、「文字列にしたときの値」は別物です。
jhenk

2019/02/16 08:56 編集

ありがとうございます、理解できました。 `new Boolean(new Boolean(false)).toString();`は`true` `new Boolean(Boolean(false)).toString();`は"false"ですね! > ...の結果を真偽値にすると`true`に、...の真偽値は`true`になると理解しています。 > この2つを文字列として評価すると"true"となりませんか? 上の私のコメントからわかるように, 「`Booleanオブジェクト`をいったん"真偽値にしてから"文字列にする」というふうに1つ間違った段階を踏んでいたのが混乱の元でした。 ならば参考サイトの、文字列に型変換されてしまう`alert()`で型変換の挙動を見ているのは不適切ではという疑問が沸きましたが、実際あまり問題になることも少ないということでしょうか。 `alert`での型変換は知らなかったので、とても参考になりました。 ご回答ありがとうございました!
think49

2019/02/16 08:55

> 真理値としての値 「真理値 === Boolean値」の理解でしたが、この場合はどういう意味で使用されていますか。
maisumakun

2019/02/16 09:02

new Booleanのようなラッパーオブジェクトを意図的に作成することは、実用上ほぼありません。 あと、デバッグで値を見たい場合はconsole.logのほうがおすすめです。
jhenk

2019/02/16 09:32 編集

To>think49さん >「真理値 === Boolean値」の理解でしたが、この場合はどういう意味で使用されていますか。 その理解で話していましたが、どこか誤った用法がありましたでしょうか? 追記: このコメントはmaisumakunさん向けのようですね。失礼しました。 To>maisumakunさん >new Booleanのようなラッパーオブジェクトを意図的に作成することは、実用上ほぼありません。 ラッパーオブジェクト作成する機会は少ない(たいていの関数はプリミティブな値を返す) ⇒あまり問題にもならないので型変換の確認に`alert()`を使っても問題のないケースが多い ということですね!勉強になります。 >デバッグで値を見たい場合はconsole.logのほうがおすすめです。 助言ありがとうございます。`Consoleオブジェクト`のメソッドはとても役に立つので, 積極的に使って使用法を覚えていこうと思います。
think49

2019/02/16 09:33

> 「真理値としての値(0あるいはNaNならfalse)」と、「文字列にしたときの値」 よく読んだら、理解できました。 「ToBooleanした時の値」と「ToStringした時の値」ということですね。 お騒がせしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問