2
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エンジニアリングの実践史 第2回「JavaScriptの設計思想を語る - SchemeとSelfの系譜」

Last updated at Posted at 2025-12-11

はじめに

グロースエクスパートナーズ株式会社の中村です。
この記事は グロースエクスパートナーズ Advent Calendar 2025 の12日目です。

アドベントカレンダー特別企画として、古くからJavaScriptに携わってきたテクニカルフェロー北條さんとの座談会を、第1回に続く第2回としてお届けします。

JavaScript誕生エピソードと言語設計

10日で作られた言語

👤 司会:
北條さんは今では「JavaScriptC++の次に大好きな言語だ」と仰っていますが、最初に触った当時は「うわ、またどうしようもないスクリプト言語が出てきたな」と思われたとか。JavaScriptって元々、Brendan Eichさんが10日で作り上げたんですよね。

💡 北條:
はい、言語自体は。だからもう手抜きの極みですよ。
Brendan Eichさんは Scheme っていう LISP 系の言語をやる人で、いわゆるゴリゴリの Schemer ですね。Netscape社にはブラウザにSchemeを乗っける仕事があるから来いよって言われて、喜び勇んでやってきたんですね。Schemeをブラウザに乗っけられるってウキウキして入社したんですけど、しばらく放置プレイが続いた後で、突然「ALGOL系の言語の見た目のスクリプト言語を載せてくれ」って言われて。ALGOL系っていうのはC言語とかJavaとかですけども、S式愛に溢れるゴリゴリのSchemerにとっては大変大きな侮辱になるんです。そういう見た目の言語を作ってくれって言われて、相当頭にきたみたいなんです。頭にきてやっつけ仕事で、やっつけ仕事だから10日でやった。
あの当時は、そういうグチを伝聞で書いたブログとかが結構あったんだけど、Brendan Eichさん、MozillaのCEOになったじゃないですか。その頃からそういう記事がだんだん目立たなくされて、すごく前向きに「JavaScriptエンジンを作ったんだぜ」っていう話も出たりして、ちょっとおいおいと思ったりして。

時刻処理のところは、JavaJava.util.Dateかなんかの丸コピーで入っていて、まあやる気ないなこいつっていうのは思いました。当時のPrototype.jsの時代は、まずプロジェクトで使うユーティリティを先に開発しておいてやるので、標準APIがクソであれば、まあそこは使わないで済むようにしてからやるので問題ないんですけど。まあ、手抜きが満点なところですよね。

Brendan Eich (ブレンダン・アイク)
JavaScriptの生みの親。1995年にNetscape社で10日間でJavaScriptの最初のプロトタイプを開発。その後MozillaでCTOを務め、Mozilla FirefoxブラウザとJavaScriptエンジン(SpiderMonkey)の開発に関わる。現在はプライバシー重視のWebブラウザ「Brave」のCEO。

なお、入社から開発までの経緯については、本人のインタビューによれば以下とされています。

  • Netscape社にはブラウザ向けのスクリプト言語を開発するために採用された。
  • 最初から「Javaに似たスクリプト言語にしたい」と言われた。
  • 怒りでやっつけたのではなく、急ぎの仕事だっただけ(1995年5月に入社し、数週間後に10日でプロト開発。9月にはβ版がリリースされ、翌96年3月には正式リリース)

Schemeの影響: レキシカルスコープ

👤 司会:
JavaScriptが出てきた時、結構Schemeに似ているなみたいなのは感じたんですか?

💡 北條:
そうですね。だからBrendan Eichさんのエピソードを知ったとき、すごく納得したんですよ。
私は最初JavaScriptが出てきたとき、「うわ、またどうしようもないクソスクリプト言語が出てきたな」と思って見ていたんですけど、まあでも仕事で書かざるを得なくて書いていると、まあ意外と光るところがあって。なので、こんなに手抜きクソ言語なのに、なぜこう光るものがあるんだろう?と思って、JavaScriptはどう作られたのかっていうのを調べたんです。

