我是一个自学成才的JS黑客,并试图更正式,因为我必须建立一个更好的JS应用程序,名称间隔和更好的JS公民。我会很感激我在这里做错了一些指示。
这个想法是使用第一个闭包来构造一个命名空间,然后在第二个我添加一个方法a' class'构造函数到命名空间对象。我在子上调用了一个方法。
(function() {
'use strict';
/**
* @namespace ProjectX
*/
var ProjectX = {
attr1: 'I am inside ProjectX'
}
window.ProjectX = ProjectX;
})()
//console.log(ProjectX.attr1); // When this line is uncommented the code will output 'foobar' as expected?
(function() {
'use strict';
ProjectX.subObj = function(val) {
this.name = val;
return this;
};
})();
var subObj = new ProjectX.subObj('Foobar');
console.log(subObj.name);

我期待着看到Foobar'在控制台日志中。但是,这会在控制台中产生以下结果:
{ " message":" Uncaught TypeError :(中间值)(中间值)(中间值)(...)不是函数", " filename":" http://stacksnippets.net/js", " lineno":03, " colno":1 }
当我读到这段代码时,我希望两个IIFE将按顺序执行,第一个将ProjectX带入生命,然后第二个向ProjectX添加一个将返回subObj的构造函数。此外,如果第16行的console.log((ProjectX.attr1)未被注释,代码将按照我的预期运行。这似乎表明ProjectX实体不会出现,直到我有这与我对IIFE的理解相矛盾,即它们立即运行,无论如何,ProjectX不是构造函数 - 它是一个全局变量。
在研究中,我发现function inside of IIFE not recognized似乎是相似的区域,但与将事件绑定到DOM而不是与我的查询并行相关。
答案 0 :(得分:4)
在第一个IIFE之后你缺少一个分号,当删除带分号的console.log时,它就变得相关了。您可以搜索JS中需要分号的情况
没有分号,您的代码可以解释为:
(function() {
var ProjectX = {
attr1: 'I am inside ProjectX'
}
window.ProjectX = ProjectX;
})()(function() {
ProjectX.subObj = function(val) {
this.name = val;
return this;
};
})();
以(IIFE)()()
格式检查以下函数,这是有效的,因为IIFE返回一个函数,该函数使用('Hey')
(function() {
return function(msg){console.log(msg)}
})()('Hey')
没有分号,javascript期望你的第一个IIFE返回一个函数,这不是你的代码的情况所以它抛出一个Type错误,说它期待一个函数但是未定义。您的代码最终评估为:
undefined(function() {
ProjectX.subObj = function(val) {
this.name = val;
return this;
};
})();
或更简化为
undefined(<a function as parameter>)()
然后会抛出错误,即此处需要function
而不是undefined
。
阅读javascript中的高阶函数,以便更好地了解这种语法以及代码模糊不清的内容。