硬核javascript模块范围

时间:2014-03-12 16:51:00

标签: javascript scope

问题:我想迭代我的函数列表,并使用以下代码修改它们:

for(var funcProperty in scope) {
    scope['_'+funcProperty] = scope[funcProperty];
    scope[funcProperty] = wrapFunctionInTryCatchBlock(scope['_'+funcProperty]);
}

我想这样做而不必明确地完成我的所有功能,并将它们添加到某个对象,从而创建所需的范围。我不想这样做,因为所有相互调用的函数都必须修改并延长其名称:

funcName变为scopeObject.funcName烦人。

如果我的函数在全局对象中,我可以很容易地做到这一点,即Window,但是我不想污染全局命名空间,所以我把它们放在一个模块中,如下所示:

var MyModule = (function() {
    function privateFunc1(...) {...} 
    function privateFunc2(...) {...}

    var public_api = {
        coolName : privateFunc1
    };
    return public_api;
}());

但是,我可以看到并找不到访问立即执行的函数调用中存在的范围对象的方法,该函数调用的返回值分配给MyModule。

我尝试在MyModule中执行此操作:

console.log(this)

要知道我们是否确实有权访问范围,当然,事实证明这是指Window。

我的问题是:什么是 MyModule专用作用域中的方法所分配的作用域对象,因为它不是全局对象,并且确实存在,因为所有函数都是隐式的访问它。作为JavaScript程序员,我有什么方法可以显式访问范围对象并枚举其属性,还是那个FORBIDDEN?

1 个答案:

答案 0 :(得分:0)

我不会急于接受这个作为答案,但我找到了一个我很满意的可能的解决方案。

"快乐的定义"在这种情况下:最小额外工作,几乎不改变现有代码。

解决方案

我们修改模块代码如下:

// $ = wrapFunctionInTryCatchBlock
function $(fun) {
return function() { 
   try {
        return fun.apply(this,arguments);
    } catch(err) {
        console.log("Error",err,err.stack);
    }
};
}

var MyModule = (function() {
    var privateFun1 = $(privateFun1(...){...});
    var privateFun2 = $(privateFun2(...){...});

    var public_api = {
        coolName : privateFun1
    };
    return public_api;
}());

为什么会这样?

我们得到了所需的代码修改(函数包装),基本上就位,因为分配给函数表达式的变量与原始命名函数本身具有完全相同的范围。

VIM正则表达式帮助

我还创建了一个VIM正则表达式来帮助解决这个问题,至少是分配线:

s/function \(\w\+\)\(.\+\)$/var \1 = $(function \1\2/g