【初心者向け】JavaScriptのグローバル変数とは?使い方と注意点

JavaScriptのグローバル変数を初心者向けに詳しく解説。基本的な概念から実際の使用例、よくある問題と回避方法まで、安全で効率的なコードを書くための重要な知識を分かりやすく紹介します。

Learning Next 運営
26 分で読めます

【初心者向け】JavaScriptのグローバル変数とは?使い方と注意点

みなさん、JavaScriptを書いていて困ったことありませんか?

「この変数、他の関数からも使いたいな...」 「どこからでもアクセスできる変数って作れるの?」

こんな疑問を感じたことがある方、きっと多いですよね。

実は、JavaScriptにはグローバル変数という便利な仕組みがあるんです! これを使えば、プログラム全体で共有できる変数を作れるようになります。

この記事では、初心者の方でも分かりやすく、グローバル変数の基本から注意点まで詳しく解説します。 正しい使い方をマスターして、もっと便利なプログラムを作ってみませんか?

グローバル変数って何だろう?

簡単に言うとどんなもの?

グローバル変数とは、プログラム全体のどこからでも使える変数のことです。

普通の変数は関数の中でしか使えませんが、グローバル変数は違います。 どの関数からでも自由にアクセスできるんです。

// グローバル変数の例
let globalMessage = "みんなで使える変数です";
let globalCount = 0;
function showMessage() {
// 関数内からグローバル変数を使える
console.log(globalMessage);
globalCount++;
console.log(`カウント: ${globalCount}`);
}
function resetCount() {
// 別の関数からも使える
globalCount = 0;
console.log("カウントをリセットしました");
}
showMessage(); // "みんなで使える変数です" "カウント: 1"
showMessage(); // "みんなで使える変数です" "カウント: 2"
resetCount(); // "カウントをリセットしました"

まるで、みんなが使える共通の道具箱みたいな感じですね。

グローバル変数の特徴

グローバル変数にはこんな特徴があります。

  • どこからでもアクセスできる
  • プログラムが終わるまでずっと存在する
  • ブラウザのwindowオブジェクトに追加される(varの場合)
  • 名前が重複すると問題が起きる可能性
// ブラウザでの例
var browserGlobal = "ブラウザの変数";
console.log(window.browserGlobal); // "ブラウザの変数"
console.log(browserGlobal); // "ブラウザの変数"
// letとconstはwindowに追加されない
let modernGlobal = "モダンな変数";
console.log(window.modernGlobal); // undefined
console.log(modernGlobal); // "モダンな変数"

便利だけど、使い方に注意が必要なんです。

グローバル変数の作り方

基本的な作成方法

一番簡単な方法は、関数の外で変数を宣言することです。

// 方法1: var を使用
var globalVar = "varで作った変数";
// 方法2: let を使用
let globalLet = "letで作った変数";
// 方法3: const を使用
const globalConst = "constで作った変数";
function testGlobalAccess() {
console.log(globalVar); // アクセスできる
console.log(globalLet); // アクセスできる
console.log(globalConst); // アクセスできる
// 変更のテスト
globalVar = "変更されたvar";
globalLet = "変更されたlet";
// globalConst = "変更不可"; // エラー!constは変更できない
}
testGlobalAccess();
console.log(globalVar); // "変更されたvar"
console.log(globalLet); // "変更されたlet"

どの方法でも作れますが、それぞれ特徴が違います。

危険な作り方(やらないで!)

宣言なしで変数を作ると、勝手にグローバル変数になってしまいます。

function createDangerousGlobal() {
// 宣言なしで代入(危険!)
dangerousGlobal = "危険な変数";
}
createDangerousGlobal();
console.log(dangerousGlobal); // "危険な変数"
// strict modeを使えば防げる
"use strict";
function strictFunction() {
// strictGlobal = "エラーになる"; // ReferenceError
}

このやり方は避けましょう。 思わぬバグの原因になります。

windowオブジェクトに直接追加

