Global and local variables in my script
I am just starting to learn javascript and am trying to write a little script that will make a grid of divs on a page.
Here's the script:
var tileWidth=50;
var tileHeight=100;
var leftPos=10;
var topPos=10;
var columns=10;
var rows=10;
var spacing=5;
$('document').ready(function() {
placeTiles();
});
function makeRow() {
for (var i=0; i<columns; i++) {
$('#canvas').append('<div class="tile" style="left:' + leftPos + 'px;top:' + topPos + 'px;"></div>');
var leftPos = leftPos + tileWidth + spacing;
}
}
function placeTiles() {
for (var i=0; i<rows; i++) {
makeRow();
var topPos = topPos + tileHeight + spacing;
}
}
Currently 100 is being created <div>
, all with a top position of 10px and a left position of undefined (for the first <div>
in the line) or NaN.
What should I do differently? Why makerow()
can't it see my global variable leftPos
(and all other variables)?
Thanks.
a source to share
"Why can't makeora () see my global leftPos (and all other variables)?"
Because it is var
not an ad. This function (scope) is a general annotation. There var
is essentially nothing being done in the top-level scope (the global context / execution scope is a window object), so it is the same as window.leftPos = 10
or just leftPos = 10
. In makeRow, you essentially have:
function makeRow() {
var leftPos = undefined // this is "hoisted" to the TOP of the function
for (...) {
// ...
leftPos = leftPos + tileWidth + spacing
}
}
Does something look suspicious? :-)
Two solutions: 1) use a different variable name (recommended) 2) use the "global" leftPos property of the window object (as shown below).
Also, while this is just a wide-ranging annotation, it usually results in cleaner code if you keep "var at the top (it's" hoisted "anyway, see above). For example:
function makeRow() {
var leftPos = window.leftPos // or use a different name, which is what I'd do
for (var i=0; i<columns; i++) {
$('#canvas').append('<div class="tile" style="left:' + leftPos + 'px;top:' + topPos + 'px;"></div>')
leftPos = leftPos + tileWidth + spacing
}
}
For more information see ID Resolution, Execution Contexts and Scope Chaining
In JavaScript, you can have scope or global scope for your variables.
If you have two variables with the same name in different scopes, the first task is assigned the variable declared in the function scope.
So you have variables leftPos
and topPos
declared in the global scope at the top of your script, and you also declare them in functions makeRow()
and placeTiles()
. The keyword is var
used to declare variables, not to assign variables.
You just need to remove the declaration of the using variable var
from the functions in order to use the global variables. Just use:
leftPos = leftPos + tileWidth + spacing; // and topPos = topPos + tileHeight + spacing;
However, you should avoid global variables. Globals are evil.
Further reading:
a source to share