JavaScriptでの変数、スコープ、および巻き上げについて理解する
序章
変数は、多くのプログラミング言語の基本的な部分であり、初心者のコーダーが学ぶ最初の最も重要な概念の1つです。 JavaScriptには変数のさまざまなプロパティがあり、名前を付けるときに従わなければならないいくつかのルールがあります。 JavaScriptでは、変数を宣言するために使用される3つのキーワードがあります— var
, let
、 と const
—そしてそれぞれがコードが変数を異なる方法で解釈する方法に影響を与えます。
このチュートリアルでは、変数とは何か、変数を宣言して名前を付ける方法について説明し、変数の違いについても詳しく見ていきます。 var
, let
、 と const
. また、巻き上げの影響と、変数の動作に対するグローバルスコープとローカルスコープの重要性についても確認します。
変数を理解する
変数は、値を格納するために使用される名前付きコンテナーです。 複数回参照する可能性のある情報は、後で使用または変更するために変数に格納できます。 JavaScriptでは、変数内に含まれる値は、数値、文字列、オブジェクトなど、任意のJavaScriptデータ型にすることができます。
今日のJavaScriptが基づいているECMAScript2015(ES6)言語仕様以前は、変数を宣言する方法は1つしかありませんでした。 var
キーワード。 その結果、ほとんどの古いコードと学習リソースは使用するだけです var
変数の場合。 の違いについて説明します var
, let
、 と const
以下の独自のセクションのキーワード。
使用できます var
変数自体の概念を示すため。 以下の例では、変数を宣言し、それに値を割り当てします。
// Assign the string value Sammy to the username identifier
var username = "sammy_shark";
このステートメントは、いくつかの部分で構成されています。
- を使用した変数の宣言
var
キーワード - 変数名(または識別子)、
username
- で表される代入演算
=
構文 - 割り当てられている値、
"sammy_shark"
今、私たちは使用することができます username
コードで。 JavaScriptはそれを覚えています username
文字列値を表します sammy_shark
.
// Check if variable is equal to value
if (username === "sammy_shark") {
console.log(true);
}
Outputtrue
前述のように、変数は任意のJavaScriptデータ型を表すために使用できます。 この例では、文字列、数値、オブジェクト、ブール値、およびnull値を使用して変数を宣言します。
// Assignment of various variables
var name = "Sammy";
var spartans = 300;
var kingdoms = [ "mammals", "birds", "fish" ];
var poem = { roses: "red", violets: "blue" };
var success = true;
var nothing = null;
使用する console.log
、特定の変数に含まれている値を確認できます。
// Send spartans variable to the console
console.log(spartans);
Output300
変数はデータをメモリに保存し、後でアクセスして変更することができます。 変数を再割り当てして、新しい値を指定することもできます。 以下の簡単な例は、パスワードを変数に保存してから更新する方法を示しています。
// Assign value to password variable
var password = "hunter2";
// Reassign variable value with a new value
password = "hunter3";
console.log(password);
Output'hunter3'
実際のプログラムでは、パスワードはデータベースに安全に保存される可能性があります。 ただし、この例は、変数の値を更新する必要がある状況を示しています。 の値 password
だった hunter2
、しかし私たちはそれをに再割り当てしました hunter3
これは、JavaScriptがその時点から認識する値です。
変数の命名
変数名は、JavaScriptでは識別子と呼ばれます。 JavaScriptの構文とコード構造の理解で識別子の命名規則のいくつかについて説明しました。ここに要約します:
- 変数名は文字のみで構成できます(
a-z
)、数字(0-9
)、ドル記号($
)、およびアンダースコア(_
) - 変数名に空白文字(タブまたはスペース)を含めることはできません
- 数字で変数の名前を始めることはできません
- 変数名として使用できない予約キーワードがいくつかあります
- 変数名では大文字と小文字が区別されます
JavaScriptには、で宣言された関数と変数の名前にキャメルケース(キャメルケースとして定型化されることもあります)を使用する規則もあります。 var
また let
. これは、最初の単語を小文字で記述し、その後のすべての単語の最初の文字をスペースなしで大文字にする方法です。 定数ではないほとんどの変数は、いくつかの例外を除いて、この規則に従います。 定数である変数の名前。 const
キーワードは、通常、すべて大文字で記述されます。
これは学ぶべき多くのルールのように思えるかもしれませんが、有効で従来の変数名を書くことはすぐに第二の性質になります。
との差 var
, let
、 と const
JavaScriptには、変数を宣言するための3つの異なるキーワードがあり、言語に複雑さの層を追加します。 3つの違いは、スコープ、巻き上げ、および再割り当てに基づいています。
自分のプログラムで3つのうちどれを使うべきか疑問に思うかもしれません。 一般的に受け入れられている方法は、 const
可能な限り、そして let
ループと再割り当ての場合。 一般的、 var
レガシーコードでの作業以外では回避できます。
可変スコープ
JavaScriptのScopeは、JavaScriptへの変数のアクセス可能性を決定するコードの現在のコンテキストを指します。 スコープには、ローカルとグローバルの2種類があります。
- グローバル変数は、ブロック外で宣言されたものです
- ローカル変数は、ブロック内で宣言された変数です
以下の例では、グローバル変数を作成します。
// Initialize a global variable
var creature = "wolf";
変数を再割り当てできることを学びました。 ローカルスコープを使用すると、元の値を変更または再割り当てすることなく、外部スコープの変数と同じ名前の新しい変数を実際に作成できます。
以下の例では、グローバルを作成します species
変数。 関数内には、同じ名前のローカル変数があります。 それらをコンソールに送信することで、スコープによって変数の値がどのように異なり、元の値が変更されていないかを確認できます。
// Initialize a global variable
var species = "human";
function transform() {
// Initialize a local, function-scoped variable
var species = "werewolf";
console.log(species);
}
// Log the global and local variable
console.log(species);
transform();
console.log(species);
Outputhuman
werewolf
human
この例では、ローカル変数はfunction-scopedです。 で宣言された変数 var
キーワードは常に関数スコープです。つまり、関数は別のスコープを持つものとして認識されます。 したがって、このローカルスコープの変数には、グローバルスコープからアクセスできません。
新しいキーワード let
と const
ただし、ブロックスコープです。 これは、新しいローカルスコープが、関数ブロックを含むあらゆる種類のブロックから作成されることを意味します。 if
ステートメント、および for
と while
ループします。
関数スコープ変数とブロックスコープ変数の違いを説明するために、新しい変数を if
を使用してブロック let
.
var fullMoon = true;
// Initialize a global variable
let species = "human";
if (fullMoon) {
// Initialize a block-scoped variable
let species = "werewolf";
console.log(`It is a full moon. Lupin is currently a ${species}.`);
}
console.log(`It is not a full moon. Lupin is currently a ${species}.`);
OutputIt is a full moon. Lupin is currently a werewolf.
It is not a full moon. Lupin is currently a human.
この例では、 species
変数にはグローバルに1つの値があります(human
)、およびローカルで別の値(werewolf
). 使用する場合 var
ただし、結果は異なります。
// Use var to initialize a variable
var species = "human";
if (fullMoon) {
// Attempt to create a new variable in a block
var species = "werewolf";
console.log(`It is a full moon. Lupin is currently a ${species}.`);
}
console.log(`It is not a full moon. Lupin is currently a ${species}.`);
OutputIt is a full moon. Lupin is currently a werewolf.
It is not a full moon. Lupin is currently a werewolf.
この例の結果では、グローバル変数とブロックスコープ変数の両方が同じ値になります。 werewolf
. これは、で新しいローカル変数を作成する代わりに var
、同じスコープで同じ変数を再割り当てしています。 var
認識しません if
別の新しいスコープの一部になります。 ブロックスコープの変数は、意図せずに変数値をオーバーライドする可能性が低いコードを生成するため、一般的に宣言することをお勧めします。
巻き上げ
これまでのほとんどの例では、 var
変数を宣言し、値を使用して初期化します。 宣言して初期化した後、変数にアクセスまたは再割り当てできます。
宣言および初期化される前に変数を使用しようとすると、次のようになります。 undefined
.
// Attempt to use a variable before declaring it
console.log(x);
// Variable assignment
var x = 100;
Outputundefined
ただし、省略した場合 var
キーワードでは、変数を宣言するのではなく、初期化するだけです。 それは戻ります ReferenceError
スクリプトの実行を停止します。
// Attempt to use a variable before declaring it
console.log(x);
// Variable assignment without var
x = 100;
OutputReferenceError: x is not defined
この理由は、 hoisting が原因です。これは、変数と関数の宣言がスコープの最上位に移動されるJavaScriptの動作です。 初期化ではなく実際の宣言のみが引き上げられるため、最初の例の値は次のようになります。 undefined
.
この概念をより明確に示すために、以下は私たちが書いたコードとJavaScriptが実際にそれをどのように解釈したかを示しています。
// The code we wrote
console.log(x);
var x = 100;
// How JavaScript interpreted it
var x;
console.log(x);
x = 100;
JavaScriptが保存されました x
スクリプトの実行前に変数としてメモリに。 定義される前にまだ呼び出されていたため、結果は次のようになります。 undefined
ではなく 100
. ただし、 ReferenceError
スクリプトを停止します。 でも var
キーワードは実際には場所を変更しませんでした var
、これは巻き上げがどのように機能するかを表すのに役立ちます。 ただし、このコードを作成したプログラマーは次の出力を期待している可能性があるため、この動作は問題を引き起こす可能性があります。 x
することが 100
、代わりに undefined
.
次の例では、巻き上げによって予測できない結果が生じる可能性があることもわかります。
// Initialize x in the global scope
var x = 100;
function hoist() {
// A condition that should not affect the outcome of the code
if (false) {
var x = 200;
}
console.log(x);
}
hoist();
Outputundefined
この例では、次のように宣言しました x
することが 100
グローバルに。 に応じて if
声明、 x
に変更される可能性があります 200
、しかし条件があったので false
の値に影響を与えるべきではありませんでした x
. その代わり、 x
の上部に吊り上げられました hoist()
関数、および値はなりました undefined
.
このタイプの予測できない動作は、プログラムにバグを引き起こす可能性があります。 以来 let
と const
ブロックスコープの場合、以下に示すように、この方法で吊り上げることはありません。
// Initialize x in the global scope
let x = true;
function hoist() {
// Initialize x in the function scope
if (3 === 4) {
let x = false;
}
console.log(x);
}
hoist();
Outputtrue
変数の重複宣言。これは次の場合に可能です。 var
、でエラーをスローします let
と const
.
// Attempt to overwrite a variable declared with var
var x = 1;
var x = 2;
console.log(x);
Output2
// Attempt to overwrite a variable declared with let
let y = 1;
let y = 2;
console.log(y);
OutputUncaught SyntaxError: Identifier 'y' has already been declared
要約すると、 var
変数宣言がメモリに保存されるJavaScriptのメカニズムであるホイストの影響を受ける可能性があります。 これにより、コードに未定義の変数が生じる可能性があります。 の導入 let
と const
変数を宣言する前に変数を使用しようとしたとき、または変数を複数回宣言しようとしたときにエラーをスローすることで、この問題を解決します。
定数
多くのプログラミング言語は、定数を備えています。これは、変更または変更できない値です。 JavaScriptでは、 const
識別子は定数に基づいてモデル化され、値は const
再割り当てできません。
すべてを書くのが一般的な慣習です const
大文字の識別子。 これにより、他の変数値と簡単に区別できるようになります。
以下の例では、変数を初期化します SPECIES
定数として const
キーワード。 変数を再割り当てしようとすると、エラーが発生します。
// Assign value to const
const SPECIES = "human";
// Attempt to reassign value
SPECIES = "werewolf";
console.log(SPECIES);
OutputUncaught TypeError: Assignment to constant variable.
以来 const
値を再割り当てすることはできません。値の宣言と初期化を同時に行う必要があります。そうしないと、エラーがスローされます。
// Declare but do not initialize a const
const TODO;
console.log(TODO);
OutputUncaught SyntaxError: Missing initializer in const declaration
プログラミングで変更できない値はimmutableと呼ばれ、変更できる値はmutableです。 それでも const
値を再割り当てすることはできません。で宣言されたオブジェクトのプロパティを変更できるため、値は変更可能です。 const
.
// Create a CAR object with two properties
const CAR = {
color: "blue",
price: 15000
}
// Modify a property of CAR
CAR.price = 20000;
console.log(CAR);
Output{ color: 'blue', price: 20000 }
定数は、将来の自分自身やプロジェクトで作業している他のプログラマーに、目的の変数を再割り当てしてはならないことを明確にするのに役立ちます。 変数が将来変更される可能性があると予想される場合は、使用する可能性があります let
代わりに変数を宣言します。
結論
このチュートリアルでは、変数とは何か、変数の命名規則、および変数値を再割り当てする方法について説明しました。 また、スコープと巻き上げ、オリジナルの制限のいくつかについて学びました var
キーワード、および方法 let
と const
それらの問題を修正します。
他の言語での変数の使用方法を比較するには、「 Python3で変数を使用する方法」に関するチュートリアルをお読みください。