このJavaScriptの解説は以下の本の2章と3章を元にしています。
Java開発者のためのAjax実践開発入門 河村嘉之、川尻剛、福沢知海(著) 技術評論社 ISBN978-4-7741-3297-6
JavaScriptはインタプリタ型のスクリプト言語で、1995年に Netscape Communications によって開発され netscape ブラウザに搭載されました。 続いてMicrosoftもよく似たJScriptを開発してInternet Explorerに搭載したのですが、 両者の互換性が低かったことが問題となり、1997年に 国際標準化機関 Ecma International がECMAScript (ECMA 262) として標準化しました。 その後、1999年に発表されたECMAScriptの第3版である ECMA 262-3 に対して、 両者が準拠することを表明したことにより、標準化が完了しました (ただし、過去への互換性のために挙動が異なる部分が残っています)。 その後、2009年に5版が、2011年に5.1版が公開されていますが、現時点(2014年5月)では、 有名どころのブラウザではECMA 262 3版をサポートしているものが多いようです。
JavaScriptは 名前が似ていますがJavaとは全く別の言語です。
クラスという静的な「テンプレート」を用いてインスタンスを生成する。 「クラス」自体は実体が無く、不変である。
クラスも一つのオブジェクトである。 プロトタイプと呼ばれる共通領域に処理を定義した上でインスタンスを生成する。 必要に応じて実行時にクラス自体の内容を書き換えることもできる。
型が厳重に管理されていて、コンパイル時にチェックされた上で最適化されて実行される。
変数に型がない。データには型がある。 変数に格納された値がどう振る舞うかを実行時に決定する。
文の末尾にはセミコロンが必要であるが、省略してもエラーにならない(補って解釈される)。 したがって、次のようにreturn の後で改行すると、意図した通りに解釈されない場合がありえる。
function a() { return 1; } |
function a() { return ; //返り値は undefinedとなる。 1; } |
varがあれば局所変数、無ければ外の変数が見える。
var a = 1; var a = 2; alert(a); // 2 |
var a = 1; var a ; alert(a); // 1 |
値を格納していない変数を参照すると「undefined」という値が返る。 まだ宣言していない変数を参照するとエラーとなる。
var a; alert(a); // 代入せずに参照 --> 「undefined」となる。 alert(aa); // 未宣言の変数を参照 --> 例外が発生する。 |
JavaScriptの変数には型の区別がないが、格納する値には型がある。
EMCAscriptでは次の6種類の型が定義されている。
変数の型によって値の格納のされ方が異なる。
複合型は0個以上のプロパティから構成される型である。 プロパティとは名前と値のペアであり、オブジェクト名にドット(.)をつけることで アクセスができる。
var obj = {}; // 変数objをからオブジェクトで初期化 obj.a = 1; // obj内のaプロパティに1を代入 alert(obj.a); // obj.aの値を参照して表示する。 |
プリミティブ型にはそれぞれに対応するオブジェクト型が wrapper クラスとして存在している。 数値型(number)に関しては、Numberオブジェクトが対応する。 プリミティブ型の値に対してプロパティアクセス演算子を使用すると、対応するwrapper クラスのインスタンスが自動的に生成される。
var a = 3.14; a.a = 1; // (new Number(a)).a = 1; と同じこと alert(a.a); // (alert((new Number(a)).a)) と同じこと --> "undefined" alert((3.14).toExponential()); // alert((new Number(3.14)).toExponential())と同じこと --> "3.14e+0" |
オブジェクト型には2通りの生成方法がある。
var x = new Object(); // new 演算子で生成する x.a = 1; x.b = 2; var y = { // Objectリテラルを用いて生成する a:1, b:2 }; |
配列型の値に対して typeof は "object" を返す。
var x = new Array(); x[0] = 1; x[1] = 2; var y = [1,2]; |
一般のobjectでも、プロパティ名を用いて配列のようにアクセスすることができる。
var obj = { a:1, b:2, c:3 }; console.log( obj['b'] ); |
関数型はデータであると同時に、実行することができる。 関数型はデータであるから、変数やプロパティに自由に格納できる。
関数を生成する方法は3通りある。
var func = new Function('a, b', 'return a + b;'); //「関数オブジェクト」として生成する // 第1引数が仮引数のリスト、第2引数が関数本体 function func(a,b) { // 「関数定義」とよぶ宣言形式 return a + b; }; var func = function (a,b) { // 「関数リテラル」で生成する return a + b; }; alert(func(1,2)); // 実引数を与えて実行する。この場合は3と表示される。 |
スコープ(scope)とは、変数名や関数名といった識別子を特定できる領域を指します。 Javaとは異なり、JavaScriptでは「関数の外側のグローバルスコープ」と 「関数の内側の関数スコープ」の2種類しかない。 つまり、for文やif文のようなブロックレベルのスコープが存在しない。
if (true) { var a = 3; } console.log(a); // 「3」 |
各スコープは、内側から外側に向かって変数を参照できる。 関数スコープからはグローバルスコープで宣言された変数を参照できるが、逆はできない。 また、関数は入れ子で定義できるが、この場合も内側の関数が外側で宣言された 変数を参照できる。
var g = 1; function outer() { var a = 2; function inner() { var b = 3; // 参照できるもの: g, a, b } // 参照できるもの: g, a } // 参照できるもの: g |
JavaScriptの変数は、インタプリタ内部では全て特殊なオブジェクトのプロパティとして 具体化されている。この特殊なオブジェクトを「変数オブジェクト」と呼ぶ。 変数オブジェクトには2種類あり、グローバルスコープに相当するGlobalオブジェクトと、 関数スコープに相当するActiviationオブジェクトがある。 変数オブジェクトのつながりをスコープチェーンと呼び、インタープリタは このスコープチェーンをたどることで指定された変数を探す。
Globalオブジェクトはスクリプトのどこでも参照できるもので、インタープリタの 起動時に1つだけ生成される。
var a = 1; function b() {}; console.log(window.a); // 「1」 |
手書きの説明 |
Activiationオブジェクトは、関数を実行するたびに生成されるオブジェクトで、 関数内部の変数をプロパティとして具体化する。
function test(a,b) { var c = a; function d() {} } test(1,2); |
手書きの説明 |
関数は内部に[[Scope]]という特殊なプロパティを持ち、ここに変数オブジェクトのリストが格納される。 これがスコープチェーンであり、変数の検索時はこのリストを末尾から先頭に順にたどって プロパティを探していく。 スコープチェーンに同名のものが見つからなかった場合は次の動作を行う。
[[Scope]]は関数が生成されたときに初期化されて、そのときのスコープチェーンの 内容を引き継ぐ。関数が定義された時とは、関数定義の場合はGlobalオブジェクトや Activationオブジェクトの初期化時で、関数リテラルの場合はその式が評価された時である。 該当する関数を実行する際に、Activationオブジェクトを新たに作成して、 リストの末尾に追加する。
(例) var a = 1; function test() { var b = 2; } test(); | |
手書きの説明 |
(例) var a = 1; funciton test1() { var b = 2; test2(); } function test2() { var c = 3; } test1(); |
手書きの説明 |
(例) function outer() { var a = 0; return function() { console.log(a++); } } var test1 = outer(); test1(); // 「0」 test1(); // 「1」 var test2 = outer(); test2(); // 「0」 |
手書きの説明 |
Chrome を起動して http://nw.tsuda.ac.jp/class/cg/javascript/ex2-50.html にアクセスせよ。画面の上のメニューから「その他のツール」-->「デベロッパーツール」-->「Console」を選択し、Chromeの画面の右半分にJavaScriptコンソールを表示し、 コンソールへの出力(ロギング)を確認すること。
ex2-50.html |
|