ES6的介紹和常用語法

来源:https://www.cnblogs.com/smyhvae/archive/2018/03/04/8506152.html
-Advertisement-
Play Games

本文最初發表於 "博客園" ,併在 "GitHub" 上持續更新 前端的系列文章 。歡迎在GitHub上關註我,一起入門和進階前端。 以下是正文。 前言 ECMAScript 是 JS 的語言標準。而 ES6 是新的 JS 語法標準。 PS:嚴格來說,ECMAScript 還包括其他很多語言的語言標 ...


本文最初發表於博客園,併在GitHub上持續更新前端的系列文章。歡迎在GitHub上關註我,一起入門和進階前端。

以下是正文。

前言

ECMAScript 是 JS 的語言標準。而 ES6 是新的 JS 語法標準。

PS:嚴格來說,ECMAScript 還包括其他很多語言的語言標準。

ECMAScript 發展歷史

  • 1995年:ECMAScript 誕生。

  • 1997年:ECMAScript 標準確立。

  • 1999年:ES3 出現,與此同時,IE5 風靡一時。

  • 2009年,ES5 出現,例如 foreach、Object.keys、Object.create 和 json 標準。

  • 2015年6月,ES6正式發佈。

ES6 的目標是:讓 JS 語言可以編寫複雜的大型應用程式,成為企業級開發語言。

ES6 的其他優勢

  • 使用 babel 語法轉換器,支持低端瀏覽器。

  • 流行的庫基本都是基於 ES6 構建。 React 預設使用 ES6 標準開發。

ES6的環境配置

掌握 ES6 之後,如果要考慮 ES5 的相容性,可以這樣做:寫 ES6 語法的 js 代碼,然後通過 Babel將 ES6 轉換為 ES5。

但是,在這之前,我們需要配置一下相關的環境。

建立工程目錄

(1)先建立一個空的工程目錄 ES6Demo,併在目錄下建立兩個文件夾 srcdist

  • src:書寫ES6代碼,我們寫的 js 程式都放在這裡。

  • dist:利用 Babel 編譯生成的 ES5 代碼。我們在 HTML 頁面需要引入 dist 里的 js 文件

(2)在 src 里新建文件 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <!-- 我們引入 ES5 中的 js 文件,而不是引入 ES6 中的 js 文件。 -->
    <script src="./dist/index.js"></script>
</head>
<body>

</body>
</html>

註意,上方代碼中,我們引入的是dist目錄下的 js 文件。

然後我們新建文件 src/index.js

let a = 'smyhvae';
const b = 'vitateam';

console.log(a);
console.log(b);

這個文件是一個 ES6語法 的js文件,稍後,我們嘗試把這個 ES6 語法的 js 文件轉化為 ES5 的 js 文件。

PS:我們在寫代碼時,能用單引號儘量用單引號,而不是雙引號,前者在壓縮之後,程式執行會更快。

全局安裝 Babel-cli

(1)初始化項目:

在安裝Babel之前,需要先用 npm init 先初始化我們的項目。打開終端或者通過cmd打開命令行工具,進入項目目錄,輸入如下命令:

    npm init -y

上方代碼中,-y 代表全部預設同意,就不用一次次按回車了(稍後再根據需要,在文件中手動修改)。命令執行完成後,會在項目的根目錄下生成package.json文件:

{
  "name": "es6demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "smyhvae",
  "license": "ISC"
}

PS:VS Code 里打開終端的快捷鍵是:Contol + ~

(2)全局安裝 Babel-cli:

在終端中輸入以下命令:

    npm install -g babel-cli

如果安裝比較慢的話,Mac 下可以使用cnpm進行安裝 ,windows 下可以使用nrm切換到 taobao 的鏡像。

(3)本地安裝 babel-preset-es2015 和 babel-cli:

    npm install --save-dev babel-preset-es2015 babel-cli

安裝完成後,會發現package.json文件,已經多了 devDependencies 選項:

(4)新建.babelrc:

在根目錄下新建文件.babelrc,輸入如下內容:

{
    "presets":[
        "es2015"
    ],
    "plugins":[]
}

(5)開始轉換:

現在,我們應該可以將 ES6 的文件轉化為 ES5 的文件了,命令如下:(此命令略顯複雜)

    babel src/index.js -o dist/index.js

我們可以將上面這個命令進行簡化一下。操作如下:

在文件 package.json 中修改鍵 scripts中的內容:

  "scripts": {
    "build": "babel src/index.js -o dist/index.js"
  },

修改後的效果如下:

