JavaScript >> Javascript 文檔 >  >> JavaScript

JavaScript 和最佳實踐中 var、let 和 const 之間的區別

簡介

編程一直包括數據的定義、數據的操作,最後是數據的顯示。數據可以表示為 我們可以在計算機程序中更改的信息。由於內存位置不是很容易閱讀,並且更改 隨著時間的推移 - 我們已經開始註釋變量 數據,帶有人類可讀的符號,我們可以調用,間接指向內存中的數據。

變量本質上是指針參考 到機器內存中的某些數據,並且可以動態更改指針以反映我們“標記”的數據的真實狀態。

注意: 通俗地說,“變量存儲數據” 並且它們是“數據容器” .這在技術上是不正確的,並且源於模糊的語義邊界 - 不清楚人們是否引用了 reference variables 內存中的對象 . (參考)變量是指針 ,並且他們指向 機器內存中的對象 - 存儲數據的位置。通俗的術語很常見,您會發現它們出現在文檔中,但值得至少將對象內存分配保留在您的腦海中。

ES2015 (ES6) 發布之前 , JavaScript 變量僅使用 var 聲明 關鍵詞;然而,隨著 ES6 的引入,聲明變量的新方法,letconst , 介紹了。這經常會帶來一些問題——主要是關於應該使用哪個關鍵字,以及何時:

var english = "Hello there!";
let french = "Bonjour!";
const german = "Hallo!";

什麼是 JavaScript 中的作用域?

範圍 為了在大多數編程語言中編寫代碼,要掌握一個重要的概念,並且在選擇要使用的變量關鍵字時起著重要的作用。範圍定義變量的可用性 .在 JavaScript 中,我們有兩個作用域:global本地 .

  • 全球範圍: 在任何代碼塊之外聲明的變量 或功能 被稱為全局變量,因為它們具有全局範圍 ,並且可以從任何函數或塊中引用。

注意: 在一個 JavaScript 文檔中,只有一個 全局範圍 存在。

假設您有一個腳本文件。同樣,在任何函數或塊之外聲明的任何變量都是全局範圍的:

// Initialized outside of function or block
var name = "John Doe";
function logName() {
  console.log(name);
};
    
logName();

在上面的例子中,name 可在 logName() 內訪問 函數,因為它具有全局範圍。它存在於應用程序的上下文中,而 logName() 函數可以調用該上下文!

  • 本地範圍: 在任何代碼塊中聲明的變量 或功能 被稱為局部變量,因為它們具有局部範圍 .它們只能在定義它們的代碼塊或函數中被引用 .
function logName() {
  // Initialized within a function or block
  var name = "John Doe";
  var id = 1;
  console.log(name);
};
    
function logId() {
  console.log(id);
}
    
logId();

這導致:

error: Uncaught ReferenceError: id is not defined

怎麼來的? id 已定義 - 但未在 範圍 中定義 logId() 功能。就功能而言 - 沒有 id 存在。它首先檢查是否存在 本地範圍的變量 .由於沒有,它檢查是否有一個全局範圍的變量 .如果不是 - id 不是從 logId() 的上下文中定義的 !

有了入門/提醒 - 讓我們看看 var , letconst 取決於範圍,以及何時應該使用每個!

var JavaScript 中的關鍵字

在 JavaScript 中,var 是一個保留關鍵字,後跟一個引用變量名。在關鍵字之後定義的名稱可以用作內存中數據的指針。

使用 var變量聲明最古老的方法 在 JavaScript 中。讓我們聲明一個變量並初始化它 通過使用賦值運算符(= ):

// Declaration and initialization
var name = "John Doe";

或者,您可以將其分解為兩個步驟 - 變量 聲明 (它是什麼)和變量初始化 (給它賦值):

// Declaration
var name;
// Initialization
name = "John Doe";

注意: 在 Java 等強類型語言中,很長一段時間以來,您都會定義 type 聲明期間的變量 ,以及在初始化期間 ,您只能分配適合該類型的值。從 Java 10 - var 添加了關鍵字,它與類型無關,並在運行時推斷類型。

var 的範圍

在函數中定義時 - 任何 var 僅限於該功能。在函數外部定義時,var 是全球性的:

免費電子書:Git Essentials

查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!

  var firstName = "John";
  
  function checkLastName() {
    var lastName = "Doe";
  }

我們在前面的例子中有兩個聲明:firstName 是全局作用域的,因為它是在函數外部定義的,並且 lastName 是本地/函數範圍的,因為它是在函數中定義的:

var firstName = "John";
  
function checkLastName() {
    var lastName = "Doe";
    console.log(lastName); // "Doe"
    console.log(firstName); // "John"
}
  
checkLastName();
console.log(lastName); // Uncaught ReferenceError: lastName is not defined

到目前為止,一切都很好。但是 - var 有問題。

