「JavaScript/変数」の版間の差分

削除された内容 追加された内容
Ef3 (トーク | 投稿記録)
→‎定数: const への代入は SyntaxError ではなく TypeError
Ef3 (トーク | 投稿記録)
→‎変数の宣言方法の全体像: const も要素の変更は妨げられない。複合オブジェクトの代入は別名を作り出す。
2 行
 
== 変数の宣言方法の全体像 ==
「変数」は、オブジェクトに名前をつけて参照の手助けをする機能です。
「変数」には、データを一定のあいだ保存するために、メモリ上に値を格納できる機能があります。また、変数の「宣言」とは、メモリ上にこれから変数のデータを格納し始める事を命令し始める事です。
型や値は変数ではなくオブジェクトが保持しています。
静的な言語に慣れた人は、やや戸惑いを感じるかもしれません。
 
JavaScriptで変数を宣言する方法は、一般的には<code>var</code>または{{code|let}} キーワードで宣言します。 var の読みは特に決まってないので、「バル」とか「バー」とか読めばいいと思います。
 
;'''コード例'''
<syntaxhighlight lang="html5javascript">
<script>
var x = 2;
document.write(x + 3); // x + 3 を計算した結果の 5 を表示
document.write(x + 3); // 5 と表示
</script>
</syntaxhighlight>
 
 
ですが、実は、なにもキーワードをつけず、
<syntaxhighlight lang="html5javascript">
<script>
x = 2;
document.write(x + 3); // x + 3 を計算した結果の 5 を表示
document.write(x + 3); // 5 と表示
</script>
</syntaxhighlight>
 
のように、直接、変数名を宣言を行っも、いない変数に値作成代入する事はことも可能です。
 
しかし、変数直接作成宣言なしで方法使用非推奨です(書籍などでも紹介されない場合も多い
strictモードでは、宣言無しでの代入は SyntaxError になります。
また、strictモードでは、キーワード無しの直接作成の方法は、使用が禁じられています。(なお、既に var または let で作成された変数の値を書き換えるのなら、キーワード無しでも可能です。また、letは宣言以外で使用が禁止されていますので(let宣言された変数を置き換える場合、キーワード無しで置き換えます)、この仕様は重要です。)
 
可読性を低下させる意味でも、宣言無しでの代入は控えるべきです。
 
なので、変数の作成の際には var または let をつけましょう。また値を変える予定がないのであれば、後述の [[#定数|const]] の使用も検討して下さい。
また、第三者のプログラマーにとっての可読性が、キーワード無しの直接作成の方法では悪くなります。
 
var と let では、関数のブロックに対する振る舞いが違います(詳しくは [[#let|let の単元]]で後述します。)。
 
なお、ECMA2015からletが導入されましのはECMA2015(ES6)なので、それ以前のバージョンのJavaScriptではletは使えないですません
なので、変数の作成の際には、なるべく var または let をつけましょう。
 
少なくりあえず、キーワード無も宣言なしで宣言代入する比べたられば、var宣言でもいいので キーワードの存在で宣言ているほうが可読性も良く、遥かにマシなので、まずは var キーワードをつけて変数を宣言するように心がけましょう。
var と let の違いは、主に関数のブロックに対する振る舞いの違いです(詳しくは let の単元で後述します。)。let のほうが、C言語の変数宣言の仕組みに近い古い舞いになります。そのためか今後の予想としては、let のほうが、より推奨されることが、プログラマー界隈では予想されます。
 
また宣言で初期値を与えないことも可能ですが、未初期化変数の参照は(意外なことに)エラーとはならないので、発見困難なバグの原因にしないためにも必ず宣言時に初期化を行いましょう。
なお、ECMA2015からletが導入されましたので、それ以前のバージョンのJavaScriptではletは使えないです。
 
<syntaxhighlight lang="javascript">
とりあえず、キーワード無しで宣言するのと比べたら、var宣言でもいいのでキーワードの存在しているほうが可読性も良く、遥かにマシなので、まずは var キーワードをつけて変数を宣言するように心がけましょう。
var x;
document.write(x); // undefined と表示(ReferenceErrorになるのは未宣言の場合で、この場合はならない)
y = 100; // 未宣言変数への代入
document.write(y); // 100 と表示、結果的に代入が宣言のように振る舞う。
z = 200; // グローバル変数への代入の実体は、グローバルオブジェクトのプロパティへの代入
window.z = 200; // これとおなじ
</syntaxhighlight>
 
===代入===
既に var または let で作成された変数の値を書き換えるのならキーワード無しでも可能ですが、その場合は宣言ではなく代入になります。
<syntaxhighlight lang="javascript">
var x = 8;
document.write(x + 3); // 58 と表示
x = "abc"; // 違う型のオブジェクトを代入
document.write(x + 3); // 5abc と表示
</syntaxhighlight>
代入をする時、それまでの値の型と違う型であっても構いません。
JavaScriptは動的な言語なので「変数はオブジェクトに名前を提供し参照の手助け」をしていることを端的に表しています。
 
なお、{{code|const}} キーワードで定数を宣言する事が出来ます。JavaScriptにおける「定数」とは、その名の通り、値の変更を許さない変数のことです。(「定数」を「変数」の特殊なものに分類するのは、数学的には違和感を感じる人もいるかもしれないが、プログラミングでは便宜上、このように分類する。プログラミングでいう「変数」とは、単に値を格納するもの、という意味である。数学でいう、値の変動する代数とは、プログラミング「変数」は意味が異なることに、読者は留意してもらいたい。)
 
<syntaxhighlight lang="javascript">
const x = 12;
const y = x * 2; // 初期化には既知の値のみで組み立てられた式が使える
x = 1; // SyntaxError: Identifier 'x' has already been declared
</syntaxhighlight>
 
const は定数を宣言しますが、Array(配列)オブジェクトや Object(連想配列)オブジェクトのように、複合的なオブジェクトの要素の変更は妨げません。
<syntaxhighlight lang="javascript" line>
const ary1 = [1,2,3];
const ary2 = ary1;
ary2[1] = "abc";
console.log(ary); // 1,abc,3
</syntaxhighlight>
* 3行目で定数な筈のaryの要素を書き換えています(ary1を書き換えるのは出来ませんが要素は可能)。
* 3行目で変更したのは ary2 の1番めの要素なのに、4行目で表示するとary1の要素が書き換わっています。
** これは、2行目でary2をary1で初期化しているためで、この時 ary2 は ary1 の別名になっています。
 
== 変数の自動判定 ==