はじめに
クロージャについて理解したことを備忘録兼ねて投稿します。
目次
クロージャとはなにか
クロージャとは、ある関数の中で、その関数と一緒に使われる変数や関数を、いつまでも
覚えている機能のことです。つまり、関数の中で使われたものを覚えておいて、また次にその関数が呼ばれたときには、前回と同じように
使えるようにしてくれる便利な仕組みです。
なぜクロージャが重要なのか、実際の現場でどんなふうに使えるか
クロージャはJavaScriptにおいて非常に重要であり、外側のスコープにある変数を参照したり、変数のスコープを制限することができます。これにより、データのプライバシー
やセキュリティ
を保護できます。また、メモ化
や高階関数の作成
にも役立ち、パフォーマンスの向上にもつながります。現場では、これらの機能を活用して、保守性の高いコード
を開発するために使用されます。
クロージャの例
サンプルコード
function makeAdd(x) {
return function(y) {
return x + y;
};
}
const addFive = makeAdd(5);
console.log(addFive(2)); // 7
console.log(addFive(7)); // 12
このスクリプトでは、makeAdd関数が引数 x を受け取り、それを加算するクロージャを返します。返された関数は、makeAdd関数が呼び出された際に渡されたxの値を保持し、その後に渡された引数yを加算して返します。
このように、makeAdd関数を呼び出すたびに異なるクロージャが生成され、それぞれが異なるxの値を保持します。したがって、makeAdd(5)で生成されたクロージャは、常に5を加算します。
このように、クロージャは、関数をより柔軟に、より高度な使い方ができるようにするために使用されます。例えば、Reactのコンポーネントの状態管理や、APIコール時の認証トークンの保持など、さまざまな場面で使用されます。
Reactのサンプルコード
import React, { useState } from 'react';
function ButtonMessage() {
const [message, setMessage] = useState('Hello, world!');
const handleClick = () => {
setMessage('Goodbye, world!');
};
return (
{message}
Change message
);
}
APIコール時の認証トークンのサンプルコード
const express = require('express');
const app = express();
const jwt = require('jsonwebtoken');
// 認証トークンを取得するエンドポイント
app.get('/login', (req, res) => {
// ユーザー認証が成功したと仮定して、JWTトークンを生成する
const token = jwt.sign({ userId: '12345' }, 'secret_key', { expiresIn: '1h' });
res.json({ token });
});
// 認証が必要なAPIエンドポイント
app.get('/protected', (req, res) => {
// リクエストヘッダーから認証トークンを取得する
const authHeader = req.headers.authorization;
const token = authHeader && authHeader.split(' ')[1];
// 認証トークンが存在しない場合、エラーレスポンスを返す
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
try {
// 認証トークンを検証する
const decoded = jwt.verify(token, 'secret_key');
const userId = decoded.userId;
// 認証トークンが正しい場合、適切なレスポンスを返す
return res.json({ message: `Hello user ${userId}! This is a protected API.` });
} catch (err) {
// 認証トークンが無効な場合、エラーレスポンスを返す
return res.status(401).json({ error: 'Unauthorized' });
}
});
// サーバーを起動する
app.listen(3000, () => {
console.log('Server started on port 3000');
});