ブラウザでは、windowオブジェクトに直接追加することもできます。

// windowオブジェクトに追加
window.customGlobal = "windowに追加した変数";
console.log(customGlobal); // "windowに追加した変数"
// thisを使った方法
this.anotherGlobal = "thisで追加";
console.log(anotherGlobal); // "thisで追加"

でも、これもあまりおすすめしません。

実際に使ってみよう

アプリの設定を管理

アプリケーションの設定をグローバル変数で管理してみましょう。

// アプリの設定をグローバルで管理
const APP_CONFIG = {
version: "1.0.0",
apiUrl: "https://api.example.com",
theme: "light",
language: "ja",
debugMode: false
};
// 設定を変更する関数
function updateTheme(newTheme) {
if (["light", "dark", "auto"].includes(newTheme)) {
APP_CONFIG.theme = newTheme;
console.log(`テーマを ${newTheme} に変更しました`);
applyTheme();
} else {
console.log("無効なテーマです");
}
}
function applyTheme() {
document.body.className = `theme-${APP_CONFIG.theme}`;
console.log(`テーマ ${APP_CONFIG.theme} を適用しました`);
}
// 使用例
console.log(`アプリバージョン: ${APP_CONFIG.version}`);
updateTheme("dark");

アプリの設定が一箇所で管理できて便利ですね。

ユーザー情報を保持

ログインしたユーザーの情報を保持してみましょう。

// ユーザー情報をグローバルで管理
let currentUser = null;
function login(username, email) {
currentUser = {
username: username,
email: email,
loginTime: new Date(),
isLoggedIn: true
};
console.log(`${username} さんがログインしました`);
updateUserInterface();
}
function logout() {
if (currentUser) {
console.log(`${currentUser.username} さんがログアウトしました`);
currentUser = null;
updateUserInterface();
}
}
function updateUserInterface() {
if (currentUser && currentUser.isLoggedIn) {
console.log(`ようこそ、${currentUser.username} さん`);
// ここでUIの更新
} else {
console.log("ログインしてください");
// ここでログインフォームの表示
}
}
function getCurrentUser() {
return currentUser;
}
// 使用例
login("太郎", "taro@example.com");
console.log("現在のユーザー:", getCurrentUser());
logout();

ユーザー情報が色んな場所から使えて便利です。

ショッピングカート

ネットショップのカート機能を作ってみましょう。

// ショッピングカートをグローバルで管理
let shoppingCart = [];
let cartTotal = 0;
function addToCart(productId, productName, price, quantity = 1) {
// 既にある商品かチェック
let existingItem = shoppingCart.find(item => item.id === productId);
if (existingItem) {
existingItem.quantity += quantity;
console.log(`${productName} の数量を ${quantity} 個追加しました`);
} else {
let newItem = {
id: productId,
name: productName,
price: price,
quantity: quantity
};
shoppingCart.push(newItem);
console.log(`${productName} をカートに追加しました`);
}
updateCartTotal();
displayCart();
}
function removeFromCart(productId) {
let index = shoppingCart.findIndex(item => item.id === productId);
if (index !== -1) {
let removedItem = shoppingCart.splice(index, 1)[0];
console.log(`${removedItem.name} をカートから削除しました`);
updateCartTotal();
displayCart();
}
}
function updateCartTotal() {
cartTotal = shoppingCart.reduce((total, item) => {
return total + (item.price * item.quantity);
}, 0);
}
function displayCart() {
console.log("=== ショッピングカート ===");
if (shoppingCart.length === 0) {
console.log("カートは空です");
} else {
shoppingCart.forEach(item => {
console.log(`${item.name} × ${item.quantity} = ¥${item.price * item.quantity}`);
});
console.log(`合計: ¥${cartTotal}`);
}
console.log("========================");
}
// 使用例
addToCart(1, "ノートPC", 89800, 1);
addToCart(2, "マウス", 2980, 2);
addToCart(1, "ノートPC", 89800, 1); // 既存商品の数量追加
removeFromCart(2);

