[英]Should I declare a variable using LET globally for a function that runs constantly?
Most relevant answers here do not refer to let , which is block scoped, but to var , which is hoisted. 这里最相关的答案不是指let ,它是块作用域,而是指var ,它被挂起。 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) (与问题无关,但它的目的是只允许玩家射击一次,在他们再次射击之前需要有一个keyup事件)
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.com/how-to-declare-variables-javascript/ 它在这里说https://www.sitepoint.com/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. 初始化:声明变量时,它会自动初始化,这意味着JavaScript引擎会为变量分配内存。
So I would be creating a whole new variable each time the let keyword is used. 因此,每次使用let关键字时,我都会创建一个全新的变量。
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? 我是否应该在函数开始时编写一个条件来检查是否已声明firePaused
,如果没有声明它? That seems total overkill. 这似乎完全矫枉过正。
If your variable is declared in the global scope, then it doesn't really matter if you use let
or var
. 如果您的变量在全局范围内声明,那么使用let
或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
becomes significant when you're declaring them in blocks: 当你在块中声明它们时, var
和let
之间的区别变得很重要:
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. 如您所见, let
声明仅限于其包装块范围。 The var
declaration ignores block scope. var
声明忽略块范围。
Looks like you are attempting to maintain a character's (hero) state in multiple locations. 看起来您正试图在多个位置维护角色(英雄)状态。 This will become 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. 根据@ jeff-huijsmans的建议,我相信你应该保持game
对象中的状态。
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.state.firePaused
- 这会将你的游戏状态锁定为单个角色,但最好包含角色射击的状态。 game.hero.firePaused
- This allows each character to maintain their own shooting state. game.hero.firePaused
- 这允许每个角色保持自己的射击状态。 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 becomes 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. 幸运的是,对于根本问题,您可以通过使用预先存在的状态对象来避免这种情况。
let
vs. var
, per se - it's about scope in general. 这个问题实际上与let
vs. var
无关 - 它本身就是范围。 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. 因此,在您的情况下,您不需要Global变量来实现在每次函数调用时不重新声明变量的目标。 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" : 由于所有代码都应该首先保留在Global范围之外,因此您的代码应该至少有一个子范围,这通常通过立即调用的函数表达式实现,该表达式创建“模块模式” :
(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). 不,你不应该创建一个全局变量(而不是与let
反正)。
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模块到IIFE到简单的块范围。
// 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`
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.