1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【セキュリティ】JavaScript Class と Prototype:仕組みから理解

1
Posted at

はじめに

JavaScript を本質から理解しようとすると必ずぶつかるのが Class と Prototype
一見すると「クラスベース言語みたいに見える」JavaScript だけど、実際にはまったく別の進化を遂げた プロトタイプベース言語だ。

本記事では、次のポイントを軸に “わかったつもり” を完全に卒業することを目指す。

  1. Prototype(プロトタイプ)とは何か
  2. Prototype Chain の動き
  3. Class 文法の正体(=シンタックスシュガー)
  4. Class 継承(extends)の内部動作
  5. new の内部処理
  6. どんなときに prototype を理解しておくべきか
  7. セキュリティ(Prototype Pollution)とのつながり

1. Prototype(プロトタイプ)とは何か

JavaScript のすべてのオブジェクトは、内部に [[Prototype]] というリンクを持っている。
これは「親オブジェクト」だと考えるとイメージがつきやすい。

プロトタイプの役割

  • オブジェクトが持っていないメソッド・プロパティを探す場所
  • 複数のオブジェクト間でメソッドを共有し、メモリ効率を高める仕組み
  • いわゆる「継承」に相当する機能を実現する土台

const obj = {};
console.log(obj.__proto__ === Object.prototype); // true

obj の親は Object.prototype
このチェーンは必要に応じてどんどん上に伸びる。


2. Prototype Chain(プロトタイプチェーン)

プロトタイプは 1 つのリンクだが、親にもさらに親がいる。
この連鎖を Prototype Chain と呼ぶ。

myObj → Person.prototype → Object.prototype → null

JavaScript のプロパティ探索はこの順で行われる。

  1. 自分自身にある?
  2. なければ prototype を見る
  3. prototype にないなら prototype の prototype を見る
  4. 最後は null に到達して終了

3. Class の正体:Prototype を包んだ「気の利いた皮」

ES6 で Class が導入されたとき、多くの JS 開発者が「ついに JS がクラスベース言語に!」と勘違いした。
しかし実際は、内部は Prototype を使った仕組みのまま。

Class の例

class Person {
  constructor(name) {
    this.name = name;
  }

  sayHi() {
    console.log(`Hi, I'm ${this.name}`);
  }
}

内部ではこう変換されている

function Person(name) {
  this.name = name;
}
Person.prototype.sayHi = function() {
  console.log(`Hi, I'm ${this.name}`);
};

はい、中身はただの prototype 操作
Class は“読みやすくしただけ”というのが真実。


4. Class 継承(extends)の内部動作

class Student extends Person {
  study() {
    console.log("studying...");
  }
}

内部では次のように処理される:

Student.prototype.__proto__ = Person.prototype

つまり prototype chain を接続しているだけ。


5. new キーワードの内部処理

new Person("Anna") を実行すると、実際には 4 ステップの秘密の儀式が行われている。

1. 新しい空オブジェクト {} を作る
2. そのオブジェクトの [[Prototype]] を Person.prototype に設定
3. constructor を呼んで this にプロパティをセット
4. this を返す

コードにすると:

function newLike(constructor, ...args) {
  const obj = Object.create(constructor.prototype); // step 1 & 2
  const result = constructor.apply(obj, args);      // step 3
  return typeof result === "object" ? result : obj; // step 4
}

JavaScript は、この内部動作で「クラス風の挙動」を演出しているだけ。


6. 実務で prototype を理解するべき理由

Class を使っても、問題は prototype レベルで発生する

  • 継承のバグは prototype chain が原因
  • メモリリークの調査で prototype を追う必要がある
  • this のバインド問題(特に React)も prototype と関係する
  • セキュリティの Prototype Pollution は prototype の構造理解が必須

JS を深く理解する人は必ず prototype にたどり着く

React, Vue, Node.js の内部でも prototype は日常的に使われている。


7. セキュリティ:Prototype Pollution とのつながり

Prototype を理解していないと攻撃の危険性も見抜けない。

例:

const payload = {
  "__proto__": {
    admin: true
  }
};
Object.assign({}, payload);

console.log({}.admin); // true

__proto__ を書き換えることで 全オブジェクトの prototype が汚染される(Polluted)
→ 本質を理解していると「なぜこうなるか」が直ちに理解できる。


はじめに

JavaScript を表面ではなく“本体”から理解したいなら、Prototype を避けることはできない。
Class は読みやすさのための糖衣構文だけど、動作はすべて Prototype 上で行われている。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?