はじめてしりました。
// Firebug出力のショートカット
function p(x){console.log(x)}
// evalの基本を確認
var context = {a : 50}; // evalのコンテキストオブジェクト
p(context.eval("a")) // 50 contextの上で評価
p(eval("a", context)) // 50 入れ替えても同じ
// カウンタクロージャーを生成する関数
function counter(){
var num = 0;
return function(){
return ++num;
}
}
// 実際にカウンターを作成
var count = counter();
p(count()); // 1
p(count()); // 2
p(count()); // 3
// 内部状態が取得できる
p(eval("num", count)); // 3
// 内部状態を変えられる
p(eval("num=10", count)); // 10
p(count()); // 11
// 関数のプロパティとしては存在していない
p(count.num); // undefined
// 無名関数で上と同じことをしてみる
var f = (function(){
var x = 100;
return function(){x}
})()
// 内部状態が取得できる
p(eval("x", f)); // 100
// 一部を変えて、再度テスト
var f = (function(){
var x = 100;
return function(){} // この関数の中でxを使わない
})()
// エラー、内部状態へのアクセスに失敗
// コンパイル時に未使用のためコンテキストから削除されている?
// p(eval("x", f)); // x is not defined
// クラスでどうなるかを確認
function Cat(age){
var _age = age;
// インスタンスメソッドとしてゲッターを追加
this.getAge = function(){
return _age;
}
}
var cat = new Cat(10);
// エラー、プライベート変数に直接アクセスできない
// p(eval("_age", cat)); // _age is not defined
// ゲッター経由ではアクセスできる
// 同一スコープでゲッター関数が定義されているため
p(eval("_age", cat.getAge)); // 10
p(eval("_age=50", cat.getAge)); // 50 ゲッター経由で書き換え
p(cat.getAge()) // 50
第二引数についての説明。
An optional argument; if specified, the evaluation is restricted to the context of the specified object.