ES6語法:var、let、const的區別詳解

来源:https://www.cnblogs.com/swzx-1213/archive/2020/03/12/12468786.html
-Advertisement-
Play Games

今天來說說es6的語法,最基礎的也就是var,let,const 的用法與區別了,我們來看看他們之間的恩怨情仇。 首先來說說var,這個只要是學過js的都知道,它是用來聲明一個變數的,但是它在開發中也會遇到一些問題,比較難解決。先來看看下麵的代碼: var str="hello world"; ​ ...


今天來說說es6的語法,最基礎的也就是var,let,const 的用法與區別了,我們來看看他們之間的恩怨情仇。
首先來說說var,這個只要是學過js的都知道,它是用來聲明一個變數的,但是它在開發中也會遇到一些問題,比較難解決。先來看看下麵的代碼:

 

var str="hello world";
​
function testVar(){
  var str="hello";
}
testVar();
console.log(str);

這段代碼的結果是 "hello world",這說明在var 申明的變數,即使是同樣的名字,在不同的塊中,在外層塊中的變數優先順序更高,也就是說,在外層優先使用並且只能使用當前塊中的變數;而在他的內部塊中的變數,比如說這個函數裡面的str,他其實也是優先使用塊內的str變數,會屏蔽掉外面的str變數,這是一點。再來看看下麵一段代碼

function variableHoisting(){
  if(condition){
    var test="hello javaScript";
  }else{
    console.log(test)
    //這裡可以訪問到test,但是它是undefined,因為初始化為它賦值成了undefined
  }
  //這裡也可以訪問到test
}

可能你會感到奇怪,我的var 申明的變數在if 代碼塊裡面,為什麼我的else裡面也能訪問呢,其實上面這段代碼相當於下麵這段代碼

 

function variableHoisting(){
  var test;
  if(condition){
    test="hello javaScript";
  }else{
    console.log(test)
    //這裡可以訪問到test,但是它是undefined,因為初始化為它賦值成了undefined
  }
    //這裡也可以訪問到test
}

現在知道了吧?這就是所謂的變數提升,我在if裡面申明的變數,其實瀏覽器在預解析的時候就對var ,以及function關鍵字的變數或者方法進行了處理,處理後的代碼就是上面這段代碼(當然,我之前講過一篇函數聲明與函數表達式的區別,你可以看看,你會知道更多。)看到這裡,也許你不會感覺var 有什麼不好的地方,再往下看看:

