众所皆知,Java script 是可以利用eval 动态存取scope chain 的区域变数
如下所示:
- var obj = {};
- (function(obj) {
- var var3 = "Varia ble 3";
- (function(obj) {
- var var2 = "Variable 2";
- (function(obj) {
- var var1 = "Variable 1";
- obj.getVar = function(varName) {
- return eval(varName);
- }
- obj.setVar = function(varName, value) {
- return eval(varName + "=value");
- }
- })(obj);
- })(obj);
- })(obj);
- console.log(obj.getVar("var2")); // Variable 2
- obj.setVar("var2", {id: 123})
- console.log(obj.getVar("var2").id); // 123
ActionScript 3.0 改版之后拿掉了eval 功能
难道因为这样就无法动态评估存取区域变数了吗?
之前我也是这样想的
不过最近再次看到 scope chain 相关文章
结合过去所学过的 AS3 namespace 语法
忽然有了其它的想法,于是开始动手测试~
测试后又有了新的发现
原来我们『可以利用internal namespace 动态存取scope chain 的区域变数! 』
AS3 语法内建的namespace 主要有AS3、public、protected、private、internal ...等
ActionScript language and syntax - Packages and namespaces
ActionScript 语言和语法- 套件和命名空间
关键就是在 internal namespace 上
文件 上写的是可以存取package 层级的名称空间
但是其实还能用来存取scope chain 的区域变数
以下是一个简单的 Demo:
- package {
- /**
- * 透过internal 名称空间动态存取scope variable
- */
- import flash .display.Sprite;
- [SWF(width="300", height="200")]
- public class ScopeTest01 extends Sprite {
-
- public function ScopeTest01() {
- var obj:Object = {};
- (function(obj:Object):void{
- var var1:String = "Variable 1";
- var var2:String = "Variable 2";
-
- obj.getVar = function (name:String):*{
- return internal::[name];
- };
- obj.setVar = function (name:String, value:*):*{
- return internal::[name] = value;
- };
- })(obj);
-
- trace(obj.getVar("var1")); // Variable 1
- obj.setVar("var1", "Hello");
- trace(obj.getVar("var1")); // Hello
- }
- }
- }
- // Ticore's Blog - http://ticore.blogspot.com/
很神奇吧!
AS3 拿掉eval 之后损失的动态评估能力,又靠着internal namespace 巧妙的找回来了
AS3 利用with, Proxy 选择性替换Scope Variables
ActionScript "with" Block Scope 遮蔽效应
ActionScript 3.0 - Function Closure
AS 3.0 利用匿名函式模拟多层 Block Scope