👤 司会:
自分が軽く調べた感じだと、JavaScriptSchemeって結構似ているみたいですね。

💡 北條:
座談会トークテーマの中に「レキシカルスコープ」と書いてありますが、これはとても重要な概念です。
現在主流の言語のほとんどはレキシカルスコープを採用していて、逆に動的スコープだけを使う言語はかなり少数派になっています。

たとえばJavaラムダ式が書けるようになりましたが、あれも完全にレキシカルスコープです。そういう意味で、いま「まともな関数を扱える言語」は、ほぼ全部レキシカルスコープだと言っていいと思います。
当時はいろいろな設計の選択肢がある中で、この言語はSchemeと同じスタイル、つまりレキシカルスコープを採用する方向で設計されていました。

レキシカルスコープとは?
関数の中から外側の変数を参照するとき、「関数が書かれた場所」で変数を探すルール。これのおかげでクロージャ(外側の変数を覚えている関数)が自然に使えます。

逆の動的スコープだと「関数が呼ばれた場所」で変数を探すので、トリッキーなテクニックが使える代わりに非常に予測しづらいコードになりがち。ちなみにJavaScriptfunctionthisは動的スコープっぽく(違うけど)動作するのでちょっと癖がありますね。アロー演算子で完全なレキシカルスコープのラムダ式が書けるようになったのは自然な流れです。

Selfの影響: プロトタイプベース

👤 司会:
Scheme以外だと、SelfJavaScriptと似ていると言われるようですね。クラス定義が前提ではなくて、プロトタイプベースでオブジェクトを作って、あとから柔軟にプロパティを追加したりできるところですよね。

💡 北條:
そうです。SelfJavaScriptも、基本的なオブジェクトモデルがプロトタイプベースなんですよね。お仕着せのクラスを中心に継承関係を定義するのではなく、「既存のオブジェクトを元に新しいオブジェクトを作る」仕組みになっていて、クラスモデルもオブジェクト同様に非常に柔軟にクラスモデル(メタクラスとも言われる)を自在に扱えるようになっている。Smalltalkの思想を引き継ぎつつ、より柔軟なモデルを目指した言語の系譜に位置しています。

プロトタイプベースとは?
C++Javaのようなクラスベース言語では、まずクラスを定義してからオブジェクトを作ります。一方、プロトタイプベースでは既存のオブジェクトを雛形にして新しいオブジェクトを作り、必要なプロパティは後から追加できます。JavaScriptclass構文は後から追加された糖衣構文で、内部は今もプロトタイプベースです。

静的ディスパッチと動的ディスパッチ

💡 北條:
で、このあたり、当時のオブジェクト指向言語というのは、スタティックディスパッチダイナミックディスパッチをどう扱うかが大きな特徴だったんですよね。C++で言えば、普通のメソッド呼び出しはコンパイル時に解決される「静的ディスパッチ」。一方、virtualを付けた関数は実行時に呼び出し先が決まる「動的ディスパッチ」で、仮想関数テーブル(vtable)というメソッド一覧みたいなのをスキャンして、「あ、これだね」って言って、ジャンプするんです。
この「名前をもとに一覧をたどって、該当するメソッドにジャンプする」という仕組みは最近では完全に一般的になっています。一方で、最近の言語でも動作効率の向上などのために静的ディスパッチ相当の機能があったりするので、そういう機能の有無をみるとちょっと面白かったりします。

補足:
プロトタイプベースの核心は「動的メソッド探索」であるため、JavaScriptプロトタイプベースのメソッド決定は、C++でいうvirtual関数の動的ディスパッチに近いということ

クラスベースの多様性

