首頁 web前端 js教程 深入理解JavaScript中的變數、範圍和提升

深入理解JavaScript中的變數、範圍和提升

Nov 25, 2019 pm 02:39 PM
javascript 變數 提升 範圍

變數是許多程式語言的基本組成部分,也是新手需要學習的第一個也是最重要的概念。 JavaScript中有許多不同的變數屬性,以及命名變數時必須遵循的一些規則。在JavaScript中,有三個關鍵字用於聲明變數——var、let和const——每個關鍵字都會影響程式碼對變數的不同解釋。

深入理解JavaScript中的變數、範圍和提升

本教學將介紹什麼是變量,如何宣告和命名變量,並進一步研究var、let和const之間的差異。我們也將回顧提升的影響以及全域和局部作用域對變數行為的重要性。 【相關課程推薦:JavaScript影片教學

理解變數

#變數是用來儲存值的命名容器。我們可能多次引用的一條資訊可以儲存在一個變數中,以供日後使用或修改。在JavaScript中,變數中包含的值可以是任何JavaScript資料類型,包括數字、字串或物件。

在今天的JavaScript所基於的ECMAScript 2015 (ES6)語言規格之前,只有一種方法來宣告變數-使用var關鍵字。因此,大多數較老的程式碼和學習資源將只對變數使用var。我們將在下面單獨一節討論var、let和const關鍵字之間的差異。

我們可以使用var來示範變數本身的概念。在下面的範例中,我們將聲明一個變量,並為其賦值。

// Assign the string value Sammy to the username identifier
var username = "sammy_shark";
登入後複製

本聲明由以下幾部分組成:

  • 使用var關鍵字聲明變數

  • 變數名(或標識符),使用者名稱

  • 賦值操作,由=語法表示

  • 指派的值「sammy_shark」

現在我們可以在程式碼中使用username。 JavaScript將記住username表示字串值sammy_shark。

// Check if variable is equal to value
if (username === "sammy_shark") {
  console.log(true);
  }
登入後複製

輸出:

true
登入後複製
登入後複製

如前所述,變數可以用來表示任何JavaScript資料型別。在本例中,我們將使用字串、數字、物件、布林值和null值宣告變數。

// Assignment of various variables
var name = "Sammy";
var spartans = 300;
var kingdoms = [ "mammals", "birds", "fish" ];
var poem = { roses: "red", violets: "blue" }; 
var success = true;
var nothing = null;
登入後複製

使用console.log,我們可以看到特定變數中包含的值。

// Send spartans variable to the console
console.log(spartans);
登入後複製

輸出:300

變數將資料儲存在記憶體中,稍後可以存取和修改這些資料。變數也可以重新分配,並給定一個新值。下面的簡化範例示範如何將密碼儲存到變數中,然後進行更新。

//为password变量赋值
var password = "hunter2";
//用一个新值重新分配变量值
password = "hunter3";
console.log(password);
登入後複製

輸出:

'hunter3'
登入後複製

在實際的程式中,密碼很可能安全地儲存在資料庫中。然而,這個例子說明了一種情況,在這種情況下,我們可能需要更新變數的值。 password的值是hunter2,但我們將其重新指派給了hunter3,這是JavaScript從那時起可以辨識的值。

命名變數

變數名稱在JavaScript中稱為識別碼。我們討論了在理解JavaScript語法和程式碼結構時命名標識符的一些規則,總結如下:

  • #變數名稱只能由字母(a-z)、數字(0-9)、美元符號($)和底線(_)組成

  • 變數名稱不能包含任何空白字元(製表符或空格)

  • 數字不能是任何變數的名稱開頭

  • 保留的關鍵字不能用作變數的名稱

  • ##變數名稱區分大小寫

#JavaScript也習慣在使用var或let宣告的函數和變數的名稱中使用駝峰大小寫(有時會作為駝峰大小寫進行樣式化)。這是一種將第一個單字小寫,然後將後面每個單字的第一個字母大寫,中間沒有空格的做法。除了一些例外,大多數非常量的變數都遵循這種約定。使用const關鍵字宣告的常數變數的名稱通常都是大寫的。

這可能看起來像是要學習很多規則,但很快就會成為編寫有效和常規變數名稱的第二天性。