目前為止,環境配置好了。以後,我們執行如下命令,即可將src/index.js這個 ES6 文件轉化為 dist/index.js這個 ES5 文件:

    npm run build

我們執行上面的命令之後,會發現, dist目錄下會生成 ES5 的 js 文件:

index.js:

    'use strict';

    var a = 'smyhvae';
    var b = 'vitateam';

    console.log(a);
    console.log(b);

當我們打開網頁後,就可以在瀏覽器的控制台,看到代碼的輸出結果。

接下來,我們講一下 ES6的常見語法。

ES6 的變數聲明

ES6 中新增了 let 和 const 來定義變數:

  • var:,ES5 和 ES6中,定義全局變數(是variable的簡寫)。

  • let:定義局部變數,替代 var。

  • const:定義常量(定義後,不可修改)。

var:全局變數

看下麵的代碼:

    {
        var a = 1;
    }

    console.log(a);   //這裡的 a,指的是 區塊 里的 a

上方代碼是可以輸出結果的,輸出結果為 1。因為 var 是全局聲明的,所以,即使是在區塊里聲明,但仍然在全局起作用。

再來看下麵這段代碼:

    var a = 1;
    {
        var a = 2;
    }

    console.log(a);   //這裡的 a,指的是 區塊 里的 a

上方代碼的輸出結果為 2 ,因為 var 是全局聲明的。

總結:

用 var 定義的全部變數,有時候會污染整個 js 的作用域。

let:局部變數

    var a = 2;
    {
        let a = 3;
    }

    console.log(a);

上方代碼的輸出結果為 2。用 let 聲明的變數,只在局部起作用。

let是防止數據污染,我們來看下麵這個例子:

用 var 聲明變數:(可以列印結果,說明迴圈體外的變數 i 被污染了)

    for (var i = 0; i < 10; i++) {
        console.log('迴圈體中:' + i);
    }

    console.log('迴圈體外:' + i);

用let聲明變數:(不能列印結果)

    for (let i = 0; i < 10; i++) {
        console.log('迴圈體中:' + i);
    }

    console.log('迴圈體外:' + i);

總結:我們要習慣用 let 聲明,減少var聲明帶來的污染全局空間

為了進一步說明 let 不會帶來污染,需要說明的是:當我們定義了let a = 1時,如果我們在同一個作用域內繼續定義let a = 2,是會報錯的。

const:聲明常量

在程式開發中,有些變數是希望聲明後,在業務層就不再發生變化,此時可以用 const 來定義。

舉例:

const name = 'smyhvae';  //定義常量

變數的解構賦值

ES6允許我們,通過數組或者對象的方式,對一組變數進行賦值,這被稱為解構。

解構賦值在實際開發中可以大量減少我們的代碼量,並且讓程式結構更清晰。

數組的解構賦值

舉例:

通常情況下,我們在為一組變數賦值時,一般是這樣寫:

    let a = 0;
    let b = 1;
    let c = 2;

現在我們可以通過數組解構的方式進行賦值:

    let [a, b, c] = [1, 2, 3];

二者的效果是一樣的。

解構的預設值:

在解構賦值時,是允許使用預設值的。舉例如下:

{
    //一個變數時
    let [foo = true] = [];
    console.log(foo); //輸出結果:true
}

{
    //兩個變數時
    let [a, b] = ['生命壹號']   //a 賦值為:生命壹號。b沒有賦值
    console.log(a + ',' + b); //輸出結果:生命壹號,undefined
}


{
    //兩個變數時
    let [a, b = 'smyhvae'] = ['生命壹號']   //a 賦值為:生命壹號。b 採用預設值 smyhvae
    console.log(a + ',' + b); //輸出結果:生命壹號,smyhvae
}

undefinednull的區別:

如果我們在賦值時,採用的是 undefined或者null,那會有什麼區別呢?

{
    let [a, b = 'smyhvae'] = ['生命壹號', undefined]; //b 雖然被賦值為 undefined,但是 b 會採用預設值
    console.log(a + ',' + b); //輸出結果:生命壹號,smyhvae
}

{
    let [a, b = 'smyhvae'] = ['生命壹號', null];  //b 被賦值為 null
    console.log(a + ',' + b); //輸出結果:生命壹號,null
}

上方代碼分析:

  • undefined:相當於什麼都沒有,此時 b 採用預設值。

  • null:相當於有值,但值為 null。

對象的解構賦值

我們同樣可以針對對象,進行結構賦值。

舉例如下:

    let { foo, bar } = { bar: '我是 bar 的值', foo: '我是 foo 的值' };
    console.log(foo + ',' + bar); //輸出結果:我是鍵 foo 的值,我是鍵 bar 的值

