admin管理员组文章数量:1399754
Most relevant answers here do not refer to let, which is block scoped, but to var, which is hoisted. I can't seem to get a definitive answer to this.
I have a variable declared globally that initializes once:
let firePaused = false;
and then a function in the keyboard handler that is running everytime I press a button:
function actOnKeyPress() {
if (rightPressed) {
game.hero.rotate(game.hero.speed);
} else if (leftPressed) {
game.hero.rotate(-game.hero.speed);
}
if (!firePressed) {
firePaused = false;
}
if (firePressed && options.numberOfBullets > 0) {
if (!firePaused) {
fireBullet();
firePaused = true;
}
}
}
(not relevant to the question, but it's purpose is to only allow the player to fire once, there needs to be a keyup event before they can fire again)
By the rules of clean code I should declare the variable at the top of the function... BUT that means it will be redeclared everytime I press a button.
It says here /
Initialization: When you declare a variable it is automatically initialized, which means memory is allocated for the variable by the JavaScript engine.
So I would be creating a whole new variable each time the let keyword is used.
Should I go to the bother of writing a conditional at the start of the function to check if firePaused
is declared yet, and if not declare it? That seems total overkill.
Most relevant answers here do not refer to let, which is block scoped, but to var, which is hoisted. I can't seem to get a definitive answer to this.
I have a variable declared globally that initializes once:
let firePaused = false;
and then a function in the keyboard handler that is running everytime I press a button:
function actOnKeyPress() {
if (rightPressed) {
game.hero.rotate(game.hero.speed);
} else if (leftPressed) {
game.hero.rotate(-game.hero.speed);
}
if (!firePressed) {
firePaused = false;
}
if (firePressed && options.numberOfBullets > 0) {
if (!firePaused) {
fireBullet();
firePaused = true;
}
}
}
(not relevant to the question, but it's purpose is to only allow the player to fire once, there needs to be a keyup event before they can fire again)
By the rules of clean code I should declare the variable at the top of the function... BUT that means it will be redeclared everytime I press a button.
It says here https://www.sitepoint./how-to-declare-variables-javascript/
Initialization: When you declare a variable it is automatically initialized, which means memory is allocated for the variable by the JavaScript engine.
So I would be creating a whole new variable each time the let keyword is used.
Should I go to the bother of writing a conditional at the start of the function to check if firePaused
is declared yet, and if not declare it? That seems total overkill.
-
1
It seems like you have a global variable,
game
. What aboutgame.state.firePaused
? That way, if you put all gamestate-related variables there, you could even easily save the game. – Jeff Huijsmans Commented May 2, 2018 at 14:25 - 1 is it possible that you could return true or false instead of setting a variable? – Ryan Schaefer Commented May 2, 2018 at 14:25
- That Sitepoint note is at best misleading, and in my opinion it's simply wrong. – Pointy Commented May 2, 2018 at 14:31
4 Answers
Reset to default 4If your variable is declared in the global scope, then it doesn't really matter if you use let
or var
.
These are functionally identical:
let myVar = 123;
function doStuff() {
console.log(myVar);
}
doStuff();
var myVar = 123;
function doStuff() {
console.log(myVar);
}
doStuff();
The difference between var
and let
bees significant when you're declaring them in blocks:
if(true) {
var foo = 1;
}
if(true) {
let bar = 2;
}
console.log("var foo:", foo);
console.log("let bar:", bar);
As you can see, the let
declaration is restricted to its wrapping block scope. The var
declaration ignores block scope.
Looks like you are attempting to maintain a character's (hero) state in multiple locations. This will bee more and more difficult to maintain in a global scope as each character's actions / states will add to the global variables.
As per @jeff-huijsmans suggestion, I believe you should maintain the state inside your game
object.
This could be defined in a few ways:
game.state.firePaused
- This locks your game state to a single character, but will better contain the state of a character shooting.game.hero.firePaused
- This allows each character to maintain their own shooting state. This also has the added benefit of being able to add more characters with firing states.
As an aside, it looks like most of the answers here are attempting to address the scope issue. Defining variables globally and attempting to maintain a state outside of a function bees very difficult to understand/read/test. There will be a lot of opinions on this topic. Fortunately for your root issue you can avoid this by using your pre-existing state object.
This question really has nothing to do with let
vs. var
, per se - it's about scope in general.
Variables should be declared in the smallest scope that keeps the program functional. Global variables should be a last resort.
So, in your case, you don't need a Global variable to achieve your goal of not re-declaring the variable upon each function call. You just need to create another scope. Since all code should be kept out of the Global scope in the first place, your code should already have at least one sub-scope, which is often achieved with an Immediately Invoked Function Expression, which creates the "Module Pattern":
(function(){
let firePaused = false; // This is scoped to the entire module, but not Global
function actOnKeyPress() {
if (rightPressed) {
game.hero.rotate(game.hero.speed);
} else if (leftPressed) {
game.hero.rotate(-game.hero.speed);
}
if (!firePressed) {
firePaused = false;
}
if (firePressed && options.numberOfBullets > 0) {
if (!firePaused) {
fireBullet();
firePaused = true;
}
}
}
})();
No, you should not create a global variable (and not with let
anyway).
Yes, you should declare it outside of the function if you want to have it shared between calls.
You can use a closure for that, with any kind of module pattern - from ES6 module to IIFE to simple block scope.
// ES6 module
let firePaused = false;
export function actOnKeyPress() {
// use `firePaused`
}
// IIFE
var actOnKeyPress = (function() {
let firePaused = false;
return function actOnKeyPress() {
// use `firePaused`
};
}());
// block scope
var actOnKeyPress;
{
let firePaused = false;
actOnKeyPress = function actOnKeyPress() {
// use `firePaused`
};
}
版权声明:本文标题:javascript - Should I declare a variable using LET globally for a function that runs constantly? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744147211a2592892.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论