var、let和const之間的區別

JavaScript有三個不同的關鍵字來聲明變量,這給語言增加了額外的複雜性。三者之間的差異是基於範圍、提升和重新分配。

關鍵字
範圍變數提升可以重新分配可以重新定義
var功能範圍YesYesYes
let阻止範圍NoYes#No
const 阻止範圍NoNoNo
#

您可能想知道应该在自己的程序中使用这三种方法中的哪一种。一个普遍接受的做法是尽可能多地使用const,并在循环和重新分配的情况下使用let。通常,在处理遗留代码之外可以避免var。

变量作用域

JavaScript中的作用域是指代码的当前上下文,它决定了变量对JavaScript的可访问性。范围的两种类型是局部的和全局的:

  • 全局变量是在块之外声明的变量

  • 局部变量是在块内声明的变量

在下面的示例中,我们将创建一个全局变量。

//初始化一个全局变量
var creature = "wolf";
登入後複製

我们知道变量可以重新分配。使用局部作用域,我们实际上可以创建与外部作用域中的变量同名的新变量,而无需更改或重新分配原始值。

在下面的示例中,我们将创建一个全局species变量。函数内部是一个具有相同名称的局部变量。通过将它们发送到控制台,我们可以看到变量的值如何根据范围而不同,并且原始值不会更改。

//初始化一个全局变量
var species = "human";
function transform() {
//初始化一个局部的、函数作用域的变量
  var species = "werewolf";
  console.log(species);
}
//记录全局和局部变量
console.log(species);
transform();
console.log(species);
登入後複製

输出:

human
werewolf
human
登入後複製

在本例中,局部变量是函数作用域的。使用var关键字声明的变量总是函数作用域,这意味着它们将函数识别为具有独立作用域。因此,这个局部作用域的变量不能从全局作用域访问。

然而,新的关键字let和const是块范围的。这意味着从任何类型的块(包括函数块、if语句、for和while循环)创建一个新的本地范围。

为了说明函数作用域变量和块作用域变量之间的区别,我们将使用let在if块中分配一个新变量。

var fullMoon = true;
//初始化一个全局变量
let species = "human";
if (fullMoon) { 
//初始化一个块范围的变量
  let species = "werewolf";
  console.log(`It is a full moon. Lupin is currently a ${species}.`);
}
console.log(`It is not a full moon. Lupin is currently a ${species}.`);
登入後複製

输出:

It is a full moon. Lupin is currently a werewolf.
It is not a full moon. Lupin is currently a human.
登入後複製

在此示例中,species变量具有一个值global(human),另一个值local(werewolf)。var但是,如果我们使用,则会有不同的结果。

//使用var初始化一个变量
var species = "human";
if (fullMoon) {  
//尝试在一个块中创建一个新变量
  var species = "werewolf";
  console.log(`It is a full moon. Lupin is currently a ${species}.`);
}

console.log(`It is not a full moon. Lupin is currently a ${species}.`);
登入後複製

输出:

It is a full moon. Lupin is currently a werewolf.
It is not a full moon. Lupin is currently a werewolf.
登入後複製

在这个例子的结果中,全局变量和块范围的变量都以相同的值结束。这是因为您不是使用var创建一个新的本地变量,而是在相同的范围内重新分配相同的变量。var不能识别是否属于不同的新范围。通常建议声明块范围的变量,因为它们生成的代码不太可能无意中覆盖变量值。

变量提升

到目前为止,在大多数示例中,我们已经使用var声明了一个变量,并使用一个值初始化了它。在声明和初始化之后,我们可以访问或重新分配变量。

如果我们试图在变量被声明和初始化之前使用它,它将返回undefined。

//在声明变量之前尝试使用它
console.log(x);
/ /变量赋值
var x = 100;
登入後複製

输出:

undefined
登入後複製
登入後複製

但是,如果省略var关键字,就不再声明变量,而是初始化它。它将返回一个ReferenceError并停止脚本的执行。

//在声明变量之前尝试使用它
console.log(x);
//没有var的变量赋值
x = 100;
登入後複製

输出:

ReferenceError: x is not defined
登入後複製

