javascript - 如何创建一个不继承词法作用域的函数 expr?

标签 javascript

以下 JavaScript 违反了 CSP(如果 CSP 有默认设置):

(function() {
  return new Function('return function Thing() {}');
}());

但是这个替代方案继承了它的父作用域:

(function() {
  var foo = '42';
  return function Thing() {};
}());

我认为这可以防止 foo 被垃圾收集。

如果您仅限于在内部编写代码,有没有办法将函数定义放在全局范围内(请注意,我的意思不是在全局范围内访问它,我的意思是它的定义存在于全局范围内) IIFE?

最佳答案

我不太确定你想在这里实现什么,因为你提供的代码没有做任何实际用途。变量foo将被创建并赋值,并且函数Thing将被返回,但是一旦执行IIFE,所有引用都会丢失,并且将发生垃圾收集。

如果我让函数作为示例更有用一点,下面将生成 thing 函数,并且变量 foo 将仍然存在,因为它已关闭结束 - 请参阅 closures .

function generateThing() {
    var foo = '42';
    return function thing() {
        console.log("thing:", foo)
    };
}

var myThing = generateThing();
myThing();

如果在内部函数中没有引用foo,则该引用将不会被维护,并且会被垃圾回收。

如果您的模块使用对象文字,则可以使用 this 限制范围。在以下示例中,generateThing 函数引用模块的 foo 字段。在执行期间,该值将在词法范围内可用。但是,如果您创建内部函数,上下文 this 将有所不同。因此,当你调用返回的函数时,它会输出undefined

您可以使用 apply 函数(以及其他函数)控制 this 的上下文。通过以 myModule 作为上下文调用函数,我们可以引用 foo 变量。

(function() {
    var myModule = {
        foo: 42,
        generateThing: function() {
            console.log("generateThing", this.foo);
            return function() {
                console.log("thing:", this.foo);
            }
        }
    }

    window.myModule = myModule;

}());

var thing = myModule.generateThing(); // log: generateThing 42
thing(); // log: thing undefined
thing.apply(myModule); // output: thing 42

关于javascript - 如何创建一个不继承词法作用域的函数 expr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36998910/

相关文章:

javascript - 使用 SVG 的圆环图

Javascript getUTCMonth() 在 12 月返回 0?

javascript - JS document.write函数和打印字符^

javascript - jquery 日期选择器不适用于母版页

javascript - 使用 jQuery 选择器时的默认上下文是什么?

javascript - angular 2 文本输入使有意义的强制性

javascript - 如何从这个类元素中获取数字?

javascript - 异步/等待如何串行和并行工作?

javascript - 如何用 ExtJS 监听单选按钮是否被选中?

javascript - 如何在PHP中使用正则表达式从大字符串中提取电话/手机号码