以下 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/