为什么这个函数运行而不是用返回值初始化全局XYZ
?
"use strict";
XYZ = (function(){
var obj = {'a':1,'b':2,'c':3};
console.log("about to return:");
console.log(obj);
return obj;
})();
console.log(XYZ); // shows undefined
jsfiddle
似乎奇怪的是,前两个console.log返回合理的输出,然后Chrome抛出Uncaught ReferenceError: XYZ is not defined
当显式使用window.XYZ
时,这工作得很好:
"use strict";
window.XYZ = (function(){
var obj = {'a':1,'b':2,'c':3};
console.log("about to return:");
console.log(obj);
return obj;
})();
console.log(XYZ); // shows a:1, b:2, c:3
如果"use strict;"
被移除,则将工作。但是不要那样做——继续读。
严格模式防止XYZ = ...
成为新的全局变量。
John Resig在他对严格模式的概述中解释道:
尝试在
foo
没有定义的地方赋值foo = "bar";
将会导致失败。对象的foo属性赋值全局对象(例如window.foo
),现在它只是抛出一个异常。这一定会抓住一些烦人的bug。
window.XYZ = IIFE()
的代码在严格模式下工作,因为这里的赋值是对现有对象window
的属性。
对于许多应用程序来说,使用window.XYZ
可能"足够好",但是您可能会遇到在包管理器中使用window.XYZ
"短路"依赖管理的平台(例如Meteor)。在这种情况下,严格模式可以在IIFE中启用,但不能在页面级别启用。
要使用严格模式,将一个单例IIFE赋值给一个新的全局变量,只在IIFE的第一行打开严格模式。
XYZ = (function() {
"use strict";
var obj = {
'a': 1,
'b': 2,
'c': 3
};
console.log("about to return:");
console.log(obj);
return obj;
})();
console.log(XYZ);
警告:"use strict;",因为第二行没有启用严格模式:
不要这样做:
XYZ = 0;
"use strict";
XYZ = ...
您可以通过查看this
没有显式设置的函数中的this
来测试是否启用了严格模式。当严格模式为true时,取消设置时this
为null
,当严格模式为false时,this
为window
。
参见:use strict"在JavaScript中做什么,背后的原因是什么?