Reputation: 42977
I am pretty new to JavaScript, and I was experimenting with the global scope following a tutorial.
In this tutorial I have 3 files:
1) index.htm:
<html>
<head></head>
<body>
<h1>HELLO WORLD !!!</h1>
<script src="app.js"></script>
<script src="utility.js"></script>
</body>
</html>
As you can see I include 2 JavaScript files.
2) app.js:
var person = 'Torny'; // When I call the logPerson() function this line override the person variable value into the global stack
//console.log(person);
logPerson();
3) utility.js in which is defined the logPerson() function defined into the app.js file:
var person = 'Steve';
function logPerson() {
console.log(person);
}
Ok, so I expected the following behavior:
Into the app.js file set the string 'Tony' as value of the person variable, the call the logPerson() function declared into the utility.js file and so print 'Tony' in the console.
The problem is that when I try to open the index.htm file into FireFox, I go into FireBug console and instead the 'Tony' value I obtain this error message:
ReferenceError: logPerson is not defined
So it seems that from the app.js file it can't see the logPerson() function that is defined into the utility.js file and imported.
Why? What am I missing? what is wrong?
Upvotes: 4
Views: 9588
Reputation: 2267
In my case, it wasn't the <script>
ordering that was the issue (as initially thought), but the scope in which the function was defined. To enable access of the function in other JS files, I made it a property of the object that is in the scope of those files. So now, it can be accessed as MyObject.myFunction
wherever MyObject
is instantiated.
(function ($) {
function MyObject(data) {
var myFunction = function(){
console.log('');
}
$.extend(this, {
// methods
"myFunction": myFunction,
});
}
}(jQuery));
Upvotes: 0
Reputation: 6404
First browser will parse the JS files.
If you see the order of script included
So when it is parsing app.js. It sees logPerson()
which is a function call not function definition. At this point of time the file utility.js is not parsed and the browser is not aware of that function also. (meaning till it reads utility.js).
So to solve this, call the logPerson api after dom-loaded, usiing body onload
function.
Upvotes: 3
Reputation: 4485
In javascript the order of the files matters. You need to load the script which defines your function before you can use it. Switch the 2 <script>
tags
<body>
<h1>HELLO WORLD !!!</h1>
<script src="utility.js"></script>
<script src="app.js"></script>
</body>
</html>
Upvotes: 13
Reputation: 5629
change
<script src="app.js"></script>
<script src="utility.js"></script>
to
<script src="utility.js"></script>
<script src="app.js"></script>
;) You try to get definitions from a script which is loaded later greetings
Upvotes: 4
Reputation: 943759
You run the script which tries to use logPerson
before you run the script that defined logPerson
.
If you reverse the order of the scripts, it will work.
Function declaration hoisting only works within a given script.
Upvotes: 2
Reputation: 8803
The explanation is as simple as that Javascript code is interpreted on the fly: As one script is loaded, it is executed immediately.
So, you just have to declare the scripts in the right order of dependence.
Upvotes: 2