“严格使用”; + 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\';", ""); } });