C
JavaScript/関数/Lesson 10

this — *JavaScript の謎*

30分·theory
このチャプター
4/4

this — *JavaScript の謎*

🎯 このレッスンを読み終えたら

このレッスンを読み終えると、以下の3つを自信を持ってできるようになります。

  • ✅ 通常の関数の this が呼び出しコンテキストによって変わるルール
  • ✅ アロー関数の this バインディングの違い
  • callapplybind を使うべきタイミング

学習目標をチェックリストとして持ち、すべて答えられるようになったらレッスンを閉じてください。

this は *4つの方法* で決まる

核心を一言で

JS の this は、関数がどのように呼び出されるか によって 4通り に決まります。他の言語と最も 異なる点。一度覚えれば一生もの。

1. デフォルト呼び出し — グローバルまたは undefined

javascript
function fn() {
    console.log(this);
}
fn();   // ブラウザ: window / Node: global / strict mode: undefined

通常の関数呼び出しは 呼び出しコンテキストなし → グローバルオブジェクトまたは undefined。

2. メソッド呼び出し — ドットの前にあるオブジェクト

javascript
const user = {
    name: "ホン・ギルドン",
    greet() {
        console.log(this.name);   // this = user (ドットの前)
    }
};

user.greet(); // "山田太郎" ← user.greet() → this = user

// ⚠️ ポイント: 呼び出し時点のドットの前が this — 同じ関数でも呼び出し方によって異なる!

const fn = user.greet; // 関数だけ変数に取り出す(user から切り離される)

fn(); // undefined ← ドットなしで呼び出し → this = グローバル(または undefined)

// → this.name = グローバルに name がない → undefined

code

同じ関数でも *どのように呼び出すか* によって `this` が異なります。

## 3. new 呼び出し — *新しいインスタンス*

javascript

function User(name) {

// 🆕 new と一緒に呼び出されると、新しい空のオブジェクト { } が this になる

code
this.name = name;        // 新しいオブジェクトに name プロパティを設定
// 自動的に return this; (省略されている)
}

const u = new User("ホン");   // ▶️ 新しいインスタンスを生成
console.log(u);              // User { name: "ホン" }
console.log(u.name);         // "ホン"

new キーワードと一緒に呼び出すと 新しいオブジェクト が生成され、そのオブジェクトが this になります。

4. 明示的バインディング — call・apply・bind

javascript
function greet() {
    console.log(this.name);
}

const user = { name: "ホン" };

// 1️⃣ call — this を指定して即座に呼び出す(引数をそのまま列挙)
greet.call(user);          // "ホン"

// 2️⃣ apply — call と同じだが、引数を配列で渡す
greet.apply(user);         // "ホン"

// 3️⃣ bind — this を「固定」した新しい関数を作って返す(即実行しない)
const bound = greet.bind(user);
bound();                   // "ホン"   ← 後でどこで呼び出しても this = user に固定

// 💡 一言の違い:
//   call/apply  → 即座に実行
//   bind        → 新しい関数を返す(後で実行)

アロー関数 — this を持たない

javascript
const obj = {
    name: "ホン",

    // 通常の関数 — this = obj(ドットの前のオブジェクト)
    method1() {
        return this.name;          // "ホン"
    },
javascript

// アロー関数 — this = 周囲のスコープ(ここではグローバル)

method2: () => this.name, // undefined

};

console.log(obj.method1()); // "ホン" ← 通常の関数: this = obj

console.log(obj.method2()); // undefined ← アロー: this が obj ではない!

code

アロー関数は *自身の this を持たない* — 外側のスコープの `this` を使います。最も一般的な用途:

javascript

class Counter {

constructor() { this.count = 0; }

start() {

setTimeout(() => {

this.count++; // ✅ Counter の this がそのまま使われる

}, 1000);

code
        // もし通常の関数だったら:
        // setTimeout(function() { this.count++ }, 1000);
        // this = window → 動かない
    }
}

React での使い方

jsx
// アロー関数 — this を気にしなくていい
<button onClick={() => this.handleClick()}>...</button>

// またはよりモダンな書き方:
<button onClick={this.handleClick}>...</button>   // クラスメソッドを直接

関数コンポーネント(現代の標準)では this 自体を使わない。Hook が代わりになる。

決定順序(暗記不要、参考まで)

1. new? → 新しいオブジェクト
2. call・apply・bind で明示? → そのオブジェクト
3. obj.method() ドット記法? → そのオブジェクト
4. それ以外 → グローバル / undefined (strict)

まとめ

  • this は 呼び出し方 によって決まる
  • メソッド呼び出し → ドットの前のオブジェクト
  • new 呼び出し → 新しいインスタンス
  • bind・call・apply で明示的に指定可能
  • アロー関数は自身の this を持たない — 最も安全な選択

⚡ 実際に試してみよう — this の4つの呼び出し方

同じ関数でも呼び出し方によって `this` がどう変わるかを一目で確認。
✏️ JS 코드
📟 コンソール出力
▶ 実行ボタンを押してください
⚠️ ブラウザのサンドボックスで実行 — console.log()のみ対応、alert/fetchは不可

🤖 AI にはこう依頼してみよう

このレッスンの概念を理解すれば、AI に 具体的に 指示できるようになります。漠然とした「直して」ではなく、語彙を持ったリクエスト — それがトークン節約の出発点です。

  • 「このコールバックの this バインディング問題をアロー関数または bind で直して」
  • 「このクラスメソッドを明示的な .bind(this) で安定させて」
  • 「このコードで strict mode をオンにしたときの this の動作の違いを教えて」

なぜこれがトークンを減らすのか

概念を知らないと、AI の回答を受け取っても 「それって何ですか?」 とまた聞き直さなければなりません。その「聞き直し」がトークンを消費します。概念を一度覚えておけば、会話が一度で 終わります。

this バインディング — 暗黙的/明示的/アロー関数, call/apply/bind - JavaScript