「関数」 をテーマに、基礎 / 中級 / 上級(応用) 各レベル 5 問ずつ、合計 15 問のオリジナル練習問題+解答+解説を作成しました。コードはそのままブラウザのコンソールで実行できます。
基礎レベル(5問)
問題1
次の関数を呼び出したときの出力は何ですか?
function greet() {
console.log("Hello!");
}
greet();
JavaScript解答
Hello!
解説
関数 greet を定義してから greet() を呼んでいるので関数内の console.log が実行される。
問題2
次の関数は何を返しますか?
function add(a, b) {
return a + b;
}
console.log(add(3, 4));
JavaScript解答
7
解説add(3,4) は 3 + 4 = 7 を返し、それを console.log で表示している。
問題3
無名関数(関数式)を使った呼び出しの例と出力を示しなさい。
const f = function() { return 10; };
console.log(f());
JavaScript解答
10
解説
関数を変数 f に代入している(関数式)。f() で呼び出すと 10 が返る。
問題4
アロー関数を使って x * 2 を返す関数を書き、console.log で呼び出してください。
const double = x => x * 2;
console.log(double(6));
JavaScript解答
12
解説
引数が1つで関数本体が式1つのとき、アロー関数は省略形で書ける。6 × 2 = 12。
問題5
デフォルト引数の動作を示すコードと出力を書きなさい。
function say(name = "Guest") {
console.log("Hi, " + name);
}
say(); // 呼び出し1
say("Alice"); // 呼び出し2
JavaScript解答
Hi, Guest
Hi, Alice
解説
引数が省略された場合 name は "Guest" になる。指定があればその値が使われる。
中級レベル(5問)
問題1(可変長引数)
...rest(restパラメータ)を使って任意個の数の合計を返す関数を書き、console.log(sum(1,2,3,4)); の出力を示しなさい。
function sum(...nums) {
return nums.reduce((a, b) => a + b, 0);
}
console.log(sum(1,2,3,4));
JavaScript解答
10
解説...nums は渡された引数を配列にする。reduce で全てを足し合わせる。1+2+3+4 = 10。
問題2(arguments と rest の違い)
次のコードの出力は何か。arguments と rest の挙動の違いに注目。
function f() {
console.log(arguments.length);
}
f(1,2,3);
JavaScript解答
3
解説arguments は関数に渡された全引数を疑似配列(配列ではない)で参照できる。長さは 3。
問題3(コールバック)
配列 nums = [1,2,3] に対してコールバックを使って各要素を2倍して出力するコードを書き、その出力を示しなさい(forEach を使う)。
const nums = [1,2,3];
nums.forEach(n => console.log(n * 2));
JavaScript解答
2
4
6
解説forEach に渡したコールバックが配列の各要素に対して順番に呼ばれ、console.log(n*2) が実行される。
問題4(クロージャ基礎)
次のコードの出力は何か。クロージャの基本を示している。
function makeCounter() {
let count = 0;
return function() {
count++;
console.log(count);
}
}
const c = makeCounter();
c();
c();
JavaScript解答
1
2
解説
戻された無名関数は count 変数を覚えている(クロージャ)。呼び出すたびに count が増える。
問題5(即時実行関数 IIFE)
IIFE(即時実行関数式)の例とその用途を簡単に示し、次のコードの出力を答えよ。
(function() {
const x = 99;
console.log(x);
})();
JavaScript解答
99
解説
関数を定義して即座に呼び出すパターン。スコープを隔離したいときに使う(グローバル変数汚染を防ぐ)。
上級/応用レベル(5問)
問題1(高階関数:関数を返す)
関数 makeAdder を作り、const add5 = makeAdder(5); console.log(add5(10)); の出力が 15 になるようにしなさい。
function makeAdder(x) {
return function(y) {
return x + y;
};
}
const add5 = makeAdder(5);
console.log(add5(10));
JavaScript解答
15
解説makeAdder は「引数 x を覚えた関数」を返す高階関数。add5(10) は 5 + 10 = 15。
問題2(カリー化の簡単な例)
次の multiply をカリー化して multiply(2)(3) が 6 を返すようにしなさい。
const multiply = a => b => a * b;
console.log(multiply(2)(3));
JavaScript解答
6
解説
アロー関数で 1 引数ずつ取る関数を返すことでカリー化を実現している。
問題3(メモ化:性能改善)
単純な再帰フィボナッチ(遅い実装)とメモ化版の違いを示し、memoFib(10) の出力値を答えよ。
// メモ化版
function memoFib() {
const cache = {};
return function fib(n) {
if (n <= 1) return n;
if (cache[n]) return cache[n];
cache[n] = fib(n-1) + fib(n-2);
return cache[n];
}
}
const fib = memoFib();
console.log(fib(10));
JavaScript解答
55
解説(簡潔)
フィボナッチ数列の 10 番目(0始まりで数えると F(10) = 55)。メモ化により同じ計算の繰り返しを避け高速化している。
(注:F(0)=0, F(1)=1 とした標準定義を使用)
問題4(this の扱いと bind)
次のコードの出力を答え、this を正しくするための方法を示せ。
const obj = {
name: "Z",
greet() { console.log(this.name); }
};
const f = obj.greet;
f(); // A
const g = obj.greet.bind(obj);
g(); // B
JavaScript解答
A: undefined(または実行環境によっては空文字やグローバル値)
B: Z
解説
メソッドを変数に代入して呼ぶと this が切れる(非メソッド呼び出しになる)。bind(obj) で this を固定すると期待どおり Z が出力される。
問題5(純粋関数 vs 副作用)
次の 2 つの関数の振る舞いを説明し、どちらが「純粋関数(pure)」か答えなさい。
let total = 0;
function impureAdd(x) {
total += x; // 外部状態を変更する
return total;
}
function pureAdd(a, b) {
return a + b;
}
JavaScript解答pureAdd が純粋関数。impureAdd は副作用を持つ(外部変数 total を変更する)ため純粋ではない。
解説
純粋関数は同じ入力で常に同じ出力を返し、外部状態を変更しない。副作用があるとテストや並列化が難しくなる。

