今まで何となく書いていたJavaScriptの文法について、知らなかった事実に触れて驚いた話(グローバルオブジェクト、論理和、コンストラクタの仕様)

JS詳しいベテランエンジニアの方には今更な内容かとは思いますがわずか2行のコードにJSの自分の知らなかった秘密が凝縮されてて衝撃を受けたので後学のためにまとめます
18
ヌル夫@アカウント分離中【プロフ参照】 @k_nulluo

このサンプルコードが何をやってるのかイミフだったのですが… ひょっとしてJSって通常メソッドだけじゃなくて、コンストラクタの上書きもできる…ってコト!? developer.mozilla.org/ja/docs/Web/AP… #JavaScript pic.twitter.com/sqk5deN9ov

2022-03-18 19:03:21
拡大
リンク developer.mozilla.org AudioContext - Web API | MDN AudioContext インターフェイスはAudioNodeによって表現され、一緒にリンクした音声モジュールから作った音声処理グラフを表します。音声コンテキストはコンテキストを含むノードの作成と音声処理もしくはデコードの実行の両方を制御します。コンテキスト内部で全てのことが起こるので、何かをする前に AudioContext を作る必要があります。 9 users
ヌル夫@アカウント分離中【プロフ参照】 @k_nulluo

AudioContextって変数にブラウザの種類に応じて特定の型を代入して そのAudioContextをnew で呼び出したら webkit系のブラウザだったらwebkitAudioContextのコンストラクタが その他のブラウザだったらAudioContextのコンストラクタが 呼ばれる…ってコトですかこれ? #質問

2022-03-18 19:05:48
ヌル夫@アカウント分離中【プロフ参照】 @k_nulluo

関数が変数に代入できるのはもうJSで常識的に使ってるやり方だったけど コンストラクタも代入できんの?(よく考えたら昔のJSだとクラスはそうやって実装してた気もする)

2022-03-18 19:07:30
ヌル夫@アカウント分離中【プロフ参照】 @k_nulluo

window.AudioContext || window.webkitAudioContext もなんじゃこりゃ?なのですが、これは多分普通のブラウザなら左のAudioContextを、safariとかだとwebkitAudioContextを返す・・・んですよね?

2022-03-18 19:10:27
奈良阪某 @narazaka

@k_nulluo はい。 AudioContext || webkitAudioContextだとAudioContextが無い場合に未定義エラーが出るが、ブラウザにおいてグローバルな変数はwindowオブジェクトのプロパティ呼び出しに出来、そうすると単にキーがなかった扱いになってエラーにならない。

2022-03-18 19:26:12
ヌル夫@アカウント分離中【プロフ参照】 @k_nulluo

JSくん・・・実は論理和といいつつ論理和を計算して真偽値を返していたわけじゃなかったんだね・・・何だよそれ (たまたま真偽値が代入された場合はブール演算と同じ結果になるので気づかないだけで実は左右の値がTruthyかどうかを見て、左がTruthyなら左を、そうでない場合は右を返している)

2022-03-18 19:31:44
奈良阪某 @narazaka

@k_nulluo またJavaScriptにおいて「クラスインスタンスの生成」は「new演算子を使うことによる関数呼び出しを含む特殊処理」であり、「コンストラクタ」は単に「それ用の関数(=処理系から見るとただの関数)」以上のものではなかったりします

2022-03-18 19:34:15
ヌル夫@アカウント分離中【プロフ参照】 @k_nulluo

@narazaka ぼくはJSくんのこと、何も分かってあげられていなかったことがわかりました。ありがとうございます ※このツイートだけで分かってなかった言語仕様が3つぐらい一気に理解(わか)ってしまった・・・

2022-03-18 19:34:32
ヌル夫@アカウント分離中【プロフ参照】 @k_nulluo

@narazaka new Hoge()するとHoge.constuctorを呼ぶという約束があるだけでコンストラクタもただの関数と同じだったから、変数にぶちこんだり上書きしたりも自由自在だった・・・?

2022-03-18 19:36:27
奈良阪某 @narazaka

@k_nulluo JavaScriptの根底にコンストラクタはなく、new演算子があります developer.mozilla.org/ja/docs/Web/Ja…

2022-03-18 19:37:34
奈良阪某 @narazaka

@k_nulluo JavaScriptはプロトタイプベースオブジェクト指向の言語なので、クラスベースの一般的な言語のパラダイムでは理解不能な操作が可能だったりしますね。 ja.wikipedia.org/wiki/%E3%83%97…

2022-03-18 19:36:28
ヌル夫@アカウント分離中【プロフ参照】 @k_nulluo

@narazaka 一度ブラウザゲーム作った時にこのあたりもさらっと触れたんですが、おまじないだと思って書いてたので、今ならもう少しプロトタイプのこと分かってあげられそうな気がします。ありがとうございます

2022-03-18 19:37:53
奈良阪某 @narazaka

@k_nulluo 動的型付言語はだいたいこういう処理ですね(Ruby, Perl) bool型に合わせる必要が無いので pic.twitter.com/wldYoF0qxT

2022-03-18 19:46:58
拡大
奈良阪某 @narazaka

@k_nulluo not演算子など真偽値の操作がどうしても必要になってはじめて型変換されます(なおPerlは真偽値コンテキストはあるが真偽値型はない) pic.twitter.com/vJEHM6ypqs

2022-03-18 19:52:13
拡大
ヌル夫@アカウント分離中【プロフ参照】 @k_nulluo

@narazaka 一応、Truthy とFalsyの概念は知ってたのですが A || B は値がTruthyであるかFalsyであるかに沿ってAとBをTrue/Falseに変換してから論理和取ってるんだとばかり思ってました…いや、昔そんな単純じゃないって読んだ気もしてきましたね… いずれにせよ、私はJSが、というより動的型付け言語キライ…だな

2022-03-18 19:55:32
ヌル夫@アカウント分離中【プロフ参照】 @k_nulluo

ごめん、JSくんの事…好きになれそうだったけど、やっぱり無理みたい… もう私静的型付けなしではいられないの…ごめんね、TSくんが呼んでるから…もう、行くね…

2022-03-18 20:02:31
ヌル夫@アカウント分離中【プロフ参照】 @k_nulluo

もちろんJSくんとの関係破綻の後でTSも闇を抱えている事に気づいてしまうオチが目に見えとるで

2022-03-18 20:03:22
奈良阪某 @narazaka

@k_nulluo TypeScriptはJavaScriptのスーパーセット(JavaScriptの仕様を全て含んでいる)!!!!!!! (うまいこと見て見ぬ振り出来るようにしてくれていて感謝に堪えない)

2022-03-18 20:07:18
ヌル夫@アカウント分離中【プロフ参照】 @k_nulluo

グローバル変数にしか見えないのにWindowのプロパティとして生えてるようにふるまうのも何でやねんだったのですが、ブラウザのJSでは「そう」なのか・・・

2022-03-18 19:39:38
奈良阪某 @narazaka

@k_nulluo window、global、this、globalThisなどがあります!(ぉ qiita.com/uhyo/items/f3b…

2022-03-18 20:04:23
奈良阪某 @narazaka

@k_nulluo なおこの辺の挙動はブラウザの開発者ツールコンソールでテスト可能なので理解が深まるかも知れない pic.twitter.com/9bk1eNKl11

2022-03-18 20:14:12
拡大