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

时间:2012-10-08 06:31:06

标签: jquery global-variables getscript use-strict

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

"use strict";

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

但是,如果我从一个带有

的javascript块中包含它
$.getScript("include_strict.js");

警告说undefined。为什么?这是怎么回事?

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

<script type="text/javascript" src="include_strict.js"></script>

在这里,我看到了预期的提醒object。如果我删除"use strict";,则jQuery.getScript()<script>;都会显示object

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

3 个答案:

答案 0 :(得分:11)

它使用$.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()

答案 1 :(得分:2)

jQuery eval更新脚本。 “使用严格;” inside 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));

答案 2 :(得分:0)

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

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