上方代碼可以看出,對象的解構與數組的結構,有一個重要的區別:數組的元素是按次序排列的,變數的取值由它的位置決定;而對象的屬性沒有次序,是根據鍵來取值的。

圓括弧的使用

如果變數 foo 在解構之前就已經定義了,此時你再去解構,就會出現問題。下麵是錯誤的代碼,編譯會報錯:

    let foo = 'haha';
    { foo } = { foo: 'smyhvae' };
    console.log(foo);

要解決報錯,只要在解構的語句外邊,加一個圓括弧即可:

    let foo = 'haha';
    ({ foo } = { foo: 'smyhvae' });
    console.log(foo); //輸出結果:smyhvae

字元串結構

字元串也可以解構,這是因為,此時字元串被轉換成了一個類似數組的對象。舉例如下:

const [a, b, c, d] = 'smyhvae';
console.log(a);
console.log(b);
console.log(c);
console.log(d);

console.log(typeof a);  //輸出結果:string

輸出結果:

擴展運算符和 rest 運算符

  • 擴展運算符的格式為...

  • rest運算符的格式為...變數名

擴展運算符

有了ES6,當我們在定義一個方法,但是不確定其參數的個數時,我們就可以用擴展運算符作為參數。

以前,我們在定義方法時,參數要確定個數,如下:(程式會報錯)

    function fn(a, b, c) {
        console.log(a);
        console.log(b);
        console.log(c);
        console.log(d);
    }

    fn(1, 2, 3);

上方代碼中,因為方法的參數是三個,但使用時是用到了四個參數,所以會報錯:

現在,我們有了擴展運算符,就不用擔心報錯的問題了。代碼可以這樣寫:

function fn(...arg) {   //當不確定方法的參數時,可以使用擴展運算符
    console.log(arg[0]);
    console.log(arg[1]);
    console.log(arg[2]);
    console.log(arg[3]);
}

fn(1, 2, 3); //方法中定義了四個參數,但只引用了三個參數,ES6 中並不會報錯。

舉例:數組賦值的問題

我們來分析一段代碼:(將數組 arr1 賦值給 arr2)

    let arr1 = ['www', 'smyhvae', 'com'];
    let arr2 = arr1;          // 將 arr1 賦值給 arr2,其實是讓 arr2 指向 arr1 的記憶體地址
    console.log('arr1:' + arr1);
    console.log('arr2:' + arr2);
    console.log('---------------------');

    arr2.push('你懂得');  //往arr2 里添加一部分內容
    console.log('arr1:' + arr1);
    console.log('arr2:' + arr2);

運行結果:

上方代碼中,我們往往 arr2 里添加了你懂的,卻發現,arr1 里也有這個內容。原因是:let arr2 = arr1;其實是讓 arr2 指向 arr1 的地址。也就是說,二者指向的是同一個記憶體地址。

如果不想讓 arr1 和 arr2 指向同一個記憶體地址,我們可以藉助擴展運算符來做:

    let arr1 = ['www', 'smyhvae', 'com'];
    let arr2 = [...arr1];  //arr2 會重新開闢記憶體地址
    console.log('arr1:' + arr1);
    console.log('arr2:' + arr2);
    console.log('---------------------');

    arr2.push('你懂得');  //往arr2 里添加一部分內容
    console.log('arr1:' + arr1);
    console.log('arr2:' + arr2);

運行結果:

我們明白了這個例子,就可以避免開發中的很多業務邏輯上的 bug。

rest 運算符

rest 在英文中指的是剩餘部分(不是指休息)。我們來舉個例子,理解剩餘部分的含義:

    function fn(first, second, ...arg) {
        console.log(arg.length);
    }

    fn(0, 1, 2, 3, 4, 5, 6);  //調用函數後,輸出結果為 5

上方代碼的輸出結果為 5。 調用fn()時,裡面有七個參數,而arg指的是剩下的部分(因為除去了firtsecond)。

從上方例子中可以看出,rest運算符適用於:知道前面的一部分參數的數量,但對於後面剩餘的參數數量未知的情況。

for ... of 迴圈

ES6 中,如果我們要遍歷一個數組,可以這樣做:

    let arr1 = [1, 2, 3, 4, 5];

    for (let value of arr1) {
        console.log(value);
    }

輸出結果:

for…of 的迴圈可以避免我們開拓記憶體空間,增加代碼運行效率,所以建議大家在以後的工作中使用for…of迴圈。

模板字元串