💡 北條:
Smalltalkでは「メタクラス」と呼ばれる仕組みがあって、クラスそのものがどういう構造を取るかが厳密に定義されている。いわば、クラスの仕組みが"カチッと"固定されているんですね。一方で、SelfCommon Lisp(CLOS)など、Lisp系のOOPシステムというのは、もっと"必要なパーツだけ揃えておくので、あとはあなたがどう組み立ててもいい"というスタイル。クラス階層をどう構築するか、オブジェクトの振る舞いをどう設計するかを、かなり自由に実装できるようになっているんです。こんな風に色々な言語がメタクラスの変更をどの程度どのように受け入れるのか調べてみても面白いと思います。Rubyとか積極的で、「メタプログラミングRuby」という本が出てるくらい。

それから、Schemeと並んで有名なLispとしてCommon Lispがあります。名前のとおり、Lispを標準化しようという流れの中で作られた言語で、実務でLispを使うならCommon Lisp以外考えられないっていうLISPerの皆さんが仰るやつです。Common LispにはCLOS(Common Lisp Object System)という強力なオブジェクトシステムがあって、クラスベースでありつつ、多重ディスパッチメソッドコンビネーションなど、かなり柔軟な機能を備えています。
Selfのようなプロトタイプベースの言語とは実装スタイルは違いますが、「従来の単純なクラスベースOOPではなく、もっと柔軟なオブジェクトモデルを追求したい」という問題意識という意味では、CLOSもまた別の方向から同じ課題にアプローチした存在と言えます。
Selfのようなプロトタイプベース言語とは思想が違うものの、「固定的なクラスモデルに縛られない、もっと表現力豊かなOOPを実現したい」というモチベーションの観点では、同じ問題に別方向からアプローチした仲間、と捉えることもできます。JavaScriptSelfの影響を受けたプロトタイプモデルを採用しているので、クラスベースメタクラス構造は存在していません(今のclass構文は後から追加された見た目上の糖衣です)。

OOP設計の多様性
オブジェクト指向言語は、それぞれ異なるアプローチでオブジェクトモデルを模索していました:

  • Smalltalk: 厳密なメタクラス構造
  • Self: クラスレスなプロトタイプベース
  • CLOS: 柔軟な多重ディスパッチ
  • C++: 静的型付けと仮想関数

JavaScriptSelfの流れを汲みつつ、Schemeレキシカルスコープを組み合わせた、ハイブリッドな設計になっています。

JavaScriptのclass構文
ES2015(ES6)で追加されたclassキーワードは、内部的には従来のプロトタイプベースの仕組みを使った「糖衣構文(syntax sugar)」です。classと書いても、実際にはプロトタイプチェーンでオブジェクトが繋がっており、C++Javaクラスベースとは根本的に異なります。
PythonRubyにあるようなClassのClass(=メタクラス)は、JavaScriptには存在しません。


📅 JavaScript技術年表 — 本記事で登場した技術たち

※ 本年表はインタビュー内容の理解を助けるための参考情報です。詳細な歴史については公式ドキュメントや一次資料をご参照ください。

本記事で北條さんが言及した技術について、歴史的な背景をまとめました。


LISP

項目 内容
登場年 1958年
開発者 John McCarthy (MIT)
思想背景(何のために作られた技術なのか) AI研究を目的に、人間の推論を想定した記号処理を実現するためにコードとデータを同じ構造(S式)で扱う数学的にシンプルなモデルを実現。
解決した課題 記号処理に適したリスト構造と再帰的な計算モデルを体系化し、当時の主流言語では扱いにくかった柔軟なデータ構造操作を可能にした。
現在の位置づけ 歴史的に重要なプログラミング言語であり、Lisp系言語(Common Lisp、Schemeなど)が研究・教育・特定の実用分野で継続して用いられている。
影響を与えたもの SchemeやCommon Lispをはじめ、Ruby、Python、JavaScript など多くの動的・関数型・スクリプト言語。

Smalltalk

