Post on 24-May-2015
description
ECMAScript OverviewRika Takahashi / @rika-tagigigigi@gmail.com
この文書について• ECMA-262 5.1 Edition での記載になるべく沿う形
で、 ECMAScript を説明します。• 表記について
▫ 文中のページ数、章番号は、 ECMA-262 5.1 Edition の対応する箇所です。 例 . "1. Scope" (P.1)
▫太字+斜体の語は、仕様上の何らかの特殊な意味を持った単語です。 初回のみ、太字 + 斜体の表記とします。
▫太字の語は、型名やオブジェクト名、予約語を指します。▫ 斜体の語は、 ECMA-262 5.1 Edition で定義される語です。
汎用的な定義のほとんどは 7 章で行われています。 Annex A (P.211) にまとめられています。
Overview
概要• ECMAScript はオブジェクトベースのプログラミング言語
• オブジェクト▫ 0 以上の属性を持つ、プロパティの集合
• 属性▫ 書き込み可能、列挙可能などのプロパティの振る舞いを規定するもの
• プロパティ▫ 他のオブジェクト , プリミティブ値 , 関数の入れ物
• プリミティブ値▫ 以下の組み込み型のいずれかに属するもの。
Undefined, Null, Boolean, Number, String▫ 補記
オブジェクトは、 Object 型に属します。• 関数
▫ 呼び出し可能なオブジェクトの一種( Object 型)▫ オブジェクトのプロパティとして関連付けられている関数をメソッドと呼ぶ
4.2 Language Overview
組み込みオブジェクト▫ global▫ Object▫ Function▫ Array▫ String▫ Boolean▫ Number▫ Math▫ Date
▫ RegExp▫ JSON▫ Error▫ EvalError▫ RangeError▫ ReferenceError▫ SyntaxError▫ TypeError▫ URIError
4.2 Language Overview
ここまでのまとめObject
Object
Undefined
Null
Boolean
Number
String
: 組み込み型
Function
Array
String
Boolean
NumberMath
Date
RegExp
JSON
: 組み込みオブジェクト
global Error
SyntaxError
ReferenceError
EvalError
RangeError
TypeError
URIError
ここまでのまとめObject
Object
Undefined
Null
Boolean
Number
String
: 組み込み型
Function
Array
String
Boolean
NumberMath
Date
RegExp
JSON
: 組み込みオブジェクト
global Error
SyntaxError
ReferenceError
EvalError
RangeError
TypeError
URIError
??
?
• 組み込み型とオブジェクト名の違い▫ 生成
"hoge"; // 組み込み型 String new String("hoge"); //String オブジェクト
▫ typeof 演算子の結果 typeof "hoge"; // "string" typeof new String("hoge"); // "object"
"11.4.3 The typeof Operator" (P.71) を参照 "Type(x)" 関数については、 "8. Type" (P.28) を参照
▫ 厳密な比較演算子の結果 "hoge" === "hoge"; // true new String("hoge") === new String("hoge"); // false
型や値ではなく、インスタンスの同一性を調べるため "11.9.4 The Strict Equals Operator" (P.81) を参照
補足
Why typeof null is object?
•Ecmascript.org▫いろいろ再定義の話をしていた時に Brendan さ
んがでてきて、色々説明していた▫単純に null のポインタを見て object を返してし
まっていたバグ(?)が仕様に。▫Node では typeof null で null を返すオプション
ができた
補足の余談• 以下のオブジェクトを newキーワードで生成することは稀
▫ new String 代替の方法 : 'hoge', "hoge"
▫ new Number 代替の方法 : 0, 100
▫ new Boolean 代替の方法 : true, false
▫ new Array 代替の方法 : []
▫ new Object 代替の方法 : {}
▫ new Function 代替の方法 : functionキーワード
• 前ページの通り、比較などを行う場合に面倒 /ややこしい問題が発生するので、使うならどちらかに統一するべき▫ どちらか片方が良いということはないが、現状、世の中のライブラリはリテラル表記を使っている
ものがほぼ全てなので、リテラル表記に統一する方が良い▫ Google JavaScript Style Guide では、これらのオブジェクトの newは基本的に禁止されている
http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Wrapper_objects_for_primitive_types#Wrapper_objects_for_primitive_types
ラッパーオブジェクトの new?• Premitive に対してメソッド呼び出しをするのは本来お
かしい▫が、やりたいので、やった時にラッパーオブジェクトに一
瞬切り替わって実行される 内部のエンジン的には切り替わっていない
▫Primitive string -> prototype -> Wrapper のメソッド これを使うが、これを入れて置ける場所が無い( primitive
なので)ので、消えてしまう。• プロパティを持てるのはオブジェクトだ、という縛りを
何とか抜け出したかった?• 言語仕様上の一貫性
補足• global オブジェクト ?
▫ スクリプトが実行される前に生成されるオブジェクトで、唯一のもの Web ブラウザーでは、 global オブジェクトの window プロパティが、
global オブジェクトそのものとなる▫ その他のオブジェクトを提供するもの▫ 例
window.Object === Object; // true delete Object; window.Object === Object; // ReferenceError: Object is not
defined new Object(); // ReferenceError: Object is not defined new window.Object(); // ReferenceError: Object is not defined
▫ "15.1 The Global Object" (P.103) を参照
演算子• 単項演算子 : delete, void, typeof, ++, --, +, -, ~, !• 乗算演算子 : *, /, %• 加算演算子 : +, -• ビットシフト演算子 : <<, >>, >>>• 関係演算子 : <, >, <=, >=, instanceof, in• 等価演算子 : ==, !=, ===, !==• バイナリビット演算子 : &, ^, |• バイナリ論理演算子 : &&, ||• 条件演算子 : ? :• 代入演算子 : =, op=• カンマ演算子 : ,
4.2 Language Overview
オブジェクト• ECMAScript では " クラス " を使用しない
▫その代わりに、リテラル記法やコンストラクタを使った様々なオブジェクト生成の方法が提供されている
▫e.g. [] // Array {} // Object
• コンストラクタ▫"prototype" プロパティを持つ関数▫"prototype" プロパティは、プロトタイプベースの継承と共有
プロパティを実装するためのもの• オブジェクトは new キーワードによって生成
▫e.g. new Date(2009, 11);
4.2.1 Objects
prototypeCF コンストラクタ
prototype と P1, P2 というプロパティを持っている
CF コンストラクタのプロトタイプCFP1 というプロパティを持っている
CF コンストラクタから生成されたオブジェクト達
q1, q2 というプロパティを持っている
prototype• この図をコードで書くと以下のとおり
▫var CF = function(){};▫CF.P1 = 1;▫CF.P2 = "hoge";▫CF.prototype = function(){};▫CF.prototype.CFP1 = "foo";▫var cf1 = new CF();▫cf1.q1 = "cf1.q1";▫cf1.q2 = "cf1.q2";▫var cf2 = new CF();▫cf2.q1 = "cf2.q1";▫cf2.q2 = "cf2.q2";
prototype• cf1-5 から P1, P2 にアクセスすることはできない
▫ cf1.P1; // undefined• cf1-5 から CFP1 にアクセスすることはできる
▫ cf1.CFP1; // "foo"▫ cf2.CFP1; // "foo"
• CFp の CFP1 を書き換えると、 cf1-5 からアクセスすると、全ての値が変わったように見える▫ CF.prototype.CFP1 = "bar";▫ cf1.CFP1; // "bar"▫ cf2.CFP1; // "bar"
• cf1 に CFP1 というプロパティを作ると、その値は共有されない▫ cf1.CFP1 = "test";▫ cf1.CFP1; // "test"▫ cf2.CFP1; // "bar"▫ プロトタイプ・チェーンと呼ばれる
プロトタイプを順に遡っていき、見つかったらそれを使う
文法ECMA-262 5.1 Edition P.7
変数宣言•"var" キーワードの後に Identifier を与える
▫VariableStatement : var VariableDeclarationList ;
▫VariableDeclarationList : VariableDeclaration VariableDeclarationList , VariableDeclaration
▫VariableDeclaration : Identifier Initialiseropt
Opt は optional で、あってもなくても良い▫"5.1.6 Grammer Notation" P.9 参照
12.2 Variable Statement
Identifier• Identifier ::
▫ IdentifierName but not ReservedWord • IdentifierName ::
▫ IdentifierStart▫ IdentifierName IdentifierPart
• IdentifierStart :: ▫ UnicodeLetter▫ $▫ _▫ \ UnicodeEscapeSequence
• IdentifierPart :: ▫ IdentifierStart▫ UnicodeCombiningMark▫ UnicodeDigit▫ UnicodeConnectorPunctuation▫ <ZWNJ>▫ <ZWJ>
12.2 Variable Statement
予約語•キーワード、将来の予約
語、 null 、 true 、 false の集合
•ReservedWord :: ▫Keyword▫FutureReservedWord▫NullLiteral▫BooleanLiteral
キーワード• "7.6.1.1 Keywords" (P.18) を参照
• Keyword :: one of▫ break do instanceof typeof ▫ case else new var ▫ catch finally return void ▫ continue for switch while ▫ debugger function this with ▫ default if throw ▫ delete in try
将来の予約語• 非 strict mode の場合、
▫ FutureReservedWord :: one of class enum extends super const export import
• strict mode の場合、▫ FutureReservedWord :: one of
class enum extends super const export import implements let private public yield interface package protected static
変数宣言の処理• VariableStatement : var VariableDeclarationList; の処理
1. VariableDeclarationList を評価します。2. (normal, empty, empty) を返します。
• VariableDeclarationList :VariableDeclarationの処理1. VariableDeclaration を評価します。
• VariableDeclarationList :VariableDeclarationList , VariableDeclaration の処理1. VariableDeclarationList を評価します。2. VariableDeclaration を評価します。
• VariableDeclaration : Identifierの処理1. Identifier と同じ文字シーケンスを含む文字列の値を返します。
• VariableDeclaration : Identifier Initialiser の処理1. Identifier で評価した結果 (11.1.2 に記述 )を lhs とします。 2. Initialiser で評価した結果を rhs とします。3. GetValue(rhs)した結果を valueとします。4. PutValue(lhs, value)を呼び出します。5. Identifier と同じ文字シーケンスを含む文字列の値を返します。
• Initialiser : = AssignmentExpression の処理1. AssignmentExpression を評価した結果を返します。
変数宣言の処理 - 詳細• (normal, empty, empty)
▫ "8.9 The Completion Specification Type" (P.36) を参照• Identifier
▫ "7.6 Identifier Names and Identifiers" (P.17) を参照• Identifier Initialiser
▫ "12.2 Variable Statement" (P.87) を参照 余談 : Initializer ではなく Initialiser らしい…イギリス英語?
フランス語では Initialiser になるらしい▫ http://mymemory.translated.net/s.php?
q=initialiser&sl=Autodetect&tl=en-GB&sj=all
• GetValue▫ "8.7.1 GetValue(V)" (P.35) を参照
• PutValue▫ "8.7.2 PutValue(V, W)" (P.36) を参照
まとめ
まとめ• ECMAScript はオブジェクトベースのプログラミング言語• 組み込み型は 6 種類• 組み込みオブジェクトは 18 種類
▫ うち、 7 つはエラー関連• クラスというものはない
▫ リテラル記法やコンストラクタでの様々な生成方法▫ prototype を使った継承、プロパティの共有を行う
• 変数宣言は var▫ Identifier で定義されている文字列等が使える
• 予約語は Identifier には使えない▫ 予約語は、キーワード、将来の予約語、 null 、 true 、 false
• キーワードは 26個• 将来の予約語は 7個、もしくは 16個
• fff系の文字系を UpperCase すると FFF になり文字数が 3倍になる
• Parse error の octal value, \0• “use strict”; の書かれた部分による処理
▫Directive Prologue の範囲。▫“use strict”; を、最後に書いたら、振り返って「お前ダメ
だったわ」的エラーを出す・・・これは難しい。• Strict code の範囲が明記されていない
▫ 関数が書かれているときに、引数は strict なのか? 関数名は?
▫ 定義関数の方のモードを利用する あとから怒る