原因在于提升,这是JavaScript的一种行为,其中变量和函数声明被移到它们作用域的顶部。由于只挂起实际声明,而没有初始化,因此第一个示例中的值返回未定义的值。

为了更清楚地演示这个概念,下面是我们编写的代码以及JavaScript如何解释它。

// The code we wrote
console.log(x);
var x = 100;
// How JavaScript interpreted it
var x;
console.log(x);
x = 100;
登入後複製

JavaScript在执行脚本之前将x保存为内存作为变量。 由于它在定义之前仍然被调用,因此结果是未定义的而不是100.但是,它不会导致ReferenceError并停止脚本。

尽管var关键字实际上并未更改var的位置,但这有助于表示提升的工作原理。 但是,这种行为可能会导致问题,因为编写此代码的程序员可能希望x的输出为true,而不是undefined。

在下一个例子中,我们还可以看到提升是如何导致不可预测的结果的:

//在全局范围内初始化x
var x = 100;
function hoist() {
//不应影响编码结果的条件
  if (false) {
      var x = 200;
  }
  console.log(x);
}

hoist();
登入後複製

输出:

undefined
登入後複製
登入後複製

在本例中,我们声明x全局为100。根据if语句,x可以更改为200,但是由于条件为false,所以它不应该影响x的值。

这种不可预测的行为可能会在程序中引起bug。由于let和const是块范围的,所以它们不会以这种方式提升,如下所示。

//在全局范围内初始化x
let x = true;function hoist() {
//在函数作用域中初始化x
 if (3 === 4) {
      let x = false;
  }
  console.log(x);
}

hoist();
登入後複製

输出:

true
登入後複製
登入後複製

变量的重复声明(这在var中是可能的)将在let和const中抛出一个错误。

//试图覆盖用var声明的变量
var x = 1;
var x = 2;

console.log(x);
登入後複製

输出:2

//试图覆盖用let声明的变量
let y = 1;
let y = 2;

console.log(y);
登入後複製

输出:

Uncaught SyntaxError: Identifier 'y' has already been declared
登入後複製

总之,使用var引入的变量有可能受到提升的影响,提升是JavaScript中的一种机制,其中变量声明被保存到内存中。这可能导致代码中出现未定义的变量。let和const的引入解决了这个问题,它在试图在声明变量之前使用该变量或多次声明该变量时抛出一个错误。

常量

许多编程语言都有常量,这些常量是不能修改或更改的值。在JavaScript中,const标识符是根据常量建模的,不能重新分配分配给const的值。

将所有const标识符都写成大写是常见的约定。这将它们与其他变量值区分开来。

在下面的示例中,我们使用const关键字将变量SPECIES初始化为常量。试图重新分配变量将导致错误。

//给const赋值
const SPECIES = "human"; 

//尝试重新分配值
SPECIES = "werewolf";

console.log(SPECIES);
登入後複製

输出:

Uncaught TypeError: Assignment to constant variable.
登入後複製

因为不能重新分配const值,所以需要同时声明和初始化它们,否则也会抛出错误。

//声明,但不初始化const
const TODO;

console.log(TODO);
登入後複製

输出:

Uncaught SyntaxError: Missing initializer in const declaration
登入後複製

不能在编程中更改的值称为不可变值,而可以更改的值是可变的。虽然const值不能重新分配,但是它们是可变的,因为可以修改用const声明的对象的属性。

//创建一个具有两个属性的CAR对象
const CAR = {
    color: "blue",
    price: 15000}
//修改CAR的属性
CAR.price = 20000;

console.log(CAR);
登入後複製

输出:

{ color: 'blue', price: 20000 }
登入後複製

常量非常有用,可以让将来的自己和其他程序员清楚地认识到,不应该重新分配预期的变量。如果您希望将来修改某个变量,那么您可能希望使用let来声明该变量。

本文来自 js教程 栏目,欢迎学习!

以上是深入理解JavaScript中的變數、範圍和提升的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

戀與深空暴擊率怎麼提升 戀與深空暴擊率怎麼提升 Mar 23, 2024 pm 01:31 PM

