【新人教育 JavaScript】Lesson 02 〜 Meet Functions and Variables 〜

#あらすじ
　このコラムはド素人でも生のJavaScriptを理解し、美しくかつ無駄のないソースコードを書けるようにするために作成している。理解しやすさのために牛歩戦術をとっているが、玄人の皆様にお詫び申し上げます。
　<b>なお、この記事に関するソースコードは[こちら](https://github.com/jerrywdlee/javascript_for_rookies)でダウンロードできます。</b>
（ ＊:タイトルのネタは<i>Longman</i>社出版の英語教科書『[Look, listen and learn!](https://openlibrary.org/works/OL10554472W/Look_listen_and_learn!)』の[Lesson 1](https://menoum.wordpress.com/2005/05/19/meet-sandy-sue/)より ）
#目次
|No.|記事|キーワード|
|:-----------|------------:|------------:|
|Lesson 01|[JavaScript is Simple](http://qiita.com/jerrywdlee/items/96efa42b35e9c9f72c91)|JavaScriptとは|
|Lesson 02|[Meet Functions and Variables(本記事)](http://qiita.com/jerrywdlee/items/eb95d6bad4695dc7ba2a)|関数と変数|
|Lesson 03|未定||
|Extra 01|[jQuery or Not, That is the Question](http://qiita.com/jerrywdlee/items/dde4044b9e4e08c74f45)|jQueryの使用と比較|
#JavaScriptの変数
　　変数は情報を格納する容器みたいなもの。JavaScriptはC言語やJavaみたな[静的型付け](https://ja.wikipedia.org/wiki/%E9%9D%99%E7%9A%84%E5%9E%8B%E4%BB%98%E3%81%91)言語と違い、すべて型の変数は同じ容器に入れる。
　
##変数を定義する実例
```js
var foo = 123;//変数 foo に数値 123 を付与する
var bar = "abc";//変数 bar に文字列 abc を付与する
var baz;//空の変数 baz を作成する、もしこの時の baz を呼び出すと undefined と出力される
baz = "Hi!";//空の変数 baz に文字列 Hi! を付与する、その時呼び出すと Hi! が出力される
```
![variables_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/87438/0cb61970-673f-3711-0c36-7ed4e8476cbf.gif)


##変数の接頭語(キーワード)と作用範囲
　JavaScriptの変数は型付け用の接頭語はないものの、変数の作用範囲の違いで、変数を宣言するための接頭語が主に３つある。

* var
* 書かない
* let

###"var"キーワード
　`var`で始まる変数の宣言はJavaScriptで最も一般に使われている。`var`で宣言した変数の作用範囲は宣言以降のほとんどすべての領域。ただし、もしある関数の中に`var`である変数を宣言した場合、別の関数でこの変数は使えない(エラーが出る)。(関数の定義は[次の章](http://qiita.com/jerrywdlee/items/eb95d6bad4695dc7ba2a#javascript%E3%81%AE%E9%96%A2%E6%95%B0)で述べる)
　なお、同じ変数を`var`で何回宣言しても、中身が変わることはない(`var`は[冪等性](https://ja.wikipedia.org/wiki/%E5%86%AA%E7%AD%89)ある?)。
<b>>>例１：</b>

```js
var foo = "Foo";
// ここの"foo"変数は一番外側に宣言されている
// このスクリプトのすべての領域が使える(グローバル変数、大域変数とも呼ぶ)
function var_demo() {
  alert(foo);// Fooが表示される
  var bar = "Bar";
  alert(bar);// Bar
}
function var_demo2() {
  alert(foo);// Fooが表示される
  alert(bar);// Error log: Can't find variable: bar
  // こで処理が止まっちゃう
  alert(foo);// 表示されない
}
function var_demo3() {
  alert(foo);// Foo
  alert(baz);// undefined ここは接頭語なしで baz が宣言される
  var baz = "Baz";
  alert(baz);// Baz
}
```
![var_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/87438/b4a94d3c-a79d-7864-f7a5-fcf32d4af7b0.gif)

###キーワードなし
　JavaScriptの変数を宣言する際、接頭語なしで自動的宣言することができる。こうやって宣言された変数はグローバル変数(大域変数)になる。もしある変数を宣言や値を与えることをせず、そのまま使おうとする時、キーワードなしの宣言とみなす場合がある(中身はundefined)。ただし、ある関数の中で宣言したもの(キーワードの種類は関係ない)を、別の関数の中でキーワードなしで同名変数を直接引用することができない(値を与えることはできる。その時キーワードなしの宣言になる)(例１の３つ目の関数)
<b>>>例２：</b>

```js
  function no_key_demo1() {
    foo = "Foo";
    alert(foo);// Foo
  }
  function no_key_demo2() {
    alert(foo);// もし別の関数が先に発動した場合、その関数で定義した foo の値になる
    //もしこの関数が先に発動した場合、エラー Can't find variable: foo が出る
  }
  function no_key_demo3() {
    foo = "Bar";
    alert(foo);// Bar
  }
```
　`no_key_demo2()` 以外の関数が先に発動した時：
![no_keyword1.gif](https://qiita-image-store.s3.amazonaws.com/0/87438/dbf5a151-a5f0-b793-304c-4560878df4dc.gif)
<br>
`no_key_demo2()` が先に発動した時：
![no_keyword2.gif](https://qiita-image-store.s3.amazonaws.com/0/87438/264d806d-46db-4dd5-e37e-b89f9f083150.gif)

###"let"キーワード
　先ほど紹介した２つの宣言の仕方、変数はグローバル変数になりやすいので、変数名を使い切ってしまう可能性が出ていた。`let`キーワードを使えば、変数の作用範囲を制限することができる。
　しかし`let`キーワードはJavaScript 1.7の新機能であるため、サポートするブラウザーが少なく(Safariはサポートしていない)、出現頻度も低い。ただし、使い方はさほど困難ではない。
　`let`の作用範囲は宣言した`{}`の内部である。宣言を行った`{}`の内部さらに`{}`がある場合、内部の`{}`でも同じ変数は使える。
<b>>>例３：</b>

```js
  function let_demo1() {
    let foo = "Foo";
    alert(foo);// Foo
    { // ここの　"{}"　は for、if 文などの "{}" も可
      alert(foo);// Foo
      let bar = "Bar"
      alert(bar)// Bar
    }
    alert(bar)// エラー: bar is not defined
  }
```

Safariは`let`をサポートしていないため、ChromeでDemoする：
![let_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/87438/8baafc1c-706a-c1de-a15b-c265168462eb.gif)

##変数の豆知識
###変数の命名
　JavaScriptの変数の命名は比較的に自由である、英数字、`$`と`_`は使える。ただし、英字、`$`と`_`から始まる必要がある(つまり数字から始めることはできない)。また、`$`や`_`一つのみの変数名は許されていない。なお、一部のライブラリでは`$`に別の役割を与えたので、`$`から始まる変数名は良くない。
　またJavaScriptはその名前のように、オフィシャルで[勧められた命名法](http://analogic.jp/naming-convention/)(変数も関数も)は[キャメル式](https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%A1%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B9)(複合語の中の単語の頭文字を大きくする)である。しかし、あまりにこれに拘ると、JavaScriptの[組み込み関数](http://alphasis.info/javascript/built-in-functions/)と間違われ、下手すると組み込み関数を上書きしてしまうので、気をつけましょう。
　個人的な意見であるが、ソースコードを読む人にわかるようにするには、[スネーク式](https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%A1%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B9#.E3.81.9D.E3.81.AE.E4.BB.96.E3.81.AE.E7.B6.B4.E3.82.8A.E6.96.B9)(単語の間をアンダーバーで間隔する)を勧める。
　そして言うまでもないが、英語以外の文字(日本語ローマ字、中国語ピンインとか)の使用はやめよう。

###定数の宣言
　JavaScriptでは定数(中身が変えられない「変数」)も宣言できる。定数を使う時は`const`キーワードを使う。

```js
  const FOO = "Foo"// 定数は全文大文字で書く方がベター
  function const_demo() {
    alert(FOO);// Foo
    FOO = "Bar";// 定数は変えられないが、ここはエラーも出ない(出るブラウザーがある)
    alert(FOO);// Foo
  }
```
![const_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/87438/8bfc283e-c8dd-5489-c159-aa7863e4029f.gif)

###変数の型を確認
　JavaScriptの変数は宣言する時型は全部`undefined`である。値を付与するとその値の型になる、違う型の値が付与するたびに、型も変えてしまう。変数の型を確認するには`typeof`演算子を用いる(演算子についてはまた後日)。

```js
  var foo;
  function typeof_demo() {
    alert(foo);// undefined
    alert(typeof foo);// undefined
    foo = "Foo";
    alert(foo);// Foo
    alert(typeof foo);// string
    foo = 123;
    alert(foo);// 123
    alert(typeof foo);// number
    foo = 1.23
    alert(foo);// 1.23
    alert(typeof foo);// number　(JavaScriptは整数小数問わず number 型である)
    foo = true;
    alert(foo);// true
    alert(typeof foo);// boolean
  }
```
　![tipeof_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/87438/ef27007a-7883-5d42-d7dc-4b878dc29cb6.gif)

　JavaScript変数の型については、[こちらの記事](http://qiita.com/south37/items/c8d20a069fcbfe4fce85)は詳しく記述している。


#JavaScriptの関数
##関数とは
　JavaScriptの関数は重複利用可能な手続きの集合である。Ruby、Python、Javaなどのメソッド(method)と同じものと理解すれば結構である。
　JavaScriptでは関数を定義する際、`function`キーワードを使う。
　また、JavaScriptの関数はインデントを用いず、`{}`で囲んでいる。
　例えば[前のLesson](http://qiita.com/jerrywdlee/items/96efa42b35e9c9f72c91#%E4%BD%9C%E6%88%90%E3%81%97%E3%81%A6%E5%8B%95%E3%81%84%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86)で出た以下の関数：

```js
  function alert_3_times() {//　ここは関数の宣言
    alert('Hello World!');// ここは関数が行う手続き
    alert('Javascript is Awesome!');
    alert('See You Later ;)');
  }// 必ず括弧を閉じる
```
　この関数のように、関数は主に4つのパーツで作られている。

* 関数宣言：キーワード`function`
* 関数名：上記関数では`alert_3_time`;(使い捨ての無名関数も存在するが、ここでは割愛する)
* 引数：関数名の後の括弧とその中の記述；上記関数では引数はないので`()`だけ書く
* 関数本体：一連の処理手続き、`{}`の中に記述する

　関数を一度作成したら、何度でも呼び出せる。関数を呼び出すには、関数名と引数だけ書けばいい。なお、関数の中で自分を呼び出すこと(再帰/recursion)もできる。

##JavaScriptの組み込み関数
　JavaScriptは使いやすいように、いろんな[組み込み関数](http://alphasis.info/javascript/built-in-functions/)が存在する。先回のLessonから使っている`alert()`関数もその一つである。それらの関数は宣言や定義をせず、名前さえ知っていれば使える。また、単語一つで使える組み込み関数と別に、それらの関数をオブジェクトに収納して、オブジェクトから関数を呼び出せる仕組みもある。その仕組みは[組み込みオブジェクト](http://alphasis.info/javascript/built-in-objects/)として知られている。オブジェクトの使い方については、また後日話します。

##関数の引数
　JavaScriptの関数の引数は関数名に次ぐ`()`の中に記入する、その括弧の間の変数がこの関数の引数になる(別の関数も、関数の外側の処理も、その変数を触ることができない)。
<b>>>例４：</b>

```html
<script type="text/javascript">
  function arg_demo1(foo) {　
    alert(foo);// 括弧の間入れたものを表示する
  }
  function arg_demo2(foo) {
    alert(foo);// 括弧の間入れたものを表示する
    alert(foo*2);// 括弧の間入れた数字を２掛けて表示する
  }
</script>

<!-- このボタン押すと、"FooBar"が表示される -->
<button onclick="arg_demo1('FooBar');">argument Demo</button>

<!-- このボタン押すと、123と246が表示される -->
<button onclick="arg_demo2(123);">argument Demo2</button>
```
![argument_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/87438/a98719cc-135d-f320-ebdc-2dfc4d5f008d.gif)
　上記のソースコードの中、`arg_demo1`関数を呼び出すとき、引数の`FooBar`は`''`で囲んでいた。それはJavaScriptで文字列を扱うときの要注意である。JavaScriptで文字列を扱うときは必ず`""`か`''`で囲むこと。もし外側が`""`を使ったとき、中の文字列は`''`にする。もちろん、逆も可能である。

　関数の引数は複数個持つこともできる。複数の引数を使う場合、各引数の間で`,`で区切る。また、関数の引数の部分に`baz = 'Baz'`のような値を付与する書き方をすると、この値の初期値を決めることができる。
<b>>>例５：</b>

```html
<script type="text/javascript">
  function arg_demo2(foo,bar,baz = "Baz") {
    //ここでもしこの関数を呼び出す時引数は２個しか与えていない
    //bazが"Baz"という初期値になる
    alert(foo);
    alert(bar);
    alert(baz);
  }
</script>
<!-- alert: Foo,Bar,Baz -->
<button onclick="arg_demo2('Foo','Bar');">argument Demo 1</button>

<!-- alert: Foo,Bar,FooBar -->
<button onclick="arg_demo2('Foo','Bar','FooBar');">argument Demo 2</button>

```

##関数の戻り値
　JavaScriptの関数は引数がで値を代入することができる、当たり前のように、戻り値を返すこともできる。ただし、引数は複数個与えられるが、戻り値は基本１つしかない。
<b>>>例６：</b>

```html
<script type="text/javascript">
  function return_demo() {
    var foo = "Foo";
    return foo;
  }
</script>

<!-- alert:Foo  -->
<button onclick="alert(return_demo());">return Demo</button>
```

解説：ここ関数`return_demo()`の戻り値`foo`の値`"Foo"`が`alert()`に渡され、表示される。

##関数の再帰
　JavaScriptの関数は関数中の手続きで、自分を呼び出すことができる。ただ、エンドポイントを定めないと無限の再帰になってしまうので、使用する際は気を使ったほうがいい。
　基本JavaScriptの関数は手続きが終わった時点で自動的に終わるが、再帰などを使うとき、途中で止めようとする時は`return`を使う。
<b>>>例７：</b>

```html
<script type="text/javascript">
  function rec_demo(foo) {
    alert(foo);
    foo--;// foo の値が１減る
    if (foo === 0) {// もし foo が０になった場合
      return;// 関数を終了させる
    }
    rec_demo(foo);
  }
</script>
<!-- 5,4,3,2,1の順で表示される -->
<button onclick="rec_demo(5)">Recursion Demo</button>
```

#要点復習

* JSの変数は殆ど`var`で宣言しているが、接頭語なしや`let`での宣言もある。
* JSの変数はそれぞれ作用範囲がある、それを無視するとエラーが出る。
* JSは組み込み関数たくさん持っているが、自分で関数を書く時は`function`を使う。
* 関数は複数の引数が使えるが、戻り値は基本１つのみ。

<b>以上でした。お疲れ様です。</b>

![sandynsue.jpg](https://qiita-image-store.s3.amazonaws.com/0/87438/8abe0584-cb62-571f-b3f1-6653a601bb18.jpeg)
『[Look, listen and learn!](https://openlibrary.org/works/OL10554472W/Look_listen_and_learn!)』の主人公:SandyとSue。
<b>[目次へ戻る](http://qiita.com/jerrywdlee/items/eb95d6bad4695dc7ba2a#%E7%9B%AE%E6%AC%A1)</b>