“严格使用”; + jQuery.getScript()= script无法导出到全局命名空间

假设我有以下脚本,名为include_strict.js 。 执行后我应该定义window.global1

 "use strict"; var globalVar = {}; alert(typeof window.globalVar); 

但是,如果我从一个javascript块包含它

 $.getScript("include_strict.js"); 

警报说undefined 。 为什么? 这里发生了什么?

仅供参考,如果我使用脚本标记包含文件,那就不会发生这种情况:

  

在这里,我看到预期的警报, object 。 如果我删除"use strict"; ,然后是jQuery.getScript(); 具有相同的显示object效果。

我已经创建了一个示例( https://docs.google.com/file/d/0B-XXu97sL1Ckb0x0OHptTmVMY00/edit )来演示这一点。

它使用$.getScript() ,它使用eval来执行脚本,该脚本无法在严格模式下修改全局范围:

其次,严格模式代码的eval不会将新变量引入周围范围。 在正常的代码中, eval("var x;")将变量x引入周围函数或全局范围。 这意味着,通常,在包含对eval的调用的函数中,每个不引用参数或局部变量的名称必须在运行时映射到特定的定义(因为该eval可能引入了一个隐藏外部变量的新变量)。 在严格模式下,eval仅为正在评估的代码创建变量,因此eval不会影响名称是指外部变量还是某个局部变量:

资料来源: https : //developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode

解决方案不是使用jQuery加载脚本,而是将script元素附加到DOM。 请注意,您甚至无法使用jQuery追加元素; 它将自动使用$.getScript()

jQuery eval脚本。 “使用严格;” 里面的eval改变了代码的语义。 这就是严格模式危险的原因! 因为在不支持它的浏览器中,您的代码会执行其他操作。

其次,严格模式代码的eval不会将新变量引入周围范围。 在正常的代码中,eval(“var x;”)将变量x引入周围函数或全局范围。 这意味着,通常,在包含对eval的调用的函数中,每个不引用参数或局部变量的名称必须在运行时映射到特定的定义(因为该eval可能引入了一个隐藏外部变量的新变量)。 在严格模式下,eval仅为要计算的代码创建变量,因此eval不会影响名称是指外部变量还是某个局部变量。

https://developer.mozilla.org/en/JavaScript/Strict_mode

解决方案是使用window.foo = "bar;" 而不是var foo = "bar"; 。 你应该把你的代码放在IIFE中以使“严格使用”; 更可预测。

 (function(window) { "use strict"; window.globalVar = {}; alert(typeof window.globalVar); }(window)); 

在执行之前处理响应删除严格模式:

  $.ajax({ url: scriptUrl, dataType: "script", dataFilter: function (data, type) { return data.replace("\'use strict\';", ""); } });