カート情報がどの関数からでも更新できて便利ですね。

ローカル変数との違いを知ろう

スコープの違い

グローバル変数とローカル変数の違いを見てみましょう。

// グローバル変数
let globalVariable = "グローバルスコープ";
function demonstrateScope() {
// ローカル変数
let localVariable = "ローカルスコープ";
console.log("関数内から:");
console.log("グローバル変数:", globalVariable); // 使える
console.log("ローカル変数:", localVariable); // 使える
}
demonstrateScope();
console.log("関数外から:");
console.log("グローバル変数:", globalVariable); // 使える
// console.log("ローカル変数:", localVariable); // エラー!使えない

ローカル変数は関数の外では使えないんです。

変数の隠蔽(シャドウイング)

同じ名前の変数があると、ローカル変数が優先されます。

let message = "グローバルメッセージ";
function testShadowing() {
let message = "ローカルメッセージ"; // グローバル変数を隠す
console.log("関数内のmessage:", message); // "ローカルメッセージ"
// グローバル変数にアクセスするには
console.log("グローバルのmessage:", window.message);
}
testShadowing();
console.log("関数外のmessage:", message); // "グローバルメッセージ"

名前が同じだと、混乱の原因になります。

よくある問題と解決方法

名前が重複する問題

// 問題のある例:名前衝突
var name = "ユーザー名";
var count = 0;
// 他のコードが同じ名前を使用
var name = "別の名前"; // 元の値が上書きされる
var count = "文字列"; // 型も変わってしまう
console.log(name); // "別の名前"
console.log(count); // "文字列"

これは危険ですね。 解決方法を見てみましょう。

// 解決方法1: 名前空間を使う
const MyApp = {
name: "ユーザー名",
count: 0,
config: {
version: "1.0.0",
debug: false
}
};
console.log(MyApp.name); // "ユーザー名"
console.log(MyApp.count); // 0
// 解決方法2: プリフィックスを付ける
const myapp_name = "ユーザー名";
const myapp_count = 0;
const myapp_config = { version: "1.0.0" };

これで安全に管理できます。

意図しない変更の問題

// 問題のある例:勝手に変更される
let userSettings = {
theme: "light",
language: "ja"
};
function someFunction() {
// 意図せずグローバル変数を変更
userSettings.theme = "dark";
userSettings.newProperty = "追加されたプロパティ";
}
console.log("変更前:", userSettings);
someFunction();
console.log("変更後:", userSettings); // 勝手に変更される

これも困りますね。 解決方法があります。

// 解決方法1: Object.freeze()で保護
const protectedSettings = Object.freeze({
theme: "light",
language: "ja"
});
function saferFunction() {
// protectedSettings.theme = "dark"; // エラーまたは無視される
console.log("設定は保護されています");
}
// 解決方法2: 関数に引数として渡す
function processSettings(settings) {
// コピーを作成
let localSettings = { ...settings };
localSettings.theme = "dark";
return localSettings;
}
let originalSettings = { theme: "light", language: "ja" };
let modifiedSettings = processSettings(originalSettings);
console.log("元の設定:", originalSettings); // 変更されない
console.log("変更された設定:", modifiedSettings); // 変更版

これで安全に使えますね。

安全な使い方をマスターしよう

名前空間パターン

関連する機能をオブジェクトにまとめる方法です。

// 良い例:名前空間パターン
const MyApplication = {
// 設定
config: {
version: "1.0.0",
apiUrl: "https://api.example.com",
debug: false
},
// データ
data: {
users: [],
currentUser: null
},
// ユーティリティ関数
utils: {
formatDate: function(date) {
return date.toLocaleDateString("ja-JP");
},
generateId: function() {
return Date.now().toString(36) + Math.random().toString(36).substr(2);
}
},
// 初期化
init: function() {
console.log(`${this.config.version} を初期化中...`);
this.loadUserData();
},
loadUserData: function() {
console.log("ユーザーデータを読み込みました");
}
};
// 使用例
MyApplication.init();
console.log("アプリバージョン:", MyApplication.config.version);