我們以前讓字元串進行拼接的時候,是這樣做的:(傳統寫法的字元串拼接)

    var name = 'smyhvae';
    var age = '26';
    console.log('name:'+name+',age:'+age);   //傳統寫法

這種寫法,比較繁瑣,而且容易出錯。

現在有了 ES6 語法,字元串拼接可以這樣寫:

    var name = 'smyhvae';
    var age = '26';

    console.log('name:'+name+',age:'+age);   //傳統寫法

    console.log(`name:${name},age:${age}`);  //ES6 寫法

註意,上方代碼中,倒數第二行用的是單引號,最後一行用的是反引號(在tab鍵的上方)。

參考鏈接:

箭頭函數

定義和調用函數:(傳統寫法)

function fn1(a, b) {
    return a + b;
}

console.log(fn1(1, 2));  //輸出結果:3

定義和調用函數:(ES6中的寫法)


    var fn2 = (a, b) => a + b;

    console.log(fn2(1, 2));  //輸出結果:3

上方代碼中,箭頭後面的內容,就相當於 return 的內容。

在箭頭函數中,如果方法體內有兩句話,那就需要在方法體外邊加上{}括弧。如下:

    var fn2 = (a, b) => {
        console.log('haha');
        return a + b;
    };
    console.log(fn2(1, 2));  //輸出結果:3

從上面的箭頭函數中,我們可以很清晰地找到函數名、參數名、方法體。

當然,在 ES6 中定義方法時,我們還可以給方法里的參數加一個預設值(預設值):

  • 方法被調用時,如果沒有給參數賦值,那就是用預設值;

  • 方法被調用時,如果給參數賦值了新的值,那就用新的值。

如下:

    var fn2 = (a, b = 5) => {
        console.log('haha');
        return a + b;
    };
    console.log(fn2(1));     //第二個參數使用預設值 5。輸出結果:6

    console.log(fn2(1, 8));  //輸出結果:9

更多 ES6 的語法,本文會陸續更新。

參考鏈接:

我的公眾號

想學習代碼之外的軟技能?不妨關註我的微信公眾號:生命團隊(id:vitateam)。

掃一掃,你將發現另一個全新的世界,而這將是一場美麗的意外:


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

-Advertisement-
Play Games
更多相關文章
  • adb工具的使用、adb連接設備、adb連接設備失敗的處理、adb常用命令 ...
  • java.net.UnknownHostException 錯誤解決方向 1. 查看是否申明瞭網路的許可權。     在AndroidManifest中需要聲明網路許可權 ···java ··· 註意申明許可權的節點不要弄錯。 2. 測試真機或者模擬機是否連上了網路 ...
  • 報錯如圖 解決 在 路徑下,刪除所有文件夾,重新run android ps:網上搜了說是說是java解壓縮編碼格式問題什麼的,感覺不靠譜,自己試出來的,不知道對別人有沒有用。 有問題歡迎交流,謝謝閱讀 ...
  • 前言 早就聽過爬蟲,這幾天開始學習nodejs,寫了個爬蟲 demo ,爬取 博客園首頁的文章標題、用戶名、閱讀數、推薦數和用戶頭像,現做個小總結。 使用到這幾個點: 1、node的核心模塊-- 文件系統 2、用於http請求的第三方模塊 -- superagent 3、用於解析DOM的第三方模塊 ...
  • 思路:通過命令行修改瀏覽器啟動參數,使得瀏覽器不進行跨域檢查,從而允許跨域 方法:命令行參數啟動瀏覽器後添加參數--disable-web-security 例:chrome --disable-web-security --disabl-web-security參數的作用是禁止瀏覽器進行跨域檢查 ...
  • 今天把昨天遺留的問題解決了。 點擊過後終於出現效果了,以後儘量趕在11點睡吧。 大家晚安。 ...
  • 作為一個圍棋愛好者,就決定在博客裡加個圍棋js程式。於是,申請了博客的js許可權,美化美化我的博客。 好在js的語法像C系的,看了看,寫個程式應該還是可以的。 圍棋里,設計好基本的數據結構: 畫圖用canvas,之前並未接觸,一樣,baidu上搜搜,知道了畫圓、畫線、畫方塊的辦法,OK了,我畫圍棋說白 ...
  • 可以用淘寶npm鏡像 然後安裝 然後初始化項目: Watch就是一個監聽 v-if是如果為false就根本不在頁面存在這個元素 v-show是通過display:none來控制這個元素的顯示和隱藏 red表示class名稱,isRed表示是否是bool值來判斷是否顯示red這個class樣式 :cl ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...