[英]Should I declare a variable using LET globally for a function that runs constantly?
这里最相关的答案不是指let ,它是块作用域,而是指var ,它被挂起。 我似乎无法得到明确的答案。
我有一个全局声明的变量初始化一次:
let firePaused = false;
然后每次按下按钮时运行的键盘处理程序中的一个函数:
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;
}
}
}
(与问题无关,但它的目的是只允许玩家射击一次,在他们再次射击之前需要有一个keyup事件)
根据清洁代码的规则,我应该在函数顶部声明变量...但这意味着每次按下按钮都会重新声明它。
它在这里说https://www.sitepoint.com/how-to-declare-variables-javascript/
初始化:声明变量时,它会自动初始化,这意味着JavaScript引擎会为变量分配内存。
因此,每次使用let关键字时,我都会创建一个全新的变量。
我是否应该在函数开始时编写一个条件来检查是否已声明firePaused
,如果没有声明它? 这似乎完全矫枉过正。
如果您的变量在全局范围内声明,那么使用let
或var
并不重要。
这些在功能上是相同的:
let myVar = 123; function doStuff() { console.log(myVar); } doStuff();
var myVar = 123; function doStuff() { console.log(myVar); } doStuff();
当你在块中声明它们时, var
和let
之间的区别变得很重要:
if(true) { var foo = 1; } if(true) { let bar = 2; } console.log("var foo:", foo); console.log("let bar:", bar);
如您所见, let
声明仅限于其包装块范围。 var
声明忽略块范围。
看起来您正试图在多个位置维护角色(英雄)状态。 由于每个角色的动作/状态将添加到全局变量,因此在全局范围内维护将变得越来越困难。
根据@ jeff-huijsmans的建议,我相信你应该保持game
对象中的状态。
这可以通过以下几种方式定义:
game.state.firePaused
- 这会将你的游戏状态锁定为单个角色,但最好包含角色射击的状态。 game.hero.firePaused
- 这允许每个角色保持自己的射击状态。 这还有一个额外的好处,就是能够在触发状态下添加更多字符。 顺便说一句,看起来这里的大多数答案都试图解决范围问题。 全局定义变量并尝试维持函数之外的状态变得非常难以理解/读取/测试。 关于这个话题会有很多意见。 幸运的是,对于根本问题,您可以通过使用预先存在的状态对象来避免这种情况。
let
vs. var
无关 - 它本身就是范围。 应该在保持程序功能的最小范围内声明变量。 全局变量应该是最后的手段。
因此,在您的情况下,您不需要Global变量来实现在每次函数调用时不重新声明变量的目标。 您只需要创建另一个范围。 由于所有代码都应该首先保留在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;
}
}
}
})();
不,你不应该创建一个全局变量(而不是与let
反正)。
是的,如果要在调用之间共享它,则应在函数外部声明它。
您可以使用任何类型的模块模式 - 从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.