項目 内容
登場年 1972年(Smalltalk-72)/ 1980年(Smalltalk-80)
開発者 Alan Kay、Dan Ingalls、Adele Goldberg(Xerox PARC)
思想背景(何のために作られた技術なのか) 教育を目的に、人間の思考を拡張する道具として、実世界を模した物体を模したオブジェクト指向(メッセージパッシング)を実現
解決した課題 モダンOOPの基盤となるモデルを確立し、動的開発環境を実現
現在の位置づけ OOPの発展に大きく貢献した歴史的言語
影響を与えたもの Java、Ruby、Objective-C、Selfなどのプログラミング言語、そしてGUI設計全般

「すべてがオブジェクト」の原点

北條さんが言及する「メタクラス」の概念を持つSmalltalkは、「クラス自体もオブジェクトである」という徹底したOOP設計を実現しました。数値も文字列も、クラスさえもオブジェクトとしてメッセージを送れる世界観は、後の多くののOOP言語に影響を与えています。


Scheme

項目 内容
登場年 1975年
開発者 Guy L. Steele Jr. & Gerald Jay Sussman(MIT)
思想背景(何のために作られた技術なのか) 言語設計の研究を目的に、LISPを再構成し、数学的関数モデル(レキシカルスコープ・クロージャ)と制御構造の研究(継続)を実現
解決した課題 レキシカルスコープの確立、末尾再帰最適化の保証
現在の位置づけ 一般普及は大きくないが、言語設計・プログラミング教育で重要な位置を占め続けている。MITの伝説的教科書「SICP (計算機プログラムの構造と解釈)」で有名
影響を与えたもの JavaScript、Ruby、Python、Haskellなど多くの言語のスコープ設計

JavaScriptに流れるSchemeのDNA

北條さんが「ゴリゴリのSchemer」と表現するBrendan Eich。彼がJavaScriptに持ち込んだSchemeの遺産は:

  • レキシカルスコープ: 関数が定義された場所で変数を解決
  • 第一級関数: 関数を値として扱い、変数に代入・引数に渡せる
  • クロージャ: 外側のスコープを「覚えている」関数

これらはすべてScheme由来であり、現代JavaScriptの根幹を成しています。


Common Lisp / CLOS (Common Lisp Object System)

項目 内容
登場年 1984年(Common Lisp)/ CLOSは1980年代後半に誕生、1994年にCommon Lisp標準へ
開発者 X3J13委員会(Common Lisp)
思想背景(何のために作られた技術なのか) 研究・産業利用の大規模化に対応するため、方言の統一(標準化)、柔軟かつ強力なOOP(CLOS)、そしてメタレベルでも拡張可能な仕組み(MOP)を実現
解決した課題 多重ディスパッチやメソッドコンビネーションにより、クラス中心のOOPが抱えていた柔軟性不足を解消した。
現在の位置づけ 現在でも研究や商用で一定の需要がある。SBCL(Common Lispコンパイラ)は2025年現在でも活発に開発が続いている。
影響を与えたもの Dylan や Julia の多重ディスパッチに強い影響を与えた。)

「固定的でないOOP」のもう一つの解答

北條さんが「別方向から同じ課題にアプローチした存在」と表現するCLOS。Selfがクラスを「なくす」方向で柔軟性を追求したのに対し、CLOSはクラスを「より強力にする」方向で柔軟性を実現しました。引数の型の組み合わせでメソッドを選ぶ「多重ディスパッチ」は、通常のOOPにはない強力な表現力を提供します。


Self

項目 内容
登場年 1987年
開発者 David Ungar & Randall B. Smith(Sun Microsystems / Stanford)
思想背景(何のために作られた技術なのか) OOPの研究を目的に、人間の認知モデルに基づきクラスを廃し、プロタイプベースでのOOPを実現
解決した課題 クラス階層の事前設計の困難さと硬直化(脆弱な基底クラス問題)の回避
現在の位置づけ 研究言語としての役目を終えたが、その思想はJavaScriptに継承
影響を与えたもの JavaScript、NewtonScript、Lua、Ioなど

プロトタイプベースの源流

