20140929 ecmascript
TRANSCRIPT
ECMA262-Edition5.1読書会第10条 実行可能コードと実行コンテキスト
2014/09/29ワークスアプリケーションズ
エンジニア藤澤勇樹
10.1 実行可能コードの種類 実行可能コードとは? 実行可能コードの種類は?
実行可能コードとは? 文字通り、Javascripにおいて実行する
ことができるテキストのこと
実行可能コードの種類は?
globalコード evalコード functionコード
・ECMAScriptのProgramとして扱われるソーステキスト
・FunctionBodyのソーステキ
ストは含まない
・eval関数に指定さ
れたソーステキスト
・globalコードとし
て認識される
・FunctionalBodyの一部として解析されたソーステキストのこと
・コンストラクタである組み込み
Functionオブジェクトを使った場
合のソーステキストを意味する
・globalコード、evalコード、functionコードの3種類
10.2 レキシカル環境 レキシカル環境とは? Environment Recordとは? 新しいレキシカル環境が作成されるタ
イミングは?
レキシカル環境とは?Environment Recordとは? レキシカル環境は以下から構成される
Environment Record nullである可能性のある外側のレキシカル
環境
Environment Recordとは、 それぞれの レキシカル環境のスコープで 識別子のバインディングを記録するための オブジェクトである
レキシカル環境のスコープ(静的スコープ)
A { var x; }
B { var x; // A内のxとは別物 C { var y; // Cの内側からしか
見えない } }
レキシカル環境のスコープ⇒静的スコープfunction A() {
var x = "A"; // 他の関数からはアクセスできない return x;
}
function B() {
var x = "B"; // 関数Aの変数xとは別もの function C() {
var y = "C";
return x + y; // 関数Bの変数xにアクセスできる }
return C();
}
alert(A()); // >>A
alert(B()); // >>BC
動的スコープvar x = 123
A { var x = 456 call C // 456と出力される}
B { call C // 123と出力される}
C { print x // 呼び出し元によって x の値が変わる}
静的スコープではない⇒動的スコープ
新しいレキシカル環境が作成されるタイミングは?
FunctinDeclatation, WithStatement, TryStatementのcatch節といったコードが評価される度に作成される
第12, 13で定義される構文が評価される度 FunctinDeclatation:第13条 WithStatement:12.10 TryStatement:12.14
10.2.1 Environment Record詳細 Environment Recordとは、
それぞれの レキシカル環境のスコープで識別子のバインディングを記録するためのオブジェクトである
Environment Record:抽象クラス 実装クラス1:宣言的Environmnt Record 実装クラス2:オブジェクトEnvironment
Record
宣言的Environmnt Record・FunctinDeclatation:第13条・TryStatement:12.14で定義される変数, function, 引数などで
利用される
例:FunctinDeclatation"a", "b", "c"の全てが宣言的Environmnt Recordに関連づけられる
function foo(a) { var b = 10; function c() {}}
例:TryStatementtry { ...} catch (e) { // "e" が宣言的Environment
Recordにバインディングされる ...}
オブジェクトEnvironment Record
グローバルオブジェクトとWithStatementにて使用される
インターネットブラウザの場合は、"window"がグローバルオブジェクトとなる
例:グローバルオブジェクト(this, window)var a = 10;console.log(a); // 10 // "this" in the global context//is the global object itselfconsole.log(this.a); // 10 // "window" is the reference to the// global object in the browser environmentconsole.log(window.a); // 10
例:WithStatement
var foo;var baz;with (document) { //document.を省略できる foo = getElementById('foo'); baz = getElementsById('baz');}
例:WithStatement
var a = 10;var b = 20; with ({a: 30}) { console.log(a + b); // 50} console.log(a + b); // 30, restored
10.3 実行コンテキスト
global実行コンテキスト
実行コンテキスト
実行中の実行コンテキスト
実行コンテキストはスタックを形成している
実行終了実行コンテキストの生成
10.3 実行コンテキスト
LexicalEnvironment VariableEnvironment ThisBinding
実行コンテキストないに内のコードによって作成された識別子リファレンスを解決するめに使用されたレキシカル環境を識別する
・実行コンテキスト内にあるVariableStatementsと
FunctionDeclarationsによって生成されたBinding
を保持するEnvironment
Recordであるレキシカル
環境を識別する
・この実行コンテキストと関連づくECMAScriptコード内にあるthisキーワードに関連づけられた値
実行コンテキストの構成要素
10.4 実行コンテキストの作成・実行可能コードを評価する度に作成さ
れて、その実行コンテキストに入る・制御が実行コンテキストに入る場合、
当該実行コンテキストのThisBindingが設定され、そのVariableEnvironmentと初期のLexicalEnvironmentが定義され、宣言的バインディングインスタンス化が実行される
10.1-10.4のまとめvar a = 10;
function foo() {
var b = 20;
console.log(a);
}
with ({a: 20}) {
var bar = function () {
console.log(a);
};
foo();
bar();
}
10.1-10.4のまとめ//global実行コンテキストの初期化globalContext = {
thisBinding: globalオブジェクト, //ブラウザであればwindow
variableEnvironment:{
宣言的EnvironmentRecord:{}
scope:globalEnv
outer : null
},
lexicalEnvironment:{
宣言的EnvironmentRecord:{}
scope:globalEnv
outer : null
}
}
10.1-10.4のまとめvar a = 10;
----------------------------------------
//バインディングオブジェクト a の作成globalContext.variableEnvironment = {
宣言的EnvironmentRecord: {a: 10}
};
10.1-10.4のまとめfunction foo() {
var b = 20;
console.log(a);
}
----------------------------------------
//何もしない。実行時に評価される
10.1-10.4のまとめwith ({a: 20}) {
----------------------------------------
//global実行コンテキストのlexicalEnvironmentを退避previousEnvironment = globalContext.lexicalEnvironment;
//新規lexicalEnvironmentの作成(レキシカル環境識別のため) globalContext.lexicalEnvironment = {
オブジェクトEnvironmentRecord: {a: 20},
outer: globalContext.lexicalEnvironment
};
10.1-10.4のまとめvar bar = function () {
console.log(a);
}
----------------------------------------
//何もしない。実行時に評価される
10.1-10.4のまとめfoo() //10が出力される----------------------------------------
//foo Functionは、VariableEnvrionmentで定義されている点に注意//新規実行コンテキストの作成と実行fooContext = {
thisBinding: globalオブジェクト,
variableEnvironment:{
宣言的EnvironmentRecord:{a:10 , b:20}
scope:globalEnv
outer : null
}
}
10.1-10.4のまとめbar() //20が出力される----------------------------------------
//bar() Functionは、LexicalEnvrionmentで定義されている点に注意//functionExpressions
//新規実行コンテキストの作成と実行barContext = {
thisBinding: globalオブジェクト,
lexicalEnvironment:{
オブジェクトEnvironmentRecord:{a:20}
outer : globalEnv
}
}
10.1-10.4のまとめ//withが終了すると、退避した環境をグローバルコンテキストに戻すglobalContext.lexicalEnvironment = previousEnvironment;