戀與深空中人物有著各方面的數值屬性,遊戲內的每一種屬性都有其特定的作用,而暴擊率這一屬性就會影響到角色的傷害,可以說是一項很重要的屬性了,而下面要帶來的就是這屬性的提升方法了,所以想知道的玩家就可以來看看了。戀與深空暴擊率提升方法一、核心方法要想達到80%的暴擊率,關鍵在於你手中的六張卡的爆擊屬性總和。日冕卡的選擇:選擇兩張日冕卡時,確保它們的芯核α和芯核β副屬性詞條中至少有一條是暴擊屬性。月冕卡的優勢:月冕卡不僅基礎屬性中包含暴擊,而且當它們達到60級且未突破時,每張卡可以提供4.1%的暴

Python 語法的心智圖:深入理解程式碼結構 Python 語法的心智圖:深入理解程式碼結構 Feb 21, 2024 am 09:00 AM

python憑藉其簡單易讀的語法,廣泛應用於廣泛的領域。掌握Python語法的基礎架構至關重要,既可以提高程式效率,又能深入理解程式碼的運作方式。為此,本文提供了一個全面的心智圖,詳細闡述了Python語法的各個面向。變數和資料類型變數是Python中用於儲存資料的容器。心智圖展示了常見的Python資料類型,包括整數、浮點數、字串、布林值和列表。每個資料類型都有其自身的特性和操作方法。運算符運算符用於對資料類型執行各種操作。心智圖涵蓋了Python中的不同運算子類型,例如算術運算子、比

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

如何使用Ajax從PHP方法取得變數? 如何使用Ajax從PHP方法取得變數? Mar 09, 2024 pm 05:36 PM

使用Ajax從PHP方法取得變數是Web開發中常見的場景,透過Ajax可以實作頁面無需刷新即可動態取得資料。在本文中,將介紹如何使用Ajax從PHP方法中取得變量,並提供具體的程式碼範例。首先,我們需要寫一個PHP檔案來處理Ajax請求,並傳回所需的變數。下面是一個簡單的PHP檔案getData.php的範例程式碼:

什麼是Java中的實例變數 什麼是Java中的實例變數 Feb 19, 2024 pm 07:55 PM

Java中的實例變數是指定義在類別中,而不是方法或建構子中的變數。實例變數也稱為成員變量,每個類別的實例都有自己的一份實例變數副本。實例變數在創建物件的過程中被初始化,以及在物件的生命週期中保存並保持其狀態。實例變數的定義通常放在類別的頂部,可以用任何存取修飾符來聲明,可以是public、private、protected或預設存取修飾符。這取決於我們希望這個變

深入理解C語言中的const 深入理解C語言中的const Feb 18, 2024 pm 12:56 PM

C中const的詳解及程式碼範例在C語言中,const關鍵字用來定義常數,表示該變數的值在程式執行過程中不能被修改。 const關鍵字可以用來修飾變數、函數參數、函數傳回值。本文將對C語言中const關鍵字的使用進行詳細解析,並提供具體的程式碼範例。 const修飾變數當const用來修飾變數時,表示變數為唯讀變量,一旦賦值就無法再修改。例如:constint

jQuery使用實踐:判斷變數是否為空的幾種方式 jQuery使用實踐:判斷變數是否為空的幾種方式 Feb 27, 2024 pm 04:12 PM

jQuery是一個廣泛應用於Web開發中的JavaScript庫,它提供了許多簡潔方便的方法來操作網頁元素和處理事件。在實際開發中,常會遇到需要判斷變數是否為空的情況。本文將介紹使用jQuery判斷變數是否為空的幾種常用方法,並附上具體的程式碼範例。方法一:使用if語句判斷varstr="";if(str){co

如何在JavaScript中取得HTTP狀態碼的簡單方法 如何在JavaScript中取得HTTP狀態碼的簡單方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP狀態碼取得方法簡介:在進行前端開發中,我們常常需要處理與後端介面的交互,而HTTP狀態碼就是其中非常重要的一部分。了解並取得HTTP狀態碼有助於我們更好地處理介面傳回的資料。本文將介紹使用JavaScript取得HTTP狀態碼的方法,並提供具體程式碼範例。一、什麼是HTTP狀態碼HTTP狀態碼是指當瀏覽器向伺服器發起請求時,服務

See all articles