“使用严格”; + jQuery.getScript() = 脚本不能导出到全局命名空间
Posted
技术标签:
【中文标题】“使用严格”; + jQuery.getScript() = 脚本不能导出到全局命名空间【英文标题】:"use strict"; + jQuery.getScript() = script can't export to global namespace 【发布时间】:2012-09-28 09:21:13 【问题描述】:假设我有以下脚本,称为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) 来演示这一点。
【问题讨论】:
【参考方案1】:它使用$.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()
。
【讨论】:
你比我多几秒 ;-) 非常有趣。我只是第一次遇到这个问题,这完全有道理。我的问题是我需要在加载后依次执行几个脚本,所以在添加下一个脚本之前我需要知道脚本何时加载。如果我使用将脚本附加到 DOM 的方法,有没有办法让我知道脚本何时加载? .load() 会起作用吗?【参考方案2】:jQuery eval
uates 脚本。 “使用严格;” 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));
【讨论】:
这不是我所需要的,但它让我“点击” - 非常感谢! :)【参考方案3】:在执行前处理移除严格模式的响应:
$.ajax(
url: scriptUrl,
dataType: "script",
dataFilter: function (data, type)
return data.replace("\'use strict\';", "");
);
【讨论】:
以上是关于“使用严格”; + jQuery.getScript() = 脚本不能导出到全局命名空间的主要内容,如果未能解决你的问题,请参考以下文章