BLOG関数定義いろいろ[オレ得JavaScriptメモ]JAVASCRIPTTwitterFacebookはてブPocketLINEコピー2016.03.08スポンサーリンクオレ得JSメモ2枚目。今日は関数のことを整理してみよう。あ、オレ得jsメモはアドベントなんとかじゃないからいつまでとか決めてないし、何回書くかとかも決めてない。必要な時に必要なことをメモってくのです。関数定義にはいろいろ方法があるみたいなので、それぞれサンプル書いて確かめてみる。関数宣言(function文)関数式(function式)コンストラクタ(Functionコンストラクタ)参考とかまとめスポンサーリンク関数宣言(function文)JavaScriptでよく見かける関数の定義方法。関数名(引数1、引数2、引数3,...){処理1;処理2;...}行頭がfunctionで始まり、関数名に続いて()の中に関数に渡す引数を、{}の中に関数が呼び出されたときに実際に行う処理を記述する。JavaScriptには関数の定義の仕方がいくつかあるが、こういうのを「関数宣言による定義」という(らしい)。関数内の処理は何もしなくても良いし、他のオブジェクトのプロパティやメソッドを操作して終わる場合もあるし、returnで演算結果を関数の呼び出し元に返すこともある。引数numを渡して,numの二乗を返す関数は次のように書ける。num;}これはsqrという名前の関数を宣言し定義しただけなのでそれだけでは実行されない。実行するにはどうすればよいか?単純に関数の名前を呼んだら、その「呼ばれたとき」に実行される。引数の必要な関数なら、呼ぶ関数名の後に()で必要な数だけ引数を渡せばよい。引数の区切りは「,(コンマ)」でいい。sqr~で定義された関数が、最後の行sqr(2)で「2」という引数の値を伴って呼び出され実行されている。これだと実行はされているけど、その結果をどこにも表示するよう記述してないので、例えばこうしてみようか。num;}console.log(sqr(2));これでコンソール画面に「4」と表示され確認することができるようになる。(console.logとalertについてはコチラ)もうちょっと細かくプロセスを説明するならば「sqr」という名前の関数を呼び出す関数「sqr」を定義している部分を探して参照する関数「sqr」に「2」という引数を渡す「引数*引数」(ここでは2*2)という処理を行うreturnでその結果(ここでは4)を関数の呼び出し元に返すconsole.logにより、返された結果(ここでは4)をコンソール画面に表示するというようなことになると思う。ところでこの例では、ソースのコード記述順としては「関数を定義する」→「関数を呼び出す」となっているが、行頭function~によって宣言された関数は、実際には「ソースの解釈時(コンパイル)時に」定義されるのであって「実行時に」定義されるわけではない。処理系全体がどのような処理経路を辿ろうとも、例え実際にその関数が1度も使用されることがなくてもそのソースがロードされ、コンパイルされたときに定義「だけ」はされる、ということ。逆に言えば関数宣言により定義される関数は、ソース上その関数が呼び出しの前に書かれていようが後に書かれていようが呼ばれれば実行される、ということになる。num;}ソースがこのように関数の呼び出し部分が先にあって、関数の定義部分が後に記述されていてもsqr(2)はきちんと実行され、コンソール画面には「4」と表示される。関数の定義が後に記述されているからと言ってsqr(2)実行時に「関数が見つかりません」みたいなエラーにはならないということだ。いった宣言より前からのアクセスを「ホイスト(巻上げ)」という。html内に次のような記述がされていた場合はどうだろう。num;}</script>これはアウト。「関数宣言による定義は後に書いてもいいって言ったじゃん!」それはそうなのだが、これはJavaScriptというよりhtmlの仕様によるものだ。htmlソースはブラウザにロードされると書いてあることが書いてある順に解釈(レンダリング)される。最初のscriptタグ内のレンダリングが完了しないと2番目のscriptタグのレンダリングに移れない。最初のscriptタグをレンダリングしている最中は2番目のscriptタグ内に記述されているコードはまだ一切解釈されていないのだ。こんな変な書き方は普通しないと思うけど、念のため。外部JSファイルにJavaScriptコードを書くときも、ファイルを分割すると同様のことが起こり得るからね。スポンサーリンク関数式(function式)関数は上記のような「関数宣言」によって定義する以外に、変数に直接代入して定義する方法もある。num;};これは私が激しく勘違いしていたことだが「sqr」は関数名「ではない」。function~」以降で記述されている関数そのものには名前がない。名前がない関数を「無名関数」とか「匿名関数」と呼んだりする。functionの閉じかっこ「}」の後ろに「;(セミコロン)」がついていることに注意。これはつまり、関数宣言ではなくあくまで変数を定義してそこに関数を代入している、ということを意味する。変数の中に値を代入したり、他のオブジェクトの参照を代入したりしているのと行為としては変わらない。いうのを「関数式」という。変数に引数を付けて渡すと関数の中の処理を実行し、また必要があればなんらかの値を返す。num;};console.log(sqr(2));こうするとコンソールは「4」と応答する。関数を呼び出しているようだ!しかし、くどいようだが呼び出しているのはあくまで変数だ。呼んだ変数の中にたまたま関数が入っていた、ということだ。num;};関数式の定義(=変数の定義とそれへの関数の代入)以前で変数sqrを呼ぶとコンソールに「変数が見つからないよ!」と言われたり、この例のように引数付で呼ぶと「sqrは関数じゃないよ!」などとエラーを返されたりする。関数宣言と関数式は似ているようで全然違うのだ。ところでsqrは変数だ。変数だから当然中身も書き換えられる。"ほげほげ";console.log(sqr);sqrに関数を代入した後、さらに「ほげほげ」という文字リテラルを代入しなおしているので、コンソールには「ほげほげ」と表示される。関数式による関数定義は「その場で定義され、その場で実行される」ので、使い捨てるのに向いている関数定義、とも言える。関数式のここまでの例では無名関数を使ってきたが、関数に名前を付けても良い。関数式で付けた関数の名前はグローバルスコープからは参照できない。num;};console.log(MyFunc(2));関数に「MyFunc」という名前を付けて、関数の外から呼んでみた。グローバルから結果を得たいときは代入された変数sqrのほうを呼ばなければならない。この場合関数を呼び出せるのは関数自身の中からだけ。65536){MyFunc(num);}};sqr(2);このように一定の条件を満たすまで再帰的に関数自身を呼び出し計算を繰り返す。例では引数として与えられた初期値を二乗しコンソールに表示、それが65,536未満なら再度その結果を二乗しコンs(ry...というようなことをしている。num*num){console.log(num);}};sqr(2);...ので一見意味がなさそうだが、高次の方程式で収束・発散調べる場合は算式そのものが複雑になるから、関数式を再帰するメリットが出てくるのかもしれない。スポンサーリンクコンストラクタ(Functionコンストラクタ)もう一つ。これは私自身あまり必要性を(今のところ)感じていない関数の定義方法。num');console.log(sqr(2));よく観察してほしい。functionではなくFunctionだ。引数のようなものがあるが、関数定義(function文)や関数式(function式)で関数本体のステートメントに相当する{}がない。このFunctionはコンストラクタと呼ばれる。()の中の引数に見える(ってうか引数だけど)部分の最後が関数本体のステートメントだ。クォーテーション’でくくって文字リテラルで与えられている。本体ステートメントが複数行にわたる場合は;(セミコロン)で区切って書いても良い。引数が複数あっても良い。num2');console.log(sqr(2,3));とはいえ、複雑な処理を行おうとすると常人には理解しがたい表記になりそう。num2');これはエラーになる。関数式の時と同じように実行時に定義される、ということだ。Function('num',str);console.log(sqr(2));おお、エラーを吐かない。コンソールにはちゃんと4と表示される。いうことは関数ステートメント自体も入れ替えてられるということだ。用途思いつかないけど。MDNQiitaはやっぱり掘るといろんなもんが出てくるなー。ありがとう、ありがとう。スポンサーリンクまとめ関数定義には3つ方法がある。関数宣言(function文)、関数式(function文)、そして関数コンストラクタ(Functionコンストラクタ)。関数宣言はホイストかかるのでどこでも呼び出せる。そのかわり使っても使わなくてもその分メモリは占有されるだろう。関数式は自身を自身の中からしか参照できない(ローカルスコープ)。実行時定義なので使い捨て。処理が通過したらメモリも破棄される(たぶん)。関数コンストラクタは...よくわからないから使わない!関数についてはほかにもコールバックの話とかクロージャとかまだまだ深い話があるけど、一度に深追いしてもアレなので今日はここまで。識者からは「いい加減なこと書くな!」と怒られそうだが、これが今のところの私の理解。BLOG関連記事JAVASCRIPT動的に識別子指定したいときはブラケット記法を使おう[オレ得JavaScriptメモ]久しぶりにJSメモです。今日は本当にメモ程度...恥ずかしながら今まで知らなかったブラケット記法について。いや知ってたけど使い方あんまりわかってなかった。単純だけどこいつは強力。JAVASCRIPT丸く収まらないJavaScriptの数値丸め~round、ceil、etc...業務用の計算処理(ちょっとした構造物の設計&計算書出力)のためスクリプト組んでるごろどくです。わからないこと調べ調べやってるんで進みが大変悪くて辛いです。プログラミング学習動画サイト『ドットインストール』ウェブ界隈のツイッタラーさんには今さらな話のような気もするけど、多分世の中にはこれ知らない人たくさんいると思うのでぜひ知っていただきたいと思いご紹介。RSSで取得することもできるのょツイッターの検索オペレーターで色んな検索方法があるってのは以前の記事の記事にもかきました。毎度毎度ツイッターウェブ(またはクライアント)で検索条件指定して調べるのも大変なんですよね。毎回同じ検索結果について取得したいならばツイッターの...JAVASCRIPTブログ拾い読み用ブックマークレットを作ってみました閲覧してるページの選択テキストと一緒にタイトルとそのページのリンクを拾い上げるブックマークレットを作ってみました。ネタフルさんのネタリストみたいにあっちこっちの拾い読み記事書く時にあると便利かと思いまして。JAVASCRIPT不便で面倒なMath周りでエイリアスや追加モジュールで省力化を図る[オレ得JavaScriptメモ]もはや何枚目かわからなくなったオレ得JavaScriptメモです。人間40歳を過ぎると一気に体力の衰えを感じるもんです。明日の健康診断が心配です。夏には42になるごろどくですどうも。40代になるとマスをかくにも一苦労です。コメントをキャンセルメールアドレスが公開されることはありません。*サイト次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する。(1)スポンサーリンクタイトルとURLをコピーしました。