var 的問題

var 不是塊作用域。 在代碼塊中聲明變量時,使用大括號 ({} ),它的作用域“流出”了塊!例如:

var name = "John Doe";
  
var someBool = true;
if (someBool) {
  var name = "Daniel Joan";
}
  
console.log(name);

name 指向“John Doe”是全局的,而 name 指向“Daniel Joan”的那個是在一個塊中定義的。但是,當我們嘗試打印 name 在範圍內,我們遇到:

Daniel Joan

使用 var 聲明變量 正如我們在代碼片段中看到的那樣,代碼中任何地方的聲明都可能導致混淆、覆蓋現有全局變量和擴展 - 錯誤。

這是 letconst 開始吧!

JavaScript 中的關鍵字

let 聲明是在 ES6 中引入的,此後成為變量聲明的首選方法。它被認為是對 var 的改進 聲明和 塊範圍(只能在直接塊中訪問的變量),規避使用 var 可能出現的主要問題 .

let 的範圍

使用 let 定義的變量 關鍵字的作用域僅限於定義它的塊或函數:

let firstName = "John";
let lastName = "Doe";

let someBool = true;
if(someBool){
    let firstName = "Jane";
    console.log(firstName);
}
  
console.log(firstName);

這一次 - firstName 指“簡”和firstName 指“約翰”不要重疊!代碼結果:

Jane
John

firstName 在塊內聲明的僅限於範圍內的塊,在塊外聲明的塊是全局可用的。 firstName 的兩個實例 被視為不同的變量引用,因為它們具有不同的作用域。

const JavaScript 中的關鍵字

const 聲明是在 ES6 中引入的,與 let 一起 , 和 let 非常相似 . const 顧名思義,指向內存中保存常量值的數據。 const 引用變量不能重新分配給內存中的不同對象:

const name = "John";
const name = "Jane";

這導致:

Uncaught SyntaxError: Identifier 'name' has already been declared

const的範圍

const 定義的變量範圍 關鍵字,如 let 的範圍 聲明,僅限於由花括號(函數或塊)定義的塊。主要區別是它們不能被更新或重新聲明,意味著值在範圍內保持不變:

const name = "John";
name = "Doe";
  
// Uncaught TypeError: Assignment to constant variable. 

良好的編碼約定

那麼,除了避免錯誤的明顯要求之外,這一切意味著什麼,您應該選擇哪個?這實際上可以歸結為幾個好的做法:

  • const 優於 let , 優於 var .避免使用 var .
  • let 優於 const 當知道它所指向的值會隨時間變化時。
  • const 非常適合全局常量值。
  • 庫通常導入為 const .

導入庫並將其實例化時 - 您不希望能夠將實例重新分配給其他東西,因為您會輸入“使用庫”的滑坡,而其他東西是“滑入代碼”下引擎蓋。

例如,如果您要 require() 像 Axios 這樣的庫,你肯定想使用它的 API。但是,沒有什麼可以阻止您(或其他人)切換出 axios 用別的東西實例 如果你還沒有使用過 const 聲明它:

let axios = require('axios');
axios.get('some_url').then(someFunction());

axios = "Totally not a string!"
axios.get('some_url').then(someFunction()); // String has no method `get()`

通過擁有 axiosconst - 避免了這個問題。另外,還可以定義全局常量,作為配置常量使用:

const WIDTH = 1920;
const HEIGHT = 1080;

結論

在本指南中,我們從最初的 var 探索了 JavaScript 中變量聲明的進展 到較新的 letconst .

我們已經探索了 JavaScript 中的作用域以及不同的聲明符號如何影響代碼中變量的作用域,注意到使用 var 的一個明顯問題 .最後,我們探討了一些好的做法,注意何時使用哪個關鍵字。


Tutorial JavaScript 教程
  1. 如何在 React 中使用腳本標籤?

  2. 了解如何在 JavaScript 中使用 map、filter 和 reduce。

  3. TC39 第 85 次會議的更新

  4. 在 JSS 集成模式下使用 Connected GraphQL 時出現證書錯誤

  5. 關於 HTTP cookie 的實用完整教程

  6. 限制摩納哥編輯器中的可編輯區域

  7. 使用 Redux Toolkit 設置 Redux

  1. 為什麼選擇無服務器?

  2. .click() 隱藏輸入按鈕不起作用(未定義)

  3. CSS - 帶有過渡屬性的動畫示例

  4. 你更喜歡苗條還是反應?

  5. 0.85 後讓 Flow 快樂

  6. 通過 Formik 表單發送驗證錯誤

  7. Discord.js 機器人的絕妙禁令命令

  1. 如何使 webpack 構建速度更快並輸出更小的包

  2. 設計 NativeBase 3.0:架構和未來

  3. 10本書編程初學者

  4. 在 Vue 中使用 GSAP 進行補間