[英]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.