```javascript

var funcs = [];
for (var i = 0; i < 10; i++) {
  funcs.push(function() {
    console.log(i); 
  });
}
funcs.forEach(function(func) {
  func(); // 輸出數值 "10" 十次
});

可能你想的是輸出0,1,2,3,4,5,6,7,8,9但是這不是正確答案,這隻能輸出10個10,為什麼呢?因為迴圈完成過後,i已經是10了,再次調用的時候,這個i值在每次迭代過程中共用了。
下麵我們就來引入一下let,以及const。let 也是用來申明變數的,但是他申明的變數是塊級作用域,什麼意思呢,看下麵

function testLet(){
  if(condition){
    let str="hello let"
  }else{
    //這裡訪問不到str 
  }
    //這裡也訪問不到str
}

 



看了上面,你也許就知道了什麼是塊級作用域,也就是一個大括弧嘛,括弧裡面就是一塊。用let申明的變數是沒有之前所說的變數提升這一說的,所以在外部塊裡面是訪問不到let申明的變數的。這樣,之前說var缺陷的哪一塊代碼經過小小的改變就能正常輸出0..9了,你看看

var funcs = [];
for (let i = 0; i < 10; i++) {
    funcs.push(function () {
        console.log(i);
    });
}
funcs.forEach(function (func) {
    func(); // 輸出數值 0-9
});    

 

這就是let,與var的一個小區別,當然如果說你申明變數的時候不指名是用的var,還是let,編譯的時候會將這個變數解析為var申明的變數。

不管是var,還是let,他們是不能重覆申明的,比如像下麵這樣

var str="var";
let str="let";

這樣是會報錯的,編譯的時候,不能重覆定義。

然後就是const了,這個其實就是常量的單詞的英文縮寫(constant),沒錯,這是用來申明一個常量的。什麼事常量呢,顧名思義,就是一旦賦值就不能再改變了。比如說:

 

const MAX=3.1415926;
MAX=3.14;

 

這樣是不行的,會報錯,常量不能改變的。來看看const的迴圈,在最基礎的for -i的迴圈裡面,他是會報錯的,運行一次過後就會報錯,但是在for-in 迴圈裡面他是不會報錯的,當然在for-of迴圈裡面也不會

 

var funcs = [],
object = {
  a: true,
  b: true,
  c: true
};
// 不會導致錯誤
for (const key in object) {
  funcs.push(function () {
  console.log(key);
  });
}
funcs.forEach(function (func) {
  func(); // 依次輸出 "a"、 "b"、 "c"
});

 

這樣是不會報錯的,來看看究竟是為什麼呢?

上面說了,const申明的變數是不能改變的,但是,我們試試申明一個對象呢,然後改變對象裡面的屬性的值。

 

const object={
name:"學習筆記",
age:18
}
console.log(object.name)
​
object.name="hello world"
console.log(object.name)

 

這段代碼,第一個會列印出來“學習筆記”,第二個會列印出來“hello world”,為什麼呢?原因在這,其實,這段代碼改變的不是object這個對象變數,而是這個變數的屬性,知道了這個就不難理解為什麼在for-in ,for-of迴圈裡面,const不會報錯了吧?如果對你有幫助的話,記得點個關註哦,如果你發現文中有錯誤,記得幫我指出來。

微信公眾號


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 註意:無特殊說明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 ClipRect ClipRect組件使用矩形裁剪子組件,通常情況下,ClipRect作用於 、 、 、 、 、 、 組件,例如ClipRect作用於Alig ...
  • 教程/Articles 1. "說說 Flutter 中最熟悉的陌生人 —— Key" 插件/Librarys 1. "dna" 一個 flutter plugin. 輕量級的Dart到Native的超級通道,可直接在dart代碼中調用原生代碼,目前支持安卓 JAVA 和 iOS ObjC. 1. ...
  • 按照國際慣例,先放效果圖 1、js動態初始化Dom結構 首先在index.html中添加基本樣式 body{background:pink;text-align: center;} 加個移動端meta頭 <meta name="viewport" content="width=device-widt ...
  • 瀏覽器首碼: css3屬性:預覽版,還沒有最終版,所以有很多相容性問題,瀏覽器不識別。 瀏覽器為了使這些屬性相容,每個瀏覽器廠商都提供了一個屬於自己瀏覽器的語法規則,瀏覽器相容首碼。 主流瀏覽器:谷歌,IE,歐朋,火狐,蘋果 瀏覽器首碼: -wekit- 谷歌 -moz- 火狐 -ms- IE -o ...
  • 閉包的定義:閉包是指有權訪問另一個函數作用域中的變數的函數 --《JavaScript 高級程式設計》。 如何理解這句話:其實就是指在函數a外面能夠訪問函數a裡面的函數b。 例如: 1 function a () { 2 var v = 123; 3 function b() { 4 console ...
  • Lodash是一個一致性、模塊化、高性能的 JavaScript 實用工具庫。 Lodash 通過降低 array、number、objects、string 等等的使用難度從而讓 JavaScript 變得更簡單。Lodash 的模塊化方法 非常適用於: 遍歷 array、object 和 str ...
  • Node.js Net 模塊提供了一些用於底層的網路通信的小工具,包含了創建伺服器/客戶端的方法 server.js var net = require("net"); var server=net.createServer(function(connection){ console.log("客戶 ...
  • 廢話不多說,直接聊乾貨。 關鍵詞“零基礎”和“迅速”,針對這兩個詞,我們就應該相應的學習規劃。首先你是一個零基礎的人,現在急需把web前端相關技能學好,在“保證學習質量”的同時用最短的時間學好web前端應該掌握的必要技術。 具體實行方案如下: 1.瞭解web前端市場需求 首先,零基礎的人應該去瞭解目 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...