JavaScript | 「thisの仕組み」をアニメーション付きで図解

javascrpit JavaScript
スポンサーリンク

thisの仕組み」は JavaScript 初心者が最初につまずく代表ポイント です。
ここでは、
🧭 直感的なアニメーション(矢印と動き)+図解
🧩 実際にブラウザで動くデモコード(HTML + JS)
の両方で説明します。

thisとは何か?

this は「その関数が“どこから呼ばれたか”によって決まる特別なキーワード」です。

つまり、「関数の中での“呼び出し主” を指すポインタ(矢印)」のようなもの。


図解アニメーションつきデモ

以下のHTMLファイルをコピーしてブラウザで開くと、
this がどのオブジェクトを指すのか」がアニメーションで見えます。


thisの動作アニメーションデモ(HTML + JS)

See the Pen How this works animation by MONO365 -Color your days- (@monoqlo365) on CodePen.

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>this の仕組みアニメーション</title>
<style>
  body {
    font-family: "Segoe UI", sans-serif;
    text-align: center;
    padding: 2rem;
    background: #f8fafc;
  }
  .obj {
    display: inline-block;
    border: 2px solid #4f46e5;
    border-radius: 1rem;
    padding: 1rem 2rem;
    margin: 1rem;
    background: white;
    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
    position: relative;
  }
  .arrow {
    position: absolute;
    top: 50%;
    left: 100%;
    width: 100px;
    height: 2px;
    background: #22c55e;
    transform-origin: left center;
    transition: transform 0.8s ease-in-out;
  }
  #log {
    margin-top: 2rem;
    padding: 1rem;
    background: #eef2ff;
    border-radius: 0.5rem;
    text-align: left;
    white-space: pre-line;
  }
  button {
    background: #4f46e5;
    color: white;
    border: none;
    padding: 0.6rem 1.2rem;
    margin: 0.4rem;
    border-radius: 0.5rem;
    cursor: pointer;
  }
  button:hover {
    background: #3730a3;
  }
</style>
</head>
<body>

<h2>🔍 JavaScript の <code>this</code> は「呼び出し主」への矢印!</h2>

<div class="obj" id="userBox">
  <strong>user オブジェクト</strong><br>
  <code>{ name: "Alice", greet() {...} }</code>
  <div class="arrow" id="arrow"></div>
</div>

<div class="obj" id="globalBox">
  <strong>グローバル(window)</strong>
</div>

<div>
  <button onclick="callUser()">user.greet()</button>
  <button onclick="callAlone()">greet()</button>
</div>

<div id="log"></div>

<script>
const user = {
  name: "Alice",
  greet() {
    log(`user.greet() 呼び出し → this は user`);
    animateArrow("user");
  }
};

function greet() {
  log(`greet() 単独呼び出し → this は undefined(strictモード)`);
  animateArrow("global");
}

function callUser() { user.greet(); }
function callAlone() { greet(); }

function log(text) {
  document.getElementById("log").textContent = text;
}

// 矢印アニメーション
function animateArrow(target) {
  const arrow = document.getElementById("arrow");
  if (target === "user") {
    arrow.style.transform = "rotate(0deg) scaleX(1)";
    arrow.style.background = "#22c55e";
  } else {
    arrow.style.transform = "rotate(45deg) scaleX(1.5)";
    arrow.style.background = "#ef4444";
  }
}
</script>
</body>
</html>
JavaScript

使い方

  1. 上のコードを this-demo.html として保存
  2. ブラウザで開く
  3. 「user.greet()」と「greet()」の2つのボタンをクリック

すると:

  • user.greet() → 矢印が user → this に向く(正しいオブジェクトを指す)
  • greet() → 矢印が グローバル(window) に向く(呼び出し主なし)

補足解説

呼び出し方this が指すもの
メソッドとして呼ぶそのオブジェクトuser.greet()thisuser
単独で呼ぶundefined(strict)または windowgreet()
イベントで呼ぶイベントを発生させた要素<button onclick="...">
call / apply / bind で指定明示的に設定したオブジェクトfunc.call(obj)
アロー関数親スコープの this を引き継ぐ( ) => this.name

よくある混乱例

const user = {
  name: "Alice",
  sayHi() {
    console.log(this.name);
  }
};

setTimeout(user.sayHi, 1000);
JavaScript

❌ 出力:undefined

👉 理由:
setTimeout に渡した時点で「sayHi関数単体」として実行されるため、
thisuser を失ってしまう。

✅ 対策:

setTimeout(user.sayHi.bind(user), 1000);
JavaScript

bind(user) で「この関数の this は必ず user にする」と固定できる。

まとめ(覚え方)

状況this が指すもの
オブジェクト.メソッド()オブジェクト
関数単体()undefined / window
アロー関数外の this を引き継ぐ
イベントハンドラクリックされた要素
bind() / call() / apply()明示的に指定した値
タイトルとURLをコピーしました