北條さんが説明する「既存のオブジェクトを元に新しいオブジェクトを作る」仕組みは、Selfで確立されました。クラスという「設計図」を先に定義する必要がなく、オブジェクトを直接コピー・拡張できる柔軟性が特徴です。JavaScriptのObject.create()__proto__は、このSelfの思想を直接受け継いでいます。


Java

項目 内容
登場年 1995年
開発者・組織 James Gosling(Sun Microsystems)
思想背景(何のために作られた技術なのか) 企業システムや組み込みを目的に、C++の危険性を廃し、移植性(JVM)と大規模開発性を実現
解決した課題 プラットフォーム非依存(Write Once, Run Anywhere)
現在の位置づけ エンタープライズ開発の定番。Androidアプリ開発でも使用
影響を与えたもの JavaScriptの構文(見た目のみ)、C#、Kotlin

名前だけ借りた関係

JavaScriptとJavaは、名前が似ているだけでまったく別の言語です。当時のNetscapeがSun Microsystemsと提携し、マーケティング上の理由で「JavaScript」と命名されました。


JavaScript

項目 内容
登場年 1995年9月(Netscape Navigator 2.0 β版)
開発者 Brendan Eich(Netscape Communications)
思想背景(何のために作られた技術なのか) ブラウザで動かすこと目的に、Java人気に合わせて構文を寄せつつ、柔軟で動的な言語を実現
解決した課題 HTMLだけでは実現できない動的なWebページの実現
現在の位置づけ フロントエンド・バックエンド・モバイルまで、あらゆる領域で使われる言語
影響を受けたもの Scheme(レキシカルスコープ)、Self(プロトタイプベース)、Java(構文の見た目)

「10日で作られた言語」

北條さんが語るように、Brendan EichはSchemeをブラウザに載せるつもりでNetscapeに入社しました。しかし「Javaに似た見た目のスクリプト言語を」という要求を受け、10日間でプロトタイプを開発。SchemeのレキシカルスコープとSelfのプロトタイプベースを組み合わせつつ、見た目はJava風という、ユニークなハイブリッド言語が誕生しました。


年表サマリー

1958年 ─ LISP開発開始(John McCarthy、MIT)
    │      └ 多くの関数型言語・動的言語に影響を与えた
    │
1972年 ─ Smalltalk-72(Alan Kay、Xerox PARC)
    │      └ OOPの基盤を形成
    │
1975年 ─ Scheme誕生(MIT)
    │      └ レキシカルスコープの採用
    │
1980年 ─ Smalltalk-80 公開
    │      └ メタクラス、GUIに大きく貢献
    │
1984年 ─ Common Lisp標準化
    │
1986-87年 ─ Self設計・開発(Xerox PARC / Stanford)
    │      └ プロトタイプベースOOPを推進
    │
1980年代後半 ─ CLOS開発(1994年にANSI標準へ統合)
    │      └ 多重ディスパッチ、メソッドコンビネーション
    │
1995年 ─ JavaScript誕生 & Java登場
    │      └ SchemeとSelfの影響を受けつつ、Javaに似た構文を採用
    │
2015年 ─ ES6(ES2015)標準化
    │      └ class構文追加(内部はプロトタイプベースのまま)
    │
現在 ─── JavaScriptは広く使われる言語の一つに

⚠️ 免責事項

本記事は、社内イベントを基に作成したものです。以下の点にご留意ください:

  • 記事内容は対談者個人の経験と見解に基づいており、所属組織の公式見解ではありません
  • 技術的な情報については正確性の確保に努めておりますが、記憶に基づく内容も含まれるため、情報の正確性・完全性を保証するものではありません
  • JavaScriptや関連技術は日々進化しており、記事執筆時点での情報となります
  • 本記事の情報を利用して生じた損害について、執筆者および所属組織は一切の責任を負いかねます
  • 正確な情報が必要な場合は、公式ドキュメントや一次情報源をご確認ください
2
0
0

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
2
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?