I have two files containing JavaScript and jQuery functions. They are referenced on the page in this order:
<script src="js/kiosk-functions.js"></script>
<script src="js/kiosk-main-socket-handler.js"></script>
In kiosk-functions.js I had originally done this -
$(function() {
// some JavaScript functions
function isJSON(str) {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
}
// some jQuery code follows...
});
Then, in kiosk-main.js I had this -
$(function() {
var socket = io();
socket.on('message', function (data) {
if(isJSON(data)) {
// do stuff
}
});
// other JavaScript and jQuery code
});
This resulted in the following error -
Uncaught ReferenceError: isJSON is not defined
Once I moved the isJSON() function out of the document ready handler in kiosk-functions.js then all was well, but left me puzzled. I read a number of the answers here on SO trying to understand what was going on, being under the impression that the function would be hoisted and available globally. I didn't find anything that demonstrated this example.
I'm sure that I am missing something simple here. Does the document ready handler (a function) keep the isJSON() function from being hoisted? Or is it a simple scope issue?
Your problem is not hoisting, but the scope of the function.
Basically in kiosk-functions.js you define a callback to document.ready and inside that callback you define the function isJSON(). The function is just known within that scope.
In the second file kiosk-main.js you try to use isJSON() as if it was defined either in that callback's scope or in the global scope. Both is not the case, hence the error.
In order to solve this, you could add some global namespace myNamespace and attach your function there:
$(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;
});
Then in the other file you can reference that global namespace to call your function:
$(function() {
var socket = io();
socket.on('message', function (data) {
if(myNamespace.isJSON(data)) {
// do stuff
}
});
// other JavaScript and jQuery code
});
Edit
As mentioned by @Alnitak in the comments: In the browser the global object is window. Changed code accordingly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With