jQuery/JavaScript功能范围/提升
我有两个包含JavaScript和jQuery函数的文件。它们在页面上的引用顺序如下:jQuery/JavaScript功能范围/提升,javascript,jquery,Javascript,Jquery,我有两个包含JavaScript和jQuery函数的文件。它们在页面上的引用顺序如下: <script src="js/kiosk-functions.js"></script> <script src="js/kiosk-main-socket-handler.js"></script> 然后,在kiosk-main.js中,我有一个- $(function() { var socket = io(); socket.on('m
<script src="js/kiosk-functions.js"></script>
<script src="js/kiosk-main-socket-handler.js"></script>
然后,在kiosk-main.js中,我有一个-
$(function() {
var socket = io();
socket.on('message', function (data) {
if(isJSON(data)) {
// do stuff
}
});
// other JavaScript and jQuery code
});
这导致了以下错误-
未捕获引用错误:未定义isJSON
一旦我将isJSON()
函数移出kiosk-functions.js中的文档就绪处理程序,一切都很好,但让我感到困惑。我在这里读了很多答案,所以我试图理解到底发生了什么,因为我的印象是,这个功能将被提升并在全球范围内可用。我没有找到任何能证明这个例子的东西
我确信我在这里遗漏了一些简单的东西。文档就绪处理程序(一个函数)是否阻止了isJSON()
函数被提升?或者这是一个简单的范围问题?$(function(){})
只是$(document.ready(function(){})的一个较短版本代码>
在上述函数中,此
是文档
,要使函数成为全局函数,它需要位于窗口
上下文中
提升不是您的问题,声明函数的范围是
如果它在代码中被广泛使用,并且不是您正在构建的特定模块或库的一部分,那么您可以在全局上下文中声明函数,或者只创建函数,window
的属性使其成为全局函数
如果是某个库或模块,则可以将其附加到该库或模块,使其仅特定于该库/模块
简而言之,如果您确实多次使用名称空间,并且它是一个通用函数,请使用名称空间或使其成为全局的。您的问题不在于提升,而在于函数的范围
基本上,在kiosk functions.js
中定义对document.ready
的回调,并在该回调中定义函数isJSON()
。该函数仅在该范围内已知
在第二个文件kiosk main.js
中,您尝试使用isJSON()
,就好像它是在回调的作用域或全局作用域中定义的一样。两者都不是这样,因此出现了错误
为了解决这个问题,您可以添加一些全局名称空间myNamespace
,并将函数附加到其中:
$(function() {
// some JavaScript functions
function isJSON(str) {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
}
// init namespace
window.myNamespace = window.myNamespace || {};
// attach function
window.myNamespace.isJSON = isJSON;
});
然后在另一个文件中,您可以引用该全局命名空间来调用您的函数:
$(function() {
var socket = io();
socket.on('message', function (data) {
if(myNamespace.isJSON(data)) {
// do stuff
}
});
// other JavaScript and jQuery code
});
编辑
正如@Alnitak在评论中提到的:在浏览器中,全局对象是窗口
。相应地更改了代码。变量和函数定义仅在封闭的函数范围内提升,在您的情况下,这是您传递给$()
的匿名函数。在这方面,提升并没有什么不同,只是isJSON
函数定义在不同的范围内
您可能希望考虑模块命名空间模式:
var NAMESPACE = NAMESPACE || {};
NAMESPACE.isJSON = function() {
...
};
其中NAMESPACE
是一个全局变量,它将包含所有本地定义的函数
名称空间| |{}
用于确保名称空间
对象如果已经存在,则不会被覆盖。因此在这种情况下不会发生提升?@JayBlanchard会发生提升,但提升函数与scopeAh有关!现在这是有道理的。javascript是函数范围的(不是说let
语句)isJSON
是在ready handler作用域下定义的OP提到的jQuery-很可能他想要window
而不是global
。感谢对使用命名空间的解释,我没有机会使用它,但看起来我可以在这个项目上利用它。@JayBlanchard不再,-)谢谢。
var NAMESPACE = NAMESPACE || {};
NAMESPACE.isJSON = function() {
...
};