【ISSUE】JSについて本気出して考えてみた
2024年12月23日 22:38
こんにちはばーんです
今回はJavaScriptの言語仕様について書いていきます。
JavaScriptの勉強会参加と(https://x-hack.connpass.com/)
その際に勧められた書籍を読んで、自分で得た知識を整理していきます。
なるべく言語仕様書のように堅苦しくなく説明していくよう心掛けますw
【JavaScriptは殆どオブジェクトである】という言葉の意味が理解できていない方
といったことを解決していきたいと思います。
【JavaScriptは殆どオブジェクトである】が理解できる
具体的には下記の内容を理解できればOKだと思っています。
①「そもそもオブジェクトがどういうものか?理解する」
↓
②「JavaScriptがどういうもので構成されているか知る」
↓
③「どういう流れで普段自分たちが②を意識せずに使えているか知る」
前段の通りJavaScriptは殆どがオブジェクトです。
関数も配列も
※3章で掘り下げます
オブジェクトとは**「名前と値を持つプロパティを格納するコンテナ」**です。
例えば下記のようなオブジェクトがあった場合は、
オブジェクト / プロパティ / メソッドを下記のように分類できます。
自分自身もオブジェクト、プロパティ、メソッドは混乱していましたが、このように明示できます。
どのようにオブジェクトを使用するか?ということです。
オブジェクト名 + ドット + プロパティ名(名前またはキー)でアクセスできます。
ちなみに関数の場合は()をつけることで実行されます。
※ドット記法とブラケット記法がありますが、話が逸れるのでブラケット記法については書きません。
※正確には関数ではなくconsoleオブジェクトの中のメソッドの1つですが、伝わりやすくする為上記のような表記としています。
当時JS完全に理解した状態だった自分は、関数と聞くと
みたいなモノを想像していました。
しかし、初学者にとっても馴染みの深いconsole.log()が関数だったなんて!と衝撃を覚えました。
このようにchromeのDevtoolにconsole.logを入力すると
ƒ log() { [native code] }
と表記されます。 ƒ はfunctionのことですね^^
このことを念頭に読み進めて頂けるとm_ _m
まずここでは、JavaScriptがどのような要素で構成されているか?を見ていきます。
結論から言うとJavaScriptはプリミティブ値とネイティブオブジェクト(コンストラクタ)で構成されています。
プリミティブ
原始的な、基本の みたいな意味ですね。
JavaScriptでは数字、文字列、真偽値などが当てはまります。
(https://developer.mozilla.org/ja/docs/Glossary/Primitive)
ネイティブオブジェクト(コンストラクタ)
はい。こちらがややこしいので詳しく書いていきます。
そもそもコンストラクタ(関数)とは、
new演算子を使って実行されるとオブジェクトを生成する関数です。
ちょっと待って下さい。ブラウザバックしないで欲しい。
当然といえばそうですが、①はbaanを定義していないので構文エラーが出ます。
②はnew演算子を使って実行しているので空のオブジェクトが生成されています。
これを普段見慣れているような形にすると、
この**Object()**の部分がコンストラクタ関数です
そして、原始的に用意されているネイティブオブジェクトは9つです。
Number()
String()
Boolean()
Object()
Array()
Function()
Date()
RegExp()
Error()
これ以外を宣言するとエラーが出ます。
ちなみにPersonを使用したい場合は、
このようにコンストラクタ関数を宣言すればOKです!
これで想定通りの振る舞いになりました^^
ここではネイティブオブジェクト(コンストラクタ)から、どのようにして普段使っているオブジェクトになっているのかを掘り下げていきます。
その為には1章の冒頭部分を掘り下げていきます。
前段の通りJavaScriptは殆どがオブジェクトです。
関数も配列も
関数もオブジェクトです。なので値としてセットできます。
例えば関数の引数であったり、メソッドとして。
※メソッドについては1章で触れているので省略します
また、ネイティブオブジェクト(コンストラクタ)についてですが、
このようにnewすることで、無名関数を生成しています。
もう少しわかりやすくする為chromeのDevtoolを使います。
無名関数が生成されていますね^^
※ただし、Functionコンストラクタによる関数の生成は推奨されません。これは、JSエンジンによる最適化を妨げたり、他の問題を引き起こしたりする場合があるためです。
こちらも関数同様にネイティブオブジェクト(コンストラクタ)をnewしてみます。
普段私たちは②を使用していると思います。
が、内部的にはJavaScriptがよしなにやってくれているだけで、配列の生成は①で行われています。
このように普段使用している関数も配列もオブジェクトです。
そして、それらはネイティブオブジェクト(コンストラクタ)より生成されています。
なので**「JavaScriptは殆どオブジェクト」**なのです。
2章まとめ
- JavaScriptはプリミティブ値とネイティブオブジェクト(コンストラクタ)で構成されている
ここで述べているプリミティブ値はどーなんの?
という話ですが、プリミティブ値はオブジェクトでラップされる時があります。
つまり、擬似的にオブジェクトのように振る舞います。
本来1(数値)はプリミティブ値なのでtoStringのプロパティを持ちませんが、プリミティブ値のプロパティにアクセスする際に、オブジェクトでラップされるのでこのような表現になります。
つまり1〜3章をまとめて
**「JavaScriptは殆どオブジェクト」**なのです。
自分自身が衝撃を受けた項目があるので、最後に番外編として追記させて頂きます。
私たちがconsole.log()を使用する時、consoleオブジェクトについてはそれほど考えないと思います。
ただ、それでもchromeのDevtoolにconsole.logを入力すると使えてしまいます。
それはつまり、JavaScriptがよしなにやってくれてます。
具体的にブラウザは、グローバルオブジェクトとしてwindowオブジェクトを持っています。
※正確にはブラウザを立ち上げたクライアントPCのメモリ上に、グローバルオブジェクトを展開しています
そして、 console はオブジェクトであり、 window のプロパティです。 log はメソッドです。
①まずchromeのDevtoolにwindowを入力します
②windowのプロパティを見てみると大量のプロパティが設定されてあります
③その中にconsoleとlogがありましたね!
ちなみにブラウザ上なのでwindow.console.log("hoge") でも動きますが、Node.jsではエラーが出ます(ReferenceError: window is not defined)
**グローバルオブジェクトが違うので。**外面は同じですが内面は違う動きをしています。
普段私たちは配列を操作する時にこのようにメソッドを使用します(今回は join)。
このような時にmyArrにjoinというプロパティを定義しましたか?
していません。ですが、実際に私たちは明示的にjoinを定義しなくても使えています。
それにはJavaScriptのプロトタイプチェーンが関係しています。
まずプロトタイプチェーンを文面だけで説明すると、
ネイティブオブジェクトコンストラクタ関数(Object, Function, Arrayなど)はオブジェクトを生成する際にprototypeプロパティを継承させます。
待って諦めないで聞いて欲しい。スクロールはもう少し我慢して欲しい。
配列を例に説明していきます。
まず、配列を作る時、普段は
と宣言します。
これは、第3章>配列オブジェクトで記載している通り
と同意です。つまり、ネイティブオブジェクトコンストラクタ関数である Array()をnewしてインスタンス(この場合myArr)を生成しています。
そして、その際にprototypeというプロパティを継承させています。
prototypeにはjoinというメソッドがあります
なので、私たちは明示しなくともjoinというメソッドが使えるのです。
プロトタイプチェーンは今回の場合であれば、myArrにjoinメソッドがないと判断するとエラーを返すのではなく遡って確認しにいきます。
※最終的にはObject()まで確認しにいきます
自分はプロトタイプチェーンを知ってから格段におまじないみたいなコードが減りました。
何故エラーが出るか?どういう仕組みで?が理解できたので。
簡単に言うとprototypeでリンクしているというイメージでいいかと思います。ブラウザでは__proto__
という表記のものもあります。
何点か補足事項があります。
この辺りは次回以降にまとめていこうと思います。
開眼!JavaScriptという本です。
とても楽しく読める言語仕様についての本でした^^
ただし、恐らく勉強始めてすぐにこれに出会っていても自分は理解できなかったと思います。
できればJavaScriptで何か動かしてから購入をおすすめします。
(道中呪文みたいな文章結構あるので)
この記事に関して細部の認識はずれている可能性があります。
技術的なマサカリwは大歓迎ですので、何かあれば遠慮なくコメント頂けると幸いです。
参考にさせていただきましたm_ _m
ありがとうございました^^
https://developer.mozilla.org/ja/docs/Web/JavaScript
https://nodejs.org/api/console.html
https://harakotan.hatenablog.jp/entry/2015/05/17/004707
https://www.tweeeety.blog/entries/2014/02/05
今回自分がこの記事を書くきっかけになったのはxhackさんの勉強会がきっかけでした。
参加していなければ理解が浅いまま進んでいたと思います。
この場を借りてお礼申し上げます。ありがとうございましたm_ _m
それではまた^o^/
[cv:issue_marketplace_engineer]
診断を受けるとあなたの現在の業務委託単価を算出します。今後副業やフリーランスで単価を交渉する際の参考になります。また次の単価レンジに到達するためのヒントも確認できます。