すべてが整理されて分かりやすいですね。

モジュールパターン

プライベートな変数と関数を作る方法です。

// モジュールパターンを使った実装
const UserManager = (function() {
// プライベート変数(外からアクセスできない)
let users = [];
let currentUserId = null;
// プライベート関数
function validateUser(user) {
return user && user.name && user.email;
}
function generateUserId() {
return 'user_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
}
// パブリックAPI(外から使える関数)
return {
addUser: function(name, email) {
if (!name || !email) {
console.log("名前とメールアドレスは必須です");
return;
}
let user = {
id: generateUserId(),
name: name,
email: email,
createdAt: new Date()
};
if (validateUser(user)) {
users.push(user);
console.log(`ユーザー ${name} を追加しました`);
return user.id;
}
},
getUser: function(userId) {
return users.find(user => user.id === userId);
},
getAllUsers: function() {
return users.map(user => ({ ...user })); // コピーを返す
},
setCurrentUser: function(userId) {
if (this.getUser(userId)) {
currentUserId = userId;
console.log(`現在のユーザーを ${userId} に設定しました`);
} else {
console.log("指定されたユーザーが見つかりません");
}
},
getCurrentUser: function() {
return currentUserId ? this.getUser(currentUserId) : null;
},
getUserCount: function() {
return users.length;
}
};
})();
// 使用例
let userId1 = UserManager.addUser("太郎", "taro@example.com");
let userId2 = UserManager.addUser("花子", "hanako@example.com");
UserManager.setCurrentUser(userId1);
console.log("現在のユーザー:", UserManager.getCurrentUser());
console.log("総ユーザー数:", UserManager.getUserCount());

プライベートな部分が守られて安全ですね。

ES6モジュール(現代的な方法)

現代のJavaScriptでは、モジュールシステムを使うのがおすすめです。

// config.js ファイル
export const APP_CONFIG = {
version: "1.0.0",
apiUrl: "https://api.example.com",
theme: "light"
};
export function updateConfig(key, value) {
if (APP_CONFIG.hasOwnProperty(key)) {
APP_CONFIG[key] = value;
console.log(`設定 ${key}${value} に更新しました`);
}
}
// userManager.js ファイル
let currentUser = null;
export function setCurrentUser(user) {
currentUser = user;
}
export function getCurrentUser() {
return currentUser;
}
export function clearCurrentUser() {
currentUser = null;
}
// main.js ファイル
import { APP_CONFIG, updateConfig } from './config.js';
import { setCurrentUser, getCurrentUser } from './userManager.js';
console.log("アプリ設定:", APP_CONFIG);
updateConfig('theme', 'dark');
setCurrentUser({ name: "太郎", email: "taro@example.com" });
console.log("現在のユーザー:", getCurrentUser());

これが一番安全で現代的な方法です。

まとめ

JavaScriptのグローバル変数について学びました。

グローバル変数の特徴

  • プログラム全体からアクセス可能
  • プログラム終了まで存在
  • 便利だけど注意が必要

実用的な使い方

  • アプリケーション設定の管理
  • ユーザー情報の保持
  • ショッピングカートの管理

よくある問題

  • 名前衝突のリスク
  • 意図しない変更
  • メモリの無駄遣い

安全な使い方

  • 名前空間パターンを使う
  • モジュールパターンを活用
  • ES6モジュールがおすすめ

グローバル変数は便利な機能ですが、使い方に注意が必要です。 現代のJavaScript開発では、ES6モジュールを使うのがベストプラクティスです。

最初は簡単な例から始めて、だんだんと安全な方法を覚えていきましょう。 正しく使えるようになれば、とても便利なプログラムが作れるようになりますよ。

ぜひ今日から、これらの技術を活用して、もっと良いプログラムを作ってみませんか?

関連記事