3

我想这样做是因为我的项目通常使用如下快捷变量:

(function() {
    var world = new World(),
        Event = world.Event,
        Guide = world.Guide;

    Event.add('updateUI', function() {
        // 1st: Correct, the value of 'this' refers to a world
        this.Guide.show('UI updated');
        // 2nd: Ok because 'world' was defined in outer scope
        world.Guide.show('UI updated');
        // 3rd: Ok because 'Guide' was defined in outer scope
        Guide.show('UI updated');
    });
})();

如果我移动Event.add('updateUI', function() { ... });到其他文件,只有第一个语句 ( this.Guide.show) 有效。如何防止此函数使用外部作用域的worldorGuide变量,以便第二条和第三条语句从一开始就抛出错误。

use strict非常接近这一点,但它只会阻止您访问全局对象。

更新以使这个问题更清楚:主要问题是:是否有任何方法可以防止函数在外部范围内查找变量?如果没有办法,请解释原因,因为我认为这样做是合理的。

4

2 回答 2

2

您可以使用阴影。如果您在函数内部显式声明变量(而不是对其进行初始化),则函数将使用此变量而不是外部作用域中的同名变量。

例子:

var outer = 'foo';

function isolated () {
  var outer;
  console.log(outer);
};

isolated(); // output undefined

这应该可以满足您的需求。

还有另一种方法,但它是一个丑陋的黑客,可能不适用于某些浏览器(IE?)。

这是一个例子:

var outer = 'foo';

function isolated () {
  console.log(outer);
};

var e = eval;
// will throw exception: 'outer' is not defined
console.log(e('('+isolated.toString()+')()'));

eval并且e不完全相同。'true' eval 可以访问整个范围,但如果您复制它,则 javascript 引擎可以通过不使外部范围可用于 evaled 代码来优化它。

但是:不要那样做

  • 首先:它依赖于 function.toString() 将输出函数代码的事实。这不是规范的一部分,因此不可靠(尽管适用于 v8 和 spidermonkey)。
  • 第二:eval应该避免,它使调试成为一场噩梦(您无法访问有用的堆栈跟踪),存在性能和安全问题,并且您很快就会得到一个糟糕的代码来维护。
于 2013-12-23T08:00:43.027 回答
0

不知道您为什么要这样做,但使用简短的示例:

(function(theFunk) {
    var world = new World(),
        Event = world.Event,
        Guide = world.Guide;

    Event.add('updateUI',theFunk);

})(function(){
        this.Guide.show('UI updated');  // 1st: depends on what you do with it
        world.Guide.show('UI updated'); // 2nd: will fail (depends on global)
        Guide.show('UI updated');       // 3rd: will fail (depends on global)
});
于 2013-10-28T04:55:46.183 回答