ES6 快速指南



ES6 - 概述

ECMAScript (ES) 是一種由ECMAScript國際標準化組織標準化的指令碼語言規範。應用程式使用它來啟用客戶端指令碼。該規範受到Self、Perl、Python、Java等程式語言的影響。JavaScript、Jscript和ActionScript等語言都遵循此規範。

本教程將介紹JavaScript中ES6的實現。

JavaScript

JavaScript由Netscape Communications Corporation的開發者Brendan Eich於1995年開發。JavaScript最初名為Mocha,在正式更名為JavaScript之前簡稱為LiveScript。它是一種由瀏覽器執行的指令碼語言,即在客戶端執行。它與HTML結合使用,以開發響應式網頁。

此處討論的ECMAScript 6的實現涵蓋了以下新特性:

  • 支援常量
  • 塊級作用域
  • 箭頭函式
  • 擴充套件的引數處理
  • 模板字面量
  • 擴充套件的字面量
  • 增強的物件屬性
  • 解構賦值
  • 模組
  • 迭代器
  • 生成器
  • 集合
  • 各種類的新的內建方法
  • Promise

ECMAScript 版本

ECMA-262共有九個版本,如下所示:

版本 名稱 描述
1 ECMAScript 1 1997年釋出的第一個版本
2 ECMAScript 2 1998年釋出的第二個版本,為滿足ISO/IEC 16262標準而進行的少量更改
3 ECMAScript 3 1999年釋出的第三版,包含語言增強功能
4 ECMAScript 4 第四版釋出計劃被取消,一些特性後來新增到ES6中,其他複雜的特性被放棄
5 ECMAScript 5 2009年釋出的第五版
5.1 ECMAScript 5.1 2011年釋出的5.1版,為滿足ISO/IEC 16262:2011標準而進行的少量更改
6 ECMAScript 2015/ES6 2015年釋出的第六版,請參閱ES6章節瞭解新特性
7 ECMAScript 2016/ES7 2016年釋出的第七版,請參閱ES7章節瞭解新特性
8 ECMAScript 2017/ES8 2017年釋出的第八版,請參閱ES8章節瞭解新特性
9 ECMAScript 2018/ES9 2018年釋出的第九版,請參閱ES9章節瞭解新特性

ES6 - 環境搭建

在本章中,我們將討論ES6環境的設定。

本地環境搭建

JavaScript可以在任何瀏覽器、任何主機和任何作業系統上執行。您將需要以下內容來編寫和測試標準的JavaScript程式:

文字編輯器

文字編輯器幫助您編寫原始碼。一些編輯器的示例包括Windows記事本、Notepad++、Emacs、vim或vi等。使用的編輯器可能因作業系統而異。原始檔通常以.js為副檔名命名。

安裝Node.js

Node.js是一個開源的、跨平臺的伺服器端JavaScript執行環境。Node.js是執行JavaScript而無需瀏覽器支援的必要條件。它使用Google V8 JavaScript引擎來執行程式碼。您可以下載Node.js原始碼或適合您平臺的預構建安裝程式。Node可在https://nodejs.org/en/download下載

在Windows上安裝

下載並執行Node的.msi安裝程式

MSI Installer

要驗證安裝是否成功,請在終端視窗中輸入命令node –v

Node -v

在Mac OS X上安裝

要在OS X上安裝node.js,您可以下載預編譯的二進位制包,這使得安裝非常簡單。訪問www.nodejs.org並點選安裝按鈕下載最新包。

Latest Package

按照安裝嚮導安裝.dmg中的包,這將同時安裝nodenpm。npm是Node包管理器,它方便安裝Node.js的附加包。

Install Node

在Linux上安裝

在安裝Node.js和npm之前,您需要安裝許多依賴項

  • RubyGCC。您需要Ruby 1.8.6或更高版本和GCC 4.2或更高版本

  • Homebrew。Homebrew最初是Mac的包管理器,但已被移植到Linux作為Linuxbrew。您可以在http://brew.sh/http://brew.sh/linuxbrew瞭解有關Homebrew的更多資訊。

整合開發環境 (IDE) 支援

JavaScript可以在許多開發環境中構建,例如Visual Studio、Sublime Text 2、WebStorm/PHPStorm、Eclipse、Brackets等。本節將討論Visual Studio Code和Brackets IDE。此處使用的開發環境是Visual Studio Code(Windows平臺)。

Visual Studio Code

這是Visual Studio的開源IDE。它適用於Mac OS X、Linux和Windows平臺。VScode可在https://vscode.com.tw獲取。

在Windows上安裝

下載適用於Windows的Visual Studio Code。

Visual Studio Code for Windows

雙擊VSCodeSetup.exe VSCodeSetup啟動安裝過程。這隻需要一分鐘。

Setup Wizard

以下是IDE的螢幕截圖。

Screenshot of IDE

您可以透過右鍵單擊檔案→在命令提示符中開啟直接轉到檔案的路徑。同樣,“在資源管理器中顯示”選項會在檔案資源管理器中顯示該檔案。

Reveal in Explorer

在Mac OS X上安裝

Visual Studio Code的Mac OS X特定安裝指南可在https://vscode.com.tw/docs/setup/setup-overview找到

在Linux上安裝

Visual Studio Code的Linux特定安裝指南可在https://vscode.com.tw/Docs/editor/setup.找到

Brackets

Brackets是由Adobe Systems建立的免費開源Web開發編輯器。它適用於Linux、Windows和Mac OS X。Brackets可在http://brackets.io獲取。

Brackets

您可以透過新增另一個擴充套件Brackets Shell在Brackets本身中執行DOS提示符/Shell。

Prompt Shell

安裝後,您將在編輯器的右側找到一個shell圖示Editor Icon。單擊該圖示後,您將看到如下所示的shell視窗。

Shell

一切準備就緒!!!

ES6 - 語法

語法定義了編寫程式的一組規則。每種語言規範都定義了自己的語法。

JavaScript程式可以由以下部分組成:

  • 變數 - 代表一個命名的記憶體塊,可以儲存程式的值。

  • 字面量 - 代表常量/固定值。

  • 運算子 - 定義如何處理運算元的符號。

  • 關鍵字 - 在語言上下文中具有特殊含義的詞。

下表列出了一些JavaScript關鍵字。下表列出了一些常用的關鍵字。

break as any switch
case if throw else
var number string get
module type instanceof typeof
finally for enum export
while void this new
null super catch let
static return true false
  • 模組 - 代表可以在不同程式/指令碼中重用的程式碼塊。

  • 註釋 - 用於提高程式碼的可讀性。這些會被JavaScript引擎忽略。

  • 識別符號 - 這些是賦予程式中元素(如變數、函式等)的名稱。識別符號的規則如下:

    • 識別符號可以包含字元和數字。但是,識別符號不能以數字開頭。

    • 識別符號不能包含特殊符號,除了下劃線 (_) 或美元符號 ($)。

    • 識別符號不能是關鍵字。它們必須是唯一的。

    • 識別符號區分大小寫。識別符號不能包含空格。

下表說明了一些有效和無效的識別符號。

有效識別符號示例 無效識別符號示例

firstName

first_name

num1

$result

Var#

first name

first-name

1number

空格和換行符

ES6忽略程式中出現的空格、製表符和換行符。您可以在程式中隨意使用空格、製表符和換行符,並且可以自由地以整潔一致的方式格式化和縮排程式,使程式碼易於閱讀和理解。

JavaScript區分大小寫

JavaScript區分大小寫。這意味著JavaScript區分大寫和小寫字元。

分號是可選的

每一行指令稱為語句。在JavaScript中,分號是可選的。

示例

console.log("hello world") 
console.log("We are learning ES6") 

單行可以包含多個語句。但是,這些語句必須用分號隔開。

JavaScript中的註釋

註釋是提高程式可讀性的一種方法。註釋可用於包含有關程式的附加資訊,例如程式碼的作者、關於函式/構造的提示等。編譯器會忽略註釋。

JavaScript支援以下型別的註釋:

  • 單行註釋 (//) - // 和行尾之間的任何文字都被視為註釋。

  • 多行註釋 (/* */) - 這些註釋可以跨越多行。

示例

//this is single line comment  
/* This is a  
Multi-line comment 
*/

你的第一個JavaScript程式碼

讓我們從傳統的“Hello World”示例開始。

var message = "Hello World" 
console.log(message)

程式可以分析如下:

  • 第1行宣告一個名為message的變數。變數是程式中儲存值的機制。

  • 第 2 行將變數的值列印到提示符中。此處,控制檯指的是終端視窗。log() 函式用於在螢幕上顯示文字。

程式碼執行

我們將使用 Node.js 來執行我們的程式碼。

  • 步驟 1 − 將檔案儲存為 Test.js

  • 步驟 2 − 在 Visual Studio Code 的專案資源管理器視窗中的工作檔案選項下,右鍵單擊 Test.js 檔案。

  • 步驟 3 − 選擇“在命令提示符中開啟”選項。

  • 步驟 4 − 在 Node 的終端視窗中鍵入以下命令。

node Test.js 

檔案成功執行後,將顯示以下輸出。

Hello World

Node.js 和 JS/ES6

ECMAScript 2015 (ES6) 功能分為三組:

  • 已釋出 − 這些是 V8 認為穩定的功能。

  • 已分階段的功能 − 這些功能幾乎已完成,但 V8 團隊認為不穩定。

  • 正在進行中 − 這些功能僅應用於測試目的。

第一類功能完全受支援,並且預設情況下已啟用。分階段的功能需要執行時 --harmony 標誌才能執行。

Node.js 的元件特定 CLI 標誌列表可在此處找到:https://nodejs.org/api/cli.html

嚴格模式

ECMAScript 規範的第五版引入了嚴格模式。嚴格模式對 JavaScript 施加了一層約束。它對正常的 JavaScript 語義進行了一些更改。

可以透過包含以下內容來轉換程式碼以在嚴格模式下工作:

// Whole-script strict mode syntax 
"use strict"; 
 v = "Hi!  I'm a strict mode script!";  // ERROR: Variable v is not declared

在上例程式碼片段中,整個程式碼作為一個受約束的 JavaScript 變體執行。

JavaScript 還允許限制函式作用域內的嚴格模式。如下所示:

v = 15 
function f1() { 
   "use strict"; 
   var v = "Hi!  I'm a strict mode script!"; 
}

在上例程式碼片段中,函式外部的任何程式碼都將在非嚴格模式下執行。函式內的所有語句都將在嚴格模式下執行。

ES6 和提升

JavaScript 引擎預設情況下會將宣告移動到頂部。此功能稱為提升。此功能適用於變數和函式。提升允許 JavaScript 在宣告元件之前使用它。但是,提升的概念不適用於在嚴格模式下執行的指令碼。

後續章節將解釋變數提升和函式提升。

ES6 - 變數

根據定義,變數是“記憶體中命名的空間”,用於儲存值。換句話說,它充當程式中值的容器。變數名稱稱為識別符號。以下是識別符號的命名規則:

  • 識別符號不能是關鍵字。

  • 識別符號可以包含字母和數字。

  • 識別符號不能包含空格和特殊字元,下劃線 (_) 和美元符號 ($) 除外。

  • 變數名不能以數字開頭。

型別語法

必須在使用變數之前宣告它。ES5 語法使用var關鍵字來實現相同的功能。宣告變數的 ES5 語法如下所示。

//Declaration using var keyword 
var  variable_name

ES6 引入了以下變數宣告語法:

  • 使用 let。
  • 使用 const。

變數初始化是指將值儲存在變數中的過程。變數可以在宣告時或稍後初始化。

宣告和初始化變數的傳統 ES5 型別語法如下所示:

//Declaration using var keyword 
var variable_name = value

示例:使用變數

var name = "Tom" 
console.log("The value in the variable is: "+name)

上面的示例聲明瞭一個變數並列印其值。

成功執行後,將顯示以下輸出。

The value in the variable is Tom

JavaScript 和動態型別

JavaScript 是一種無型別語言。這意味著 JavaScript 變數可以儲存任何資料型別的值。與許多其他語言不同,您不必在變數宣告期間告訴 JavaScript 變數將儲存何種型別的值。變數的值型別可以在程式執行期間更改,JavaScript 會自動處理它。此功能稱為動態型別

JavaScript 變數作用域

變數的作用域是定義它的程式區域。傳統上,JavaScript 只定義了兩種作用域:全域性作用域和區域性作用域。

  • 全域性作用域− 全域性作用域的變數可以從 JavaScript 程式碼的任何部分訪問。

  • 區域性作用域− 區域性作用域的變數可以從宣告它的函式中訪問。

示例:全域性變數與區域性變數

以下示例聲明瞭兩個名為num的變數——一個在函式外部(全域性作用域),另一個在函式內部(區域性作用域)。

var num = 10 
function test() { 
   var num = 100 
   console.log("value of num in test() "+num) 
} 
console.log("value of num outside test() "+num) 
test()

在函式內引用變數時,將顯示區域性作用域變數的值。但是,在函式外部訪問變數num時,將返回全域性作用域例項。

成功執行後,將顯示以下輸出。

value of num outside test() 10
value of num in test() 100

ES6 定義了一個新的變數作用域:塊作用域。

Let 和塊作用域

塊作用域將變數的訪問許可權限制為宣告它的塊。var關鍵字為變數分配函式作用域。與 var 關鍵字不同,let關鍵字允許指令碼將對變數的訪問許可權限制為最近的封閉塊。

"use strict" 
function test() { 
   var num = 100 
   console.log("value of num in test() "+num) { 
      console.log("Inner Block begins") 
      let num = 200 
      console.log("value of num : "+num)  
   } 
} 
test()

指令碼在函式的區域性作用域內聲明瞭一個變數num,並使用 let 關鍵字在塊內重新宣告它。當在內部塊外部訪問變數時,將列印區域性作用域變數的值,而內部塊內將引用塊作用域變數。

注意 − 嚴格模式是一種選擇加入 JavaScript 受限變體的方法。

成功執行後,將顯示以下輸出。

value of num in test() 100 
Inner Block begins 
value of num : 200

示例:let 與 var

var no = 10; 
var no = 20; 
console.log(no);

執行上述程式碼後,將顯示以下輸出。

20

讓我們使用let關鍵字重寫相同的程式碼。

let no = 10; 
let no = 20; 
console.log(no);

上面的程式碼將丟擲一個錯誤:識別符號“no”已被宣告。任何使用 let 關鍵字宣告的變數都被分配了塊作用域。

let 和塊級安全性

如果我們嘗試在同一個塊中兩次宣告一個let變數,它將丟擲一個錯誤。考慮以下示例:

<script>
   let balance = 5000 // number type
   console.log(typeof balance)
   let balance = {message:"hello"} // changing number to object type
   console.log(typeof balance)
</script>

上面的程式碼將導致以下錯誤:

Uncaught SyntaxError: Identifier 'balance' has already been declared

let 和多個塊

但是,可以在不同的塊級作用域中使用相同的let變數,而不會出現任何語法錯誤。

示例

<script>
   let count = 100
   for (let count = 1;count <= 10;count++){
      //inside for loop brackets ,count value starts from 1
      console.log("count value inside loop is ",count);
   }
   //outside for loop brackets ,count value is 100
   console.log("count value after loop is",count);

   if(count == 100){
      //inside if brackets ,count value is 50
      let count = 50;
      console.log("count inside if block",count);
   }
   console.log(count);
</script>

上述程式碼的輸出如下:

count value inside loop is 1
count value inside loop is 2
count value inside loop is 3
count value inside loop is 4
count value inside loop is 5
count value inside loop is 6
count value inside loop is 7
count value inside loop is 8
count value inside loop is 9
count value inside loop is 10
count value after loop is 100
count inside if block 50
100

const

const宣告建立對值的只讀引用。這並不意味著它儲存的值是不可變的,只是變數識別符號不能重新賦值。常量具有塊作用域,就像使用 let 語句定義的變數一樣。常量的值不能透過重新賦值來更改,並且不能重新宣告。

使用const關鍵字宣告的變數,以下規則適用:

  • 常量不能重新賦值。
  • 常量不能重新宣告。
  • 常量需要初始化器。這意味著常量必須在其宣告期間初始化。
  • 分配給const變數的值是可變的。

示例

const x = 10
x = 12 // will result in an error!!

上面的程式碼將返回一個錯誤,因為常量不能重新賦值。常量變數是不可變的。

常量是不可變的

與使用let關鍵字宣告的變數不同,常量是不可變的。這意味著它的值不能更改。例如,如果我們嘗試更改常量變數的值,將顯示錯誤。

<script>
   let income = 100000
   const INTEREST_RATE = 0.08
   income += 50000 // mutable
   console.log("changed income value is ",income)
   INTEREST_RATE += 0.01
   console.log("changed rate is ",INTEREST_RATE) //Error: not mutable
</script>

上述程式碼的輸出如下:

changed income value is 150000
Uncaught TypeError: Assignment to constant variable

const 和陣列

以下示例顯示如何建立不可變陣列。可以向陣列中新增新元素。但是,重新初始化陣列將導致錯誤,如下所示:

<script>
   const DEPT_NOS = [10,20,30,50]
   DEPT_NOS.push(40)
   console.log('dept numbers is ',DEPT_NOS)

   const EMP_IDS = [1001,1002,1003]
   console.log('employee ids',EMP_IDS)
   //re assigning variable employee ids
   EMP_IDS = [2001,2002,2003]
   console.log('employee ids after changing',EMP_IDS)
</script>

上述程式碼的輸出將如下所示:

dept numbers is (5) [10, 20, 30, 50, 40]
employee ids (3) [1001, 1002, 1003]
Uncaught TypeError: Assignment to constant variable.

var 關鍵字

在 ES6 之前,var關鍵字用於在 JavaScript 中宣告變數。使用var宣告的變數不支援塊級作用域。這意味著如果在迴圈或if 塊中聲明瞭一個變數,則可以在迴圈或if 塊外部訪問它。這是因為使用var關鍵字宣告的變數支援提升。

var 和提升

變數提升允許在 JavaScript 程式中使用變數,即使在宣告它之前也是如此。此類變數預設情況下將初始化為undefined。JavaScript 執行時將掃描變數宣告並將它們放在函式或指令碼的頂部。使用var關鍵字宣告的變數將提升到頂部。考慮以下示例:

<script>
   variable company is hoisted to top , var company = undefined
   console.log(company); // using variable before declaring
   var company = "TutorialsPoint"; // declare and initialized here
   console.log(company);
</script>

上述程式碼的輸出將如下所示:

undefined
TutorialsPoint

var 和塊作用域

塊作用域將變數的訪問許可權限制為宣告它的塊。var關鍵字為變數分配函式作用域。使用var關鍵字宣告的變數沒有塊作用域。考慮以下示例:

<script>
   //hoisted to top ; var i = undefined
   for (var i = 1;i <= 5;i++){
      console.log(i);
   }
   console.log("after the loop i value is "+i);
</script>

上述程式碼的輸出如下:

1
2
3
4
5
after the loop i value is 6

變數i使用var關鍵字在 for 迴圈內宣告。變數 i 在迴圈外部是可訪問的。但是,有時可能需要限制塊內變數的訪問許可權。在這種情況下,我們不能使用var關鍵字。ES6 引入了let關鍵字來克服此限制。

var 和塊級安全性

如果我們在塊內使用var 關鍵字兩次宣告相同的變數,編譯器不會丟擲錯誤。但是,這可能會導致執行時出現意外的邏輯錯誤。

<script>
   var balance = 5000
   console.log(typeof balance)
   var balance = {message:"hello"}
   console.log(typeof balance)
</script>

上述程式碼的輸出如下所示:

number
object

ES6 - 運算子

表示式是一種特殊型別的語句,它計算出一個值。每個表示式都由以下部分組成:

  • 運算元 − 表示資料。

  • 運算子 − 定義如何處理運算元以生成值。

考慮以下表達式:2 + 3。在此表示式中,2 和 3 是運算元,符號 +(加號)是運算子。JavaScript 支援以下型別的運算子:

  • 算術運算子
  • 邏輯運算子
  • 關係運算符
  • 按位運算子
  • 賦值運算子
  • 三元/條件運算子
  • 字串運算子
  • 型別運算子
  • void 運算子

算術運算子

假設變數ab中的值分別為 10 和 5。

顯示示例

運算子 功能 示例
+ 加法

返回運算元的總和。

a + b 為 15
- 減法

返回值的差。

a-b 為 5
* 乘法

返回值。

a*b 為 50
/ 除法

執行除法運算並返回商。

a/b 為 2
% 模數

執行除法並返回餘數。

a%b 為 0
++ 遞增

將變數的值遞增 1。

a++ 為 11
-- 遞減

將變數的值遞減 1。

a-- 為 9

關係運算符

關係運算符測試或定義兩個實體之間關係的型別。關係運算符返回布林值,即 true/false。

假設 A 的值為 10,B 的值為 20。

顯示示例

運算子 描述 示例
> 大於 (A > B) 為 False
< 小於 (A < B) 為 True
>= 大於或等於 (A >= B) 為 False
<= 小於或等於 (A <= B) 為 True
== 相等 (A == B) 為 False
!= 不等於 (A!= B) 為真

邏輯運算子

邏輯運算子用於組合兩個或多個條件。邏輯運算子也返回布林值。假設變數 A 的值為 10,B 的值為 20。

顯示示例.

運算子 描述 示例
&& 與(And)

只有當所有指定的表示式都返回真時,運算子才返回真。

(A > 10 && B > 10) 為假
|| 或(Or)

如果至少一個指定的表示式返回真,則運算子返回真。

(A > 10 || B > 10) 為真
! 非(Not)

該運算子返回表示式的結果的反值。例如:!(7>5) 返回假。

!(A > 10) 為真

位運算子

JavaScript 支援以下位運算子。下表總結了 JavaScript 的位運算子。

顯示示例.

運算子 用法 描述
按位與(Bitwise AND) a & b 對於兩個運算元的相應位都為 1 的每一位位置,返回 1
按位或(Bitwise OR) a | b 對於兩個運算元中任何一個或兩個運算元的相應位為 1 的每一位位置,返回 1
按位異或(Bitwise XOR) a^b 對於兩個運算元中只有一個運算元的相應位為 1 的每一位位置,返回 1
按位非(Bitwise NOT) ~ a 反轉其運算元的位
左移(Left shift) a << b 將 a 的二進位制表示向左移動 b (< 32) 位,從右邊移入零
算術右移(Sign-propagating right shift) a >> b 將 a 的二進位制表示向右移動 b (< 32) 位,丟棄移出的位
邏輯右移(Zero-fill right shift) a >>> b 將 a 的二進位制表示向右移動 b (< 32) 位,丟棄移出的位,並從左邊移入零

賦值運算子

下表總結了賦值運算子。

顯示示例.

序號 運算子和描述
1

= (簡單賦值)

將右側運算元的值賦給左側運算元。

示例 − C = A + B 將 A + B 的值賦給 C

2

+= (加法賦值)

它將右側運算元新增到左側運算元,並將結果賦給左側運算元。

示例 − C += A 等效於 C = C + A

3

-= (減法賦值)

它從左側運算元中減去右側運算元,並將結果賦給左側運算元。

示例 C -= A 等效於 C = C - A

4

*= (乘法賦值)

它將右側運算元乘以左側運算元,並將結果賦給左側運算元。

示例 C *= A 等效於 C = C * A

5

/= (除法賦值)

它將左側運算元除以右側運算元,並將結果賦給左側運算元。

注意 − 位運算子也適用相同的邏輯,因此它們將變為 <<=、>>=、>>>=、&=、|= 和 ^=。

其他運算子

以下是一些其他運算子。

負號運算子 (-)

更改值的符號。以下程式是相同的示例。

var x = 4 
var y = -x; 
console.log("value of x: ",x); //outputs 4 
console.log("value of y: ",y); //outputs -4

上述程式成功執行後將顯示以下輸出。

value of x: 4 
value of y: -4 

字串運算子:連線運算子 (+)

當 + 運算子應用於字串時,它會將第二個字串附加到第一個字串。以下程式有助於理解這個概念。

var msg = "hello"+"world" 
console.log(msg) 

上述程式成功執行後將顯示以下輸出。

helloworld

連線操作不會在字串之間新增空格。可以在單個語句中連線多個字串。

條件運算子 (?)

此運算子用於表示條件表示式。條件運算子有時也稱為三元運算子。以下是語法。

Test ? expr1 : expr2

其中,

Test − 指的是條件表示式

expr1 − 如果條件為真則返回的值

expr2 − 如果條件為假則返回的值

示例

var num = -2 
var result = num > 0 ?"positive":"non-positive" 
console.log(result)

第 2 行檢查變數 num 中的值是否大於零。如果 num 設定為大於零的值,則返回字串“positive”,否則返回“non-positive”字串。

上述程式成功執行後將顯示以下輸出。

non-positive 

typeof 運算子

這是一個一元運算子。此運算子返回運算元的資料型別。下表列出了 JavaScript 中 typeof 運算子返回的資料型別和值。

型別 typeof 返回的字串
數字 "number"
字串 "string"
布林值 "boolean"
物件 "object"

以下示例程式碼顯示數字作為輸出。

var num = 12 
console.log(typeof num); //output: number

執行上述程式碼後,將顯示以下輸出。

number

擴充套件運算子

ES6 提供了一個名為擴充套件運算子的新運算子。擴充套件運算子由三個點“...”表示。擴充套件運算子將陣列轉換為單個數組元素。

擴充套件運算子和函式

以下示例說明了在函式中使用擴充套件運算子。

<script>
   function addThreeNumbers(a,b,c){
      return a+b+c;
   }
   const arr = [10,20,30]
   console.log('sum is :',addThreeNumbers(...arr))
   console.log('sum is ',addThreeNumbers(...[1,2,3]))
</script>

上述程式碼的輸出將如下所示:

sum is : 60
sum is 6

擴充套件運算子和陣列複製與連線

擴充套件運算子可用於將一個數組複製到另一個數組。它還可用於連線兩個或多個數組。這在下面的示例中顯示:

示例

<script>
   //copy array using spread operator
   let source_arr = [10,20,30]
   let dest_arr = [...source_arr]
   console.log(dest_arr)
	
   //concatenate two arrays
   let arr1 = [10,20,30]
   let arr2 =[40,50,60]
   let arr3 = [...arr1,...arr2]
   console.log(arr3)
</script>

上述程式碼的輸出將如下所示:

[10, 20, 30]
[10, 20, 30, 40, 50, 60]

擴充套件運算子和物件複製與連線

擴充套件運算子可用於將一個物件複製到另一個物件。它還可用於連線兩個或多個物件。這在下面的示例中顯示:

<script>
   //copy object
   let student1 ={firstName:'Mohtashim',company:'TutorialsPoint'}
   let student2 ={...student1}
   console.log(student2)
   //concatenate objects
   let student3 = {lastName:'Mohammad'}
   let student4 = {...student1,...student3}
   console.log(student4)
</script>

上述程式碼的輸出將如下所示:

{firstName: "Mohtashim", company: "TutorialsPoint"}
{firstName: "Mohtashim", company: "TutorialsPoint", lastName: "Mohammad"}

ES6 - 決策語句

條件/決策結構在執行指令之前評估條件。

Decision Making

JavaScript 中的條件結構在下表中進行了分類。

序號 語句和描述
1 if 語句

“if”語句由一個布林表示式後跟一個或多個語句組成。

2 if…else 語句

“if”語句後面可以跟一個可選的“else”語句,當布林表示式為假時執行此語句。

3 else..if 階梯/巢狀 if 語句

else…if 階梯用於測試多個條件。以下是相同的語法。

4 switch…case 語句

switch 語句評估表示式,將表示式的值與 case 子句匹配,並執行與該 case 關聯的語句。

ES6 - 迴圈語句

有時,某些指令需要重複執行。迴圈是執行此操作的理想方法。迴圈表示必須重複的一組指令。在迴圈的上下文中,重複稱為迭代

下圖說明了迴圈的分類:

Loops

確定性迴圈

迭代次數確定/固定的迴圈稱為確定性迴圈。“for 迴圈”是確定性迴圈的一種實現。

for (initial_count_value; termination-condition; step) { 
   //statements
}   

序號 確定性迴圈和描述
1 “for”迴圈

for 迴圈在指定次數內執行程式碼塊。

2 for…in 迴圈

for...in 迴圈用於迴圈遍歷物件的屬性。

3 for…of 迴圈

for…of 迴圈用於迭代可迭代物件而不是物件字面量。

不確定性迴圈

當迴圈中的迭代次數是不確定或未知時,使用不確定性迴圈。

可以使用以下方法實現不確定性迴圈:

序號 不確定性迴圈和描述
1 while 迴圈

while 迴圈每次指定的條件計算結果為真時執行指令。

2 do…while 迴圈

do…while 迴圈類似於 while 迴圈,只是 do...while 迴圈在第一次執行迴圈時不評估條件。

迴圈控制語句

序號 迴圈控制語句和描述
1 break 語句

break 語句用於將控制權從結構中移出。

2 continue 語句

continue 語句跳過當前迭代中的後續語句,並將控制權帶回迴圈的開頭。

使用標籤控制流程

標籤只是一個後跟冒號 (:) 的識別符號,應用於語句或程式碼塊。標籤可以與breakcontinue 一起使用以更精確地控制流程。

‘continue’‘break’ 語句與其標籤名稱之間不允許換行。此外,標籤名稱和關聯迴圈之間也不應有任何其他語句。

序號 標籤和描述
1 帶 break 的標籤

標籤可以與 break 和 continue 一起使用以更精確地控制流程。

2 帶 continue 的標籤

‘continue’ 或 ‘break’ 語句與其標籤名稱之間不允許換行。

ES6 - 函式

函式是可讀、可維護和可重用程式碼的構建塊。函式使用 function 關鍵字定義。以下是定義標準函式的語法。

function function_name() { 
   // function body 
} 

要強制執行函式,必須呼叫它。這稱為函式呼叫。以下是呼叫函式的語法。

function_name()

示例:簡單的函式定義

//define a  function 
function test() { 
   console.log("function called") 
} 
//call the function 
test()

此示例定義了一個函式 test()。一對定界符 ({ }) 定義函式體。它也稱為函式作用域。必須呼叫函式才能強制其執行。

執行上述程式碼後,將顯示以下輸出。

function called

函式分類

函式可以分為返回值函式和引數化函式。

返回值函式

函式還可以將值與控制一起返回給呼叫方。此類函式稱為返回值函式。

以下是返回值函式的語法。

function function_name() { 
   //statements 
   return value; 
}
  • 返回值函式必須以 return 語句結尾。

  • 函式最多可以返回一個值。換句話說,每個函式只能有一個 return 語句。

  • return 語句應該是函式中的最後一個語句。

以下程式碼片段是返回值函式的示例:

function retStr() { 
   return "hello world!!!" 
}  
var val = retStr() 
console.log(val) 

上述示例定義了一個函式,該函式將字串“hello world!!!”返回給呼叫方。上述程式碼成功執行後將顯示以下輸出。

hello world!!! 

引數化函式

引數是一種向函式傳遞值的方式。引數構成函式簽名的一部分。在呼叫函式期間,引數值將傳遞給函式。除非明確指定,否則傳遞給函式的值的數量必須與定義的引數數量匹配。

以下是定義引數化函式的語法。

function func_name( param1,param2 ,…..paramN) {   
   ...... 
   ...... 
}

示例 - 引數化函式

此示例定義了一個名為 add 的函式,它接受兩個引數 **n1** 和 **n2**,並列印它們的和。在呼叫函式時,引數值將傳遞給函式。

function add( n1,n2) { 
   var sum = n1 + n2 
   console.log("The sum of the values entered "+sum) 
} 
add(12,13) 

執行上述程式碼後,將顯示以下輸出。

The sum of the values entered 25

預設函式引數

在 ES6 中,如果函式未傳遞任何值或值為 undefined,則允許引數初始化為預設值。以下程式碼對此進行了說明。

function add(a, b = 1) { 
   return a+b; 
} 
console.log(add(4))

上面的函式將 b 的值預設設定為 1。除非顯式傳遞值,否則函式將始終認為引數 b 的值為 1。成功執行上述程式碼後將顯示以下輸出。

5

如果函式顯式傳遞值,則引數的預設值將被覆蓋。

function add(a, b = 1) { 
   return a + b; 
} 
console.log(add(4,2))

上面的程式碼將引數 b 的值顯式設定為 2,從而覆蓋其預設值。成功執行上述程式碼後將顯示以下輸出。

6

為了更好地理解,讓我們考慮以下示例。

示例 1

以下示例顯示了一個接受兩個引數並返回其和的函式。第二個引數的預設值為 10。這意味著,如果未向第二個引數傳遞任何值,則其值為 10。

<script>
   function addTwoNumbers(first,second = 10){
      console.log('first parameter is :',first)
      console.log('second parameter is :',second)
      return first+second;
   }

   console.log("case 1 sum:",addTwoNumbers(20)) // no value
   console.log("case 2 sum:",addTwoNumbers(2,3))
   console.log("case 3 sum:",addTwoNumbers())
   console.log("case 4 sum",addTwoNumbers(1,null))//null passed
   console.log("case 5 sum",addTwoNumbers(3,undefined))
</script>

上述程式碼的輸出如下所示:

first parameter is : 20
second parameter is : 10
case 1 sum: 30
first parameter is : 2
second parameter is : 3
case 2 sum: 5
first parameter is : undefined
second parameter is : 10
case 3 sum: NaN
first parameter is : 1
second parameter is : null
case 4 sum 1
first parameter is : 3
second parameter is : 10
case 5 sum 13

示例 2

<script>
   let DEFAULT_VAL = 30
      function addTwoNumbers(first,second = DEFAULT_VAL){
         console.log('first parameter is :',first)
         console.log('second parameter is :',second)
         return first+second;
      }
      console.log("case 1 sum",addTwoNumbers(1))
      console.log("case 2 sum",addTwoNumbers(3,undefined))
</script>

上述程式碼的輸出將如下所示:

first parameter is : 1
second parameter is : 30
case 1 sum 31
first parameter is : 3
second parameter is : 30
case 2 sum 33

剩餘引數

剩餘引數類似於 Java 中的可變引數。剩餘引數不會限制您可以傳遞給函式的值的數量。但是,傳遞的值必須全部為相同型別。換句話說,剩餘引數充當相同型別多個引數的佔位符。

要宣告剩餘引數,引數名字首為三個點,稱為擴充套件運算子。以下示例說明了這一點。

function fun1(...params) { 
   console.log(params.length); 
}  
fun1();  
fun1(5); 
fun1(5, 6, 7); 

執行上述程式碼後,將顯示以下輸出。

0 
1 
3

**注意** - 剩餘引數應位於函式引數列表的最後。

匿名函式

未繫結到識別符號(函式名)的函式稱為匿名函式。這些函式在執行時動態宣告。匿名函式可以接受輸入並返回輸出,就像標準函式一樣。匿名函式在其初始建立後通常不可訪問。

變數可以賦值為匿名函式。這樣的表示式稱為 **函式表示式**。

以下是匿名函式的語法。

var res = function( [arguments] ) { ... } 

示例 - 匿名函式

var f = function(){ return "hello"} 
console.log(f()) 

執行上述程式碼後,將顯示以下輸出。

hello 

示例 - 匿名引數化函式

var func = function(x,y){ return x*y }; 
function product() { 
   var result; 
   result = func(10,20); 
   console.log("The product : "+result) 
} 
product()

執行上述程式碼後,將顯示以下輸出。

The product : 200 

Function 建構函式

函式語句不是定義新函式的唯一方法;您可以使用 Function() 建構函式和 new 運算子動態定義函式。

以下是使用 Function() 建構函式和 new 運算子建立函式的語法。

var variablename = new Function(Arg1, Arg2..., "Function Body"); 

Function() 建構函式接受任意數量的字串引數。最後一個引數是函式的主體——它可以包含任意 JavaScript 語句,這些語句之間用分號隔開。

Function() 建構函式不會傳遞任何指定其建立的函式名稱的引數。

示例 - Function 建構函式

var func = new Function("x", "y", "return x*y;"); 
function product() { 
   var result; 
   result = func(10,20); 
   console.log("The product : "+result)
} 
product()

在上面的示例中,Function() 建構函式用於定義匿名函式。該函式接受兩個引數並返回它們的乘積。

執行上述程式碼後,將顯示以下輸出。

The product : 200

遞迴和 JavaScript 函式

遞迴是一種透過讓函式反覆呼叫自身直到得到結果來迭代操作的技術。當需要在迴圈中使用不同的引數反覆呼叫同一個函式時,遞迴最適用。

示例 - 遞迴

function factorial(num) { 
   if(num <= 0) { 
      return 1; 
   } else { 
      return (num * factorial(num-1)  ) 
   } 
} 
console.log(factorial(6)) 

在上面的示例中,函式呼叫自身。成功執行上述程式碼後將顯示以下輸出。

720 

示例 - 匿名遞迴函式

(function() { 
   var msg = "Hello World" 
   console.log(msg)
})()

該函式使用一對括號 () 呼叫自身。成功執行上述程式碼後將顯示以下輸出。

Hello World 

Lambda 函式

Lambda 指的是程式設計中的匿名函式。Lambda 函式是一種表示匿名函式的簡潔機制。這些函式也稱為 **箭頭函式**。

Lambda 函式 - 結構

Lambda 函式有三個部分:

  • **引數** - 函式可以選擇具有引數。

  • **胖箭頭符號/lambda 符號** (=>):它也稱為“轉到”運算子。

  • **語句** - 表示函式的指令集。

**提示** - 按慣例,鼓勵使用單個字母引數來進行緊湊而精確的函式宣告。

Lambda 表示式

這是一個指向單行程式碼的匿名函式表示式。以下是相同的語法。

([param1, parma2,…param n] )=>statement;

示例 - Lambda 表示式

var foo = (x)=>10+x 
console.log(foo(10)) 

此示例聲明瞭一個 lambda 表示式函式。該函式返回 10 和傳遞的引數的和。

執行上述程式碼後,將顯示以下輸出。

20

Lambda 語句

這是一個指向程式碼塊的匿名函式宣告。當函式體跨越多行時,使用此語法。以下是相同的語法。

( [param1, parma2,…param n] )=> {       
   //code block 
}

示例 - Lambda 語句

var msg = ()=> { 
   console.log("function invoked") 
} 
msg() 

函式的引用被返回並存儲在變數 msg 中。成功執行上述程式碼後將顯示以下輸出。

function  invoked 

語法變體

單個引數的可選括號。

var msg = x=> { 
   console.log(x) 
} 
msg(10)

單個語句的可選大括號。無引數的空括號。

var disp = ()=>console.log("Hello World") 
disp();

函式表示式和函式宣告

函式表示式和函式宣告並非同義詞。與函式表示式不同,函式宣告受函式名稱約束。

兩者之間的根本區別在於,函式宣告在其執行之前被解析。另一方面,函式表示式僅在指令碼引擎在執行期間遇到它時才被解析。

當 JavaScript 解析器在主程式碼流中看到一個函式時,它會假設函式宣告。當函式作為語句的一部分出現時,它就是一個函式表示式。

函式提升

像變數一樣,函式也可以提升。與變數不同,函式宣告在提升時會提升函式定義,而不僅僅是提升函式名稱。

以下程式碼片段說明了 JavaScript 中的函式提升。

hoist_function();  
function hoist_function() { 
   console.log("foo"); 
} 

執行上述程式碼後,將顯示以下輸出。

foo 

但是,函式表示式不能提升。以下程式碼片段說明了這一點。

hoist_function(); // TypeError: hoist_function() is not a function  
var hoist_function() = function() { 
   console.log("bar"); 
};

立即呼叫函式表示式

立即呼叫函式表示式 (IIFE) 可用於避免塊內的變數提升。它允許公開訪問方法,同時保留函式內定義的變數的私有性。這種模式稱為自執行匿名函式。以下兩個示例更好地解釋了這個概念。

示例 1:IIFE

var main = function() { 
   var loop = function() { 
      for(var x = 0;x<5;x++) {
         console.log(x); 
      } 
   }(); 
   console.log("x can not be accessed outside the block scope x value is :"+x); 
} 
main();

示例 2:IIFE

var main = function() { 
   (function() { 
      for(var x = 0;x<5;x++) { 
         console.log(x); 
      } 
   })(); 
   console.log("x can not be accessed outside the block scope x value is :"+x); 
} 
main();

這兩個示例都將呈現以下輸出。

0 
1 
2 
3 
4 
Uncaught ReferenceError: x is not define

生成器函式

呼叫普通函式時,控制權將保留在被呼叫函式中,直到它返回。使用 ES6 中的生成器,呼叫函式現在可以控制被呼叫函式的執行。生成器類似於普通函式,不同之處在於:

  • 函式可以在任何時候將控制權返回給呼叫者。

  • 呼叫生成器時,它不會立即執行。相反,您將獲得一個迭代器。當您呼叫迭代器的 next 方法時,函式將執行。

生成器用在函式關鍵字後新增星號來表示;否則,它們的語法與普通函式相同。

以下示例說明了這一點。

"use strict" 
function* rainbow() { 
   // the asterisk marks this as a generator 
   yield 'red'; 
   yield 'orange'; 
   yield 'yellow'; 
   yield 'green'; 
   yield 'blue'; 
   yield 'indigo'; 
   yield 'violet'; 
} 
for(let color of rainbow()) { 
   console.log(color); 
} 

生成器允許呼叫者和被呼叫函式之間進行雙向通訊。這是透過使用 **yield** 關鍵字實現的。

考慮以下示例:

function* ask() { 
   const name = yield "What is your name?"; 
   const sport = yield "What is your favorite sport?"; 
   return `${name}'s favorite sport is ${sport}`; 
}  
const it = ask(); 
console.log(it.next()); 
console.log(it.next('Ethan'));  
console.log(it.next('Cricket')); 

生成器函式的順序如下:

  • 生成器以暫停狀態啟動;返回迭代器。

  • it.next() 產生“What is your name”。生成器暫停。這是由 yield 關鍵字完成的。

  • 呼叫 it.next(“Ethan”) 將值 Ethan 分配給變數 name 併產生“What is your favorite sport?”。生成器再次暫停。

  • 呼叫 it.next(“Cricket”) 將值 Cricket 分配給變數 sport 並執行隨後的 return 語句。

因此,上述程式碼的輸出將是:

{ 
   value: 'What is your name?', done: false 
} 
{ 
   value: 'What is your favorite sport?', done: false 
} 
{ 
   value: 'Ethan\'s favorite sport is Cricket', done: true 
}

**注意** - 生成器函式不能使用箭頭函式表示。

箭頭函式

ES 中引入的箭頭函式有助於以簡潔的方式編寫 JavaScript 函式。現在讓我們詳細瞭解一下。

ES5 和匿名函式

JavaScript 大量使用 **匿名函式**。匿名函式是沒有附加名稱的函式。匿名函式用於 **函式回撥**。以下示例說明了在 ES5 中使用匿名函式:

<script>
   setTimeout(function(){
      console.log('Learning at TutorialsPoint is fun!!')
   },1000)
</script>

上面的示例將匿名函式作為引數傳遞給預定義的 **setTimeout() 函式**。setTimeout() 函式將在 1 秒後回撥匿名函式。

1 秒後顯示以下輸出:

Learning at TutorialsPoint is fun!!

箭頭函式語法

ES6 引入了 **箭頭函式** 的概念,以簡化 **匿名函式** 的使用。箭頭函式有三個部分,如下所示:

  • **引數** - 箭頭函式可以選擇具有引數

  • **胖箭頭符號 (=>)** - 它也稱為“轉到”運算子

  • **語句** - 表示函式的指令集

**提示** - 按慣例,鼓勵使用單個字母引數來進行緊湊而精確的箭頭函式宣告。

語法

//Arrow function that points to a single line of code
()=>some_expression

//Arrow function that points to a block of code
()=> { //some statements }`

//Arrow function with parameters
(param1,param2)=>{//some statement}

示例:ES6 中的箭頭函式

以下示例使用箭頭函式定義了兩個函式表示式 **add** 和 **isEven**

<script>
   const add = (n1,n2) => n1+n2
   console.log(add(10,20))

   const isEven = (n1) => {
      if(n1%2 == 0)
         return true;
      else
         return false;
   }
   console.log(isEven(10))
</script>

上述程式碼的輸出如下所示:

30
true

Array.prototype.map() 和箭頭函式

在以下示例中,箭頭函式作為引數傳遞給 **Array.prototype.map() 函式。** map() 函式對陣列中的每個元素執行箭頭函式。在這種情況下,箭頭函式顯示陣列中的每個元素及其索引。

<script>
   const names = ['TutorialsPoint','Mohtashim','Bhargavi','Raja']
   names.map((element,index)=> {
      console.log('inside arrow function')
      console.log('index is '+index+' element value is :'+element)
   })
</script>

上述程式碼的輸出將如下所示:

inside arrow function
index is 0 element value is :TutorialsPoint
inside arrow function
index is 1 element value is :Mohtashim
inside arrow function
index is 2 element value is :Bhargavi
inside arrow function
index is 3 element value is :Raja

示例:window.setTimeout() 和箭頭函式

以下示例將箭頭函式作為引數傳遞給預定義的 **setTimeout() 函式**。**setTimeout()** 函式將在 1 秒後回撥箭頭函式。

<script>
   setTimeout(()=>{
      console.log('Learning at TutorialsPoint is fun!!')
   },1000)
</script>

1 秒後顯示以下輸出:

Learning at TutorialsPoint is fun!!

箭頭函式和“this”

在箭頭函式內部,如果我們使用 **this 指標**,它將指向封閉的詞法作用域。這意味著箭頭函式不會在每次呼叫時建立一個新的 **this 指標** 例項。箭頭函式使用其封閉作用域。為了理解這一點,讓我們來看一個例子。

<script>
   //constructor function
   function Student(rollno,firstName,lastName) {
      this.rollno = rollno;
      this.firstName = firstName;
      this.lastName = lastName;
      this.fullNameUsingAnonymous = function(){
         setTimeout(function(){
            //creates a new instance of this ,hides outer scope of this
            console.log(this.firstName+ " "+this.lastName)
         },2000)
      }
      this.fullNameUsingArrow = function(){
         setTimeout(()=>{
            //uses this instance of outer scope
            console.log(this.firstName+ " "+this.lastName)
         },3000)
      }
   }
   const s1 = new Student(101,'Mohammad','Mohtashim')
   s1.fullNameUsingAnonymous();
   s1.fullNameUsingArrow();
</script>

當匿名函式與 **setTimeout()** 一起使用時,函式將在 2000 毫秒後被呼叫。將建立一個新的 **“this”** 例項,它會隱藏 Student 函式的例項。因此,**this.firstName** 和 **this.lastName** 的值將為 **undefined**。該函式不使用詞法作用域或當前執行的上下文。這個問題可以使用 **箭頭函式** 來解決。

上述程式碼的輸出如下:

undefined undefined
Mohammad Mohtashim

ES6 - 事件

JavaScript 旨在為您的頁面新增互動性。JavaScript 使用事件機制來實現這一點。**事件** 是文件物件模型 (DOM) 級別 3 的一部分,每個 HTML 元素都包含一組可以觸發 JavaScript 程式碼的事件。

事件是由軟體識別的動作或事件。它可以由使用者或系統觸發。一些常見的事件示例包括使用者單擊按鈕、載入網頁、單擊超連結等等。以下是一些常見的 HTML 事件。

事件處理程式

事件發生時,應用程式會執行一組相關的任務。實現此目的的程式碼塊稱為**事件處理程式 (eventhandler)**。每個HTML元素都有一組與其關聯的事件。我們可以使用事件處理程式在JavaScript中定義如何處理這些事件。

onclick 事件型別

這是最常用的事件型別,它在使用者點選滑鼠左鍵時發生。您可以針對此事件型別新增驗證、警告等。

示例

<html> 
   <head> 
      <script type = "text/javascript">  
         function sayHello() {  
            document.write ("Hello World")  
         }   
      </script> 
   </head> 
   
   <body> 
      <p> Click the following button and see result</p> 
      <input type = "button" onclick = "sayHello()" value = "Say Hello" /> 
   </body> 
</html> 

執行上述程式碼後,將顯示以下輸出。

Onclick Event Type

onsubmit 事件型別

**onsubmit** 事件在您嘗試提交表單時發生。您可以針對此事件型別新增表單驗證。

以下示例顯示如何使用**onsubmit**。這裡我們在將表單資料提交到Web伺服器之前呼叫 validate() 函式。如果 validate() 函式返回 true,則提交表單;否則,不提交資料。

示例

<html> 
   <head> 
      <script type = "text/javascript">  
         function validation() {  
            all validation goes here  
            .........  
            return either true or false  
         }   
      </script> 
   </head> 
   
   <body> 
      <form method = "POST" action = "t.cgi" onsubmit = "return validate()"> 
         .......  
         <input type = "submit" value = "Submit" /> 
      </form> 
   </body> 
</html>

onmouseover 和 onmouseout

這兩個事件型別將幫助您為影像甚至文字建立不錯的效果。當您將滑鼠移到任何元素上時,**onmouseover** 事件觸發;當您將滑鼠從該元素移開時,**onmouseout** 事件觸發。

示例

<html> 
   <head> 
      <script type = "text/javascript"> 
         function over() {  
            document.write ("Mouse Over");  
         }  
         function out() {  
            document.write ("Mouse Out");  
         }  
      </script> 
   </head> 

   <body> 
      <p>Bring your mouse inside the division to see the result:</p> 
      <div onmouseover = "over()" onmouseout = "out()"> 
         <h2> This is inside the division </h2> 
      </div> 
   </body> 
</html>

執行上述程式碼後,將顯示以下輸出。

Onmouseover Onmouseout

HTML 5 標準事件

下表列出了標準HTML 5 事件,供您參考。指令碼指示針對該事件執行的JavaScript函式。

屬性 描述
offline 指令碼 文件離線時觸發
onabort 指令碼 在中止事件時觸發
onafterprint 指令碼 文件列印後觸發
onbeforeonload 指令碼 文件載入前觸發
onbeforeprint 指令碼 文件列印前觸發
onblur 指令碼 視窗失去焦點時觸發
oncanplay 指令碼 媒體可以開始播放時觸發,但可能需要停止緩衝
oncanplaythrough 指令碼 媒體可以播放到結尾時觸發,無需停止緩衝
onchange 指令碼 元素更改時觸發
onclick 指令碼 滑鼠點選時觸發
oncontextmenu 指令碼 觸發上下文選單時觸發
ondblclick 指令碼 滑鼠雙擊時觸發
ondrag 指令碼 拖動元素時觸發
ondragend 指令碼 拖動操作結束時觸發
ondragenter 指令碼 將元素拖動到有效的放置目標時觸發
ondragleave 指令碼 元素離開有效的放置目標時觸發
ondragover 指令碼 將元素拖動到有效的放置目標上方時觸發
ondragstart 指令碼 拖動操作開始時觸發
ondrop 指令碼 拖動元素被放下時觸發
ondurationchange 指令碼 媒體長度更改時觸發
onemptied 指令碼 媒體資源元素突然變空時觸發
onended 指令碼 媒體播放結束時觸發
onerror 指令碼 發生錯誤時觸發
onfocus 指令碼 視窗獲得焦點時觸發
onformchange 指令碼 表單更改時觸發
onforminput 指令碼 表單獲得使用者輸入時觸發
onhaschange 指令碼 文件已更改時觸發
oninput 指令碼 元素獲得使用者輸入時觸發
oninvalid 指令碼 元素無效時觸發
onkeydown 指令碼 按下鍵時觸發
onkeypress 指令碼 按下並釋放鍵時觸發
onkeyup 指令碼 釋放鍵時觸發
onload 指令碼 文件載入時觸發
onloadeddata 指令碼 媒體資料載入時觸發
onloadedmetadata 指令碼 媒體元素的持續時間和其他媒體資料載入時觸發
onloadstart 指令碼 瀏覽器開始載入媒體資料時觸發
onmessage 指令碼 觸發訊息時觸發
onmousedown 指令碼 按下滑鼠按鈕時觸發
onmousemove 指令碼 滑鼠指標移動時觸發
onmouseout 指令碼 滑鼠指標移出元素時觸發
onmouseover 指令碼 滑鼠指標移到元素上時觸發
onmouseup 指令碼 釋放滑鼠按鈕時觸發
onmousewheel 指令碼 旋轉滑鼠滾輪時觸發
onoffline 指令碼 文件離線時觸發
ononline 指令碼 文件上線時觸發
onpagehide 指令碼 視窗隱藏時觸發
onpageshow 指令碼 視窗變為可見時觸發
onpause 指令碼 媒體資料暫停時觸發
onplay 指令碼 媒體資料即將開始播放時觸發
onplaying 指令碼 媒體資料已開始播放時觸發
onpopstate 指令碼 視窗的歷史記錄更改時觸發
onprogress 指令碼 瀏覽器正在獲取媒體資料時觸發
onratechange 指令碼 媒體資料的播放速率更改時觸發
onreadystatechange 指令碼 就緒狀態更改時觸發
onredo 指令碼 文件執行重做操作時觸發
onresize 指令碼 視窗大小調整時觸發
onscroll 指令碼 滾動元素的捲軸時觸發
onseeked 指令碼 媒體元素的 seeking 屬性不再為 true,並且搜尋已結束時觸發
onseeking 指令碼 媒體元素的 seeking 屬性為 true,並且搜尋已開始時觸發
onselect 指令碼 選擇元素時觸發
onstalled 指令碼 獲取媒體資料時發生錯誤時觸發
onstorage 指令碼 文件載入時觸發
onsubmit 指令碼 提交表單時觸發
onsuspend 指令碼 瀏覽器一直在獲取媒體資料,但在獲取整個媒體檔案之前停止時觸發
ontimeupdate 指令碼 媒體更改其播放位置時觸發
onundo 指令碼 文件執行撤消操作時觸發
onunload 指令碼 使用者離開文件時觸發
onvolumechange 指令碼 媒體更改音量時觸發,將音量設定為“靜音”時也會觸發
onwaiting 指令碼 媒體已停止播放,但預計會恢復播放時觸發

ES6 - Cookie

Web瀏覽器和伺服器使用HTTP協議進行通訊。HTTP是無狀態協議,即它不維護客戶端在客戶端發出的多個請求中的資料。客戶端和伺服器之間完整的請求-響應週期定義為**會話 (session)**。Cookie是瀏覽器用於儲存與使用者會話相關的資料的預設機制。

它是如何工作的?

您的伺服器以Cookie的形式向訪問者的瀏覽器傳送一些資料。瀏覽器可能會接受Cookie。如果接受,它將作為純文字記錄儲存在訪問者的硬碟驅動器上。現在,當訪問者訪問您網站上的另一個頁面時,瀏覽器會將相同的Cookie傳送到伺服器以進行檢索。檢索後,您的伺服器就會知道/記住之前儲存的內容。

Cookie是5個可變長度欄位的純文字資料記錄。

  • **Expires** - Cookie將過期的日期。如果為空,則Cookie將在訪問者退出瀏覽器時過期。

  • **Domain** - 您網站的域名。

  • **Path** - 設定Cookie的目錄或網頁的路徑。如果要從任何目錄或頁面檢索Cookie,則此路徑可以為空。

  • **Secure** - 如果此欄位包含單詞“secure”,則只能使用安全伺服器檢索Cookie。如果此欄位為空,則不存在此類限制。

  • **Name = Value** - Cookie以鍵值對的形式設定和檢索。

Cookie最初是為CGI程式設計設計的。Cookie中包含的資料會在Web瀏覽器和Web伺服器之間自動傳輸,因此伺服器上的CGI指令碼可以讀取和寫入儲存在客戶端的Cookie值。

JavaScript還可以使用Document物件的cookie屬性操作Cookie。JavaScript可以讀取、建立、修改和刪除適用於當前網頁的Cookie。

儲存Cookie

建立Cookie的最簡單方法是為**document.cookie**物件賦值一個字串值,如下所示。

"document.cookie = "key1 = value1; key2 = value2; expires = date";

這裡,“expires”屬性是可選的。如果您為該屬性提供有效的日期或時間,則Cookie將在給定的日期或時間過期,此後將無法訪問Cookie的值。

**注意** - Cookie值可能不包含分號、逗號或空格。因此,您可能需要使用JavaScript的**escape()**函式在將值儲存到Cookie之前對其進行編碼。如果這樣做,在讀取Cookie值時,您還必須使用相應的**unescape()**函式。

示例

<html> 
   <head> 
      <script type = "text/javascript">  
         function WriteCookie() {  
            if( document.myform.customer.value == "" ){  
               alert ("Enter some value!");  
               return;  
            }  
            cookievalue =  escape(document.myform.customer.value) + ";";  
            document.cookie = "name = " + cookievalue;  
            document.write ("Setting Cookies : " + "name = " + cookievalue );  
         }  
      </script> 
   </head> 
      
   <body> 
      <form name = "myform" action = ""> 
         Enter name: <input type = "text" name = "customer"/> 
         <input type = "button" value = "Set" onclick = "WriteCookie();"/> 
      </form> 
   </body> 
</html>

執行上述程式碼後,將顯示以下輸出。

Cookies

現在您的計算機上有一個名為name的Cookie。您可以使用多個用逗號分隔的鍵=值對設定多個Cookie。

讀取Cookie

讀取Cookie與寫入Cookie一樣簡單,因為**document.cookie**物件的值就是Cookie。因此,您可以隨時使用此字串訪問Cookie。**document.cookie**字串將保留用分號分隔的鍵=值對列表,其中鍵是Cookie的名稱,值是其字串值。

您可以使用字串的**split()**函式將字串分解為鍵和值,如下例所示。

示例

<html> 
   <head> 
      <script type = "text/javascript"> 
         function ReadCookie() {  
            var allcookies  =  document.cookie;  
            document.write ("All Cookies : " + allcookies ); 
         } 
         // Get all the cookies pairs in an array  
         cookiearray = allcookies.split(';');  
         
         // Now take key value pair out of this array  
         for(var i = 0; i<cookiearray.length; i++) {  
            name  =  cookiearray[i].split('=')[0];  
            value = cookiearray[i].split('=')[1];  
            document.write ("Key is : " + name + " and Value is : " + value); 
         }  
      </script> 
   </head> 

   <body> 
      <form name = "myform" action = ""> 
         <p> click the following button and see the result:</p> 
         <input type = "button" value = "Get Cookie" onclick = "ReadCookie()"/> 
      </form> 
   </body> 
</html> 

**注意** - 這裡,length是Array類的⼀種⽅法,⽤於返回陣列的長度。

您的計算機上可能已經設定了其他一些Cookie。以上程式碼將顯示您計算機上設定的所有Cookie。

執行上述程式碼後,將顯示以下輸出。

Reading Cookies

設定Cookie過期日期

您可以透過設定過期日期並在Cookie中儲存過期日期來延長Cookie的使用壽命,使其超過當前瀏覽器會話。這可以透過將“expires”屬性設定為日期和時間來完成。以下示例說明如何將Cookie的過期日期延長1個月。

示例

<html> 
   <head> 
      <script type = "text/javascript"> 
         function WriteCookie() {  
            var now = new Date();  
            now.setMonth( now.getMonth() + 1 );  
            cookievalue = escape(document.myform.customer.value) + ";"  
            document.cookie = "name = " + cookievalue;  
            document.cookie = "expires = " + now.toUTCString() + ";"  
            document.write ("Setting Cookies : " + "name = " + cookievalue );  
         } 
      </script> 
   </head> 

   <body> 
      <form name = "formname" action = ""> 
         Enter Cookie Name: <input type = "text" name = "customer"/> 
         <input type = "button" value = "Set Cookie" onclick = "WriteCookie()"/> 
      </form> 
   </body> 
</html> 

執行上述程式碼後,將顯示以下輸出。

Cookies Expiry Date

刪除Cookie

有時您可能想要刪除Cookie,以便後續嘗試讀取Cookie時返回空值。為此,您只需要將過期日期設定為過去的時間即可。以下示例說明如何透過將Cookie的過期日期設定為當前日期前一個月來刪除Cookie。

示例

<html> 
   <head> 
      <script type = "text/javascript"> 
         function WriteCookie() {  
            var now = new Date();  
            now.setMonth( now.getMonth() - 1 );  
            cookievalue = escape(document.myform.customer.value) + ";" 
            document.cookie = "name=" + cookievalue;  
            document.cookie = "expires = " + now.toUTCString() + ";"  
            document.write("Setting Cookies : " + "name = " + cookievalue );  
         }  
      </script> 
   </head> 

   <body> 
      <form name = "formname" action = ""> 
         Enter Cookie Name: <input type = "text" name = "customer"/> 
         <input type = "button" value = "Set Cookie" onclick = "WriteCookie()"/> 
      </form> 
   </body> 
</html>

執行上述程式碼後,將顯示以下輸出。

Deleting Cookie

ES6 - 頁面跳轉

**重定向 (Redirect)** 是一種將使用者和搜尋引擎傳送到與他們最初請求的URL不同的URL的方法。頁面重定向是一種自動將一個網頁重定向到另一個網頁的方法。重定向的頁面通常位於同一網站上,也可以位於不同的網站或Web伺服器上。

JavaScript頁面重定向

window.location 和 window.location.href

在JavaScript中,您可以使用多種方法將一個網頁重定向到另一個網頁。幾乎所有方法都與**window.location**物件相關,該物件是Window物件的屬性。它可以用來獲取當前的URL地址(網址)以及將瀏覽器重定向到新頁面。就行為而言,這兩種用法相同。**window.location**返回一個物件。如果未設定**.href**,則**window.location**預設為更改引數**.href**。

示例

<!DOCTYPE html> 
<html> 
   <head> 
      <script> 
         function newLocation() { 
            window.location = "http://www.xyz.com"; 
         } 
      </script> 
   </head> 

   <body> 
      <input type = "button" value = "Go to new location" onclick = "newLocation()"> 
   </body> 
</html>

location.replace()

另一個最常用的方法是 `window.location` 物件的 `replace()` 方法,它將用新文件替換當前文件。在 `replace()` 方法中,您可以傳遞一個新的 URL 到 `replace()` 方法,它將執行 HTTP 重定向。

以下是該方法的語法。

window.location.replace("http://www.abc.com

location.assign()

`location.assign()` 方法在瀏覽器視窗中載入一個新文件。

以下是該方法的語法。

window.location.assign("http://www.abc.org"); 

assign() 與 replace()

`assign()` 和 `replace()` 方法的區別在於,`location.replace()` 方法會刪除文件歷史記錄中的當前 URL,因此無法返回到原始文件。在這種情況下,您無法使用瀏覽器的“後退”按鈕。如果您想避免這種情況,應該使用 `location.assign()` 方法,因為它會在瀏覽器中載入一個新文件。

location.reload()

`location.reload()` 方法重新載入瀏覽器視窗中的當前文件。

以下是該方法的語法。

window.location.reload("http://www.yahoo.com");

window.navigate()

`window.navigate()` 方法類似於為 `window.location.href` 屬性賦值。因為它只在 MS Internet Explorer 中可用,所以您應該避免在跨瀏覽器開發中使用它。

以下是該方法的語法。

window.navigate("http://www.abc.com"); 

重定向和搜尋引擎最佳化

如果您想通知搜尋引擎 (SEO) 您的 URL 轉發,您應該將 `rel="canonical"` 元標記新增到您的網站頭部,因為搜尋引擎不會分析 JavaScript 來檢查重定向。

以下是該方法的語法。

<link rel = "canonical" href = "http://abc.com/" />

ES6 - 對話方塊

JavaScript 支援三種重要的對話方塊型別。這些對話方塊可用於發出警報,或獲取對任何輸入的確認,或從使用者那裡獲得某種輸入。在這裡,我們將逐一討論每個對話方塊。

警告對話方塊

警告對話方塊主要用於向用戶傳送警告訊息。例如,如果一個輸入欄位要求輸入一些文字,但使用者沒有提供任何輸入,那麼作為驗證的一部分,您可以使用警告框來發送警告訊息。

儘管如此,警告框仍然可以用於更友好的訊息。警告框只提供一個“確定”按鈕供選擇並繼續。

示例

<html> 
   <head> 
      <script type = "text/javascript"> 
         function Warn() {  
            alert ("This is a warning message!");  
            document.write ("This is a warning message!");  
         } 
      </script> 
   </head> 

   <body> 
      <p>Click the following button to see the result: </p> 
      <form> 
         <input type = "button" value = "Click Me" onclick = "Warn();" /> 
      </form> 
   </body> 
</html> 

執行上述程式碼後,將顯示以下輸出。

alert dialogue box

確認對話方塊

確認對話方塊主要用於獲取使用者對任何選項的同意。它顯示一個帶有兩個按鈕的對話方塊:“確定”和“取消”。

如果使用者單擊“確定”按鈕,則 `confirm()` 視窗方法將返回 `true`。如果使用者單擊“取消”按鈕,則 `confirm()` 返回 `false`。您可以按如下方式使用確認對話方塊。

示例

<html> 
   <head> 
      <script type = "text/javascript"> 
         function getConfirmation(){  
            var retVal = confirm("Do you want to continue ?");  
            
            if( retVal == true ){  
               document.write ("User wants to continue!");  
               return true;  
            } else {  
               Document.write ("User does not want to continue!");  
               return false;  
            }  
         }  
      </script> 
   </head> 

   <body> 
      <p>Click the following button to see the result: </p> 
      <form> 
         <input type = "button" value = "Click Me" onclick = "getConfirmation();" /> 
      </form> 
   </body> 
</html> 

執行上述程式碼後,將顯示以下輸出。

confirmation dialogue box

提示對話方塊

當您想彈出一個文字框以獲取使用者輸入時,提示對話方塊非常有用。因此,它使您能夠與使用者互動。使用者需要填寫欄位,然後單擊“確定”。

此對話方塊使用名為 `prompt()` 的方法顯示,該方法接受兩個引數:(i)您要在文字框中顯示的標籤;(ii)要在文字框中顯示的預設字串。

此對話方塊有兩個按鈕:“確定”和“取消”。如果使用者單擊“確定”按鈕,則 `prompt()` 視窗方法將返回文字框中輸入的值。如果使用者單擊“取消”按鈕,則 `prompt()` 視窗方法將返回 `null`。

示例

<html> 
   <head> 
      <script type = "text/javascript"> 
         function getValue(){  
            var retVal = prompt("Enter your name : ", "your name here");  
            document.write("You have entered : " + retVal);  
         }  
      </script> 
   </head> 

   <body> 
      <p>Click the following button to see the result: </p> 
      <form> 
         <input type = "button" value = "Click Me" onclick = "getValue();" /> 
      </form> 
   </body> 
</html> 

執行上述程式碼後,將顯示以下輸出。

prompt dialogue box

ES6 - void 關鍵字

`void` 是 JavaScript 中一個重要的關鍵字,可以用作一元運算子,出現在其單個運算元之前,該運算元可以是任何型別。此運算子指定要計算的表示式,但不返回值。該運算子計算給定的表示式,然後返回 `undefined`。

以下是該方法的語法。

void expression

Void 和立即呼叫函式表示式

使用立即呼叫函式表示式時,`void` 可用於強制將 `function` 關鍵字視為表示式而不是宣告。

考慮以下示例:

void function iife_void() { 
   var msg = function () {console.log("hello world")}; 
   msg(); 
}();

執行上述程式碼後,將顯示以下輸出。

hello world

Void 和 JavaScript URI

`JavaScript: URI` 是 HTML 頁面中常見的語法。瀏覽器會計算 URI 並用返回的值替換頁面的內容。除非返回的值是 `undefined`,否則情況屬實。此運算子最常見的用途是在客戶端 `JavaScript: URL` 中,它允許您計算表示式的副作用,而不會讓瀏覽器顯示計算表示式的值。

考慮以下程式碼片段:

<a href = "javascript:void(javascript:alert('hello world!!'))"> 
  Click here to do nothing 
</a> 
<br/><br/><br/> 
<a href = "javascript:alert('hello');">Click here for an alert</a>

將上述檔案儲存為 HTML 文件,並在瀏覽器中開啟它。第一個超連結在單擊時計算 `javascript:alert(“hello”)` 並將其傳遞給 `void()` 運算子。但是,由於 `void` 運算子返回 `undefined`,因此頁面上不會顯示任何結果。

另一方面,單擊第二個超連結時會顯示一個警告對話方塊。

ES6 - 頁面列印

很多時候,您可能希望在網頁上放置一個按鈕,以便透過實際印表機列印該網頁的內容。JavaScript 幫助您使用 `window` 物件的 `print` 函式實現此功能。

JavaScript `print` 函式 `window.print()` 在執行時會列印當前網頁。您可以使用 `onclick` 事件直接呼叫此函式,如下例所示。

示例

<html> 
   <body> 
      <form> 
         <input type = "button" value = "Print" onclick = "window.print()"/> 
      </form> 
   </body> 
</html>

執行上述程式碼後,將顯示以下輸出。

page printing

ES6 - 物件

JavaScript 支援擴充套件資料型別。JavaScript 物件是定義自定義資料型別的好方法。

一個 `物件` 是一個例項,它包含一組鍵值對。與原始資料型別不同,物件可以表示多個或複雜的值,並且可以在其生命週期內發生變化。值可以是標量值、函式甚至是其他物件的陣列。

將進一步討論定義物件的語法變體。

物件初始化器

與原始型別一樣,物件也有字面量語法:`花括號` ({和})。以下是定義物件的語法。

var identifier = {
   Key1:value, Key2: function () { 
      //functions 
   }, 
   Key3: [“content1”,” content2”] 
} 

物件的內容稱為 `屬性`(或成員),屬性由 `名稱`(或鍵)和 `` 組成。屬性名必須是字串或符號,值可以是任何型別(包括其他物件)。

與所有 JavaScript 變數一樣,物件名(可以是普通變數)和屬性名都區分大小寫。您可以使用簡單的點表示法訪問物件的屬性。

以下是訪問物件屬性的語法。

objectName.propertyName 

示例:物件初始化器

var person = { 
   firstname:"Tom", 
   lastname:"Hanks", 
   func:function(){return "Hello!!"},    
}; 
//access the object values 
console.log(person.firstname)   
console.log(person.lastname) 
console.log(person.func())

上述示例定義了一個物件 `person`。該物件具有三個屬性。第三個屬性是指向一個函式。

執行上述程式碼後,將顯示以下輸出。

Tom 
Hanks 
Hello!!

在 ES6 中,為與屬性名稱匹配的屬性值賦值時,您可以省略屬性值。

示例

var foo = 'bar' 
var baz = { foo } 
console.log(baz.foo)

上面的程式碼片段定義了一個物件 `baz`。該物件具有一個屬性 `foo`。此處省略屬性值,因為 ES6 會隱式地將變數 `foo` 的值分配給物件的鍵 `foo`。

以下是上述程式碼的 ES5 等效程式碼。

var foo = 'bar' 
var baz = { foo:foo } 
console.log(baz.foo)

執行上述程式碼後,將顯示以下輸出。

bar

使用此簡寫語法,JS 引擎會在包含作用域中查詢具有相同名稱的變數。如果找到,則將該變數的值賦給屬性。如果找不到,則會丟擲 `ReferenceError`。

`Object()` 建構函式

JavaScript 提供了一個名為 `Object()` 的特殊建構函式來構建物件。`new` 運算子用於建立物件的例項。要建立物件,`new` 運算子後跟構造方法。

以下是定義物件的語法。

var obj_name = new Object(); 
obj_name.property = value;    
OR             
obj_name["key"] = value 

以下是訪問屬性的語法。

Object_name.property_key                    
OR              
Object_name["property_key"]

示例

var myCar = new Object(); 
myCar.make = "Ford"; //define an object 
myCar.model = "Mustang"; 
myCar.year = 1987;  

console.log(myCar["make"]) //access the object property 
console.log(myCar["model"]) 
console.log(myCar["year"])

執行上述程式碼後,將顯示以下輸出。

Ford 
Mustang 
1987

物件的未賦值屬性為 `undefined`。

示例

var myCar = new Object(); 
myCar.make = "Ford"; 
console.log(myCar["model"])

執行上述程式碼後,將顯示以下輸出。

undefined

注意 - 物件屬性名可以是任何有效的 JavaScript 字串,或者任何可以轉換為字串的內容,包括空字串。但是,任何不是有效 JavaScript 識別符號的屬性名(例如,具有空格或連字元,或者以數字開頭的屬性名)只能使用方括號表示法訪問。

也可以使用儲存在變數中的字串值來訪問屬性。換句話說,物件的屬性鍵可以是動態值。例如:一個變數。以下示例說明了這一概念。

示例

var myCar = new Object()  
var propertyName = "make"; 
myCar[propertyName] = "Ford"; 
console.log(myCar.make)

執行上述程式碼後,將顯示以下輸出。

Ford

建構函式

可以使用以下兩個步驟建立物件:

步驟 1 - 透過編寫建構函式來定義物件型別。

以下是該方法的語法。

function function_name() { 
   this.property_name = value 
}

`this` 關鍵字引用當前正在使用的物件,並定義物件的屬性。

步驟 2 - 使用 `new` 語法建立物件的例項。

var Object_name= new function_name() 
//Access the property value  

Object_name.property_name

`new` 關鍵字呼叫函式建構函式並初始化函式的屬性鍵。

示例 - 使用函式建構函式

function Car() { 
   this.make = "Ford" 
   this.model = "F123" 
}  
var obj = new Car() 
console.log(obj.make) 
console.log(obj.model)

上述示例使用函式建構函式來定義物件。

執行上述程式碼後,將顯示以下輸出。

Ford 
F123 

總是可以向先前定義的物件新增新屬性。例如,考慮以下程式碼片段:

function Car() { 
   this.make = "Ford" 
} 
var obj = new Car() 
obj.model = "F123" 
console.log(obj.make) 
console.log(obj.model)

執行上述程式碼後,將顯示以下輸出。

Ford 
F123

`Object.create` 方法

也可以使用 `Object.create()` 方法建立物件。它允許您建立所需物件的原型,而無需定義建構函式。

示例

var roles = { 
   type: "Admin", // Default value of properties 
   displayType : function() {  
      // Method which will display type of role 
      console.log(this.type); 
   } 
}  
// Create new role type called super_role 
var super_role = Object.create(roles); 
super_role.displayType(); // Output:Admin  

// Create new role type called Guest 
var guest_role = Object.create(roles); 
guest_role.type = "Guest"; 
guest_role.displayType(); // Output:Guest

上述示例定義了一個物件 `roles` 併為屬性設定預設值。建立了兩個新例項,它們覆蓋了物件的預設屬性值。

執行上述程式碼後,將顯示以下輸出。

Admin 
Guest

`Object.assign()` 函式

`Object.assign()` 方法用於將一個或多個源物件的全部可列舉自身屬性的值複製到目標物件。它將返回目標物件。

以下是該方法的語法。

Object.assign(target, ...sources)    

示例 - 克隆物件

"use strict" 
var det = { name:"Tom", ID:"E1001" }; 
var copy = Object.assign({}, det); 
console.log(copy);  
for (let val in copy) { 
   console.log(copy[val]) 
}

執行上述程式碼後,將顯示以下輸出。

Tom 
E1001

示例 - 合併物件

var o1 = { a: 10 }; 
var o2 = { b: 20 }; 
var o3 = { c: 30 }; 
var obj = Object.assign(o1, o2, o3); 
console.log(obj);  
console.log(o1);

執行上述程式碼後,將顯示以下輸出。

{ a: 10, b: 20, c: 30 } 
{ a: 10, b: 20, c: 30 }

注意 - 與複製物件不同,當物件合併時,較大的物件不會維護屬性的新副本。相反,它持有原始物件中包含的屬性的引用。以下示例解釋了這個概念。

var o1 = { a: 10 }; 
var obj = Object.assign(o1); 
obj.a++ 
console.log("Value of 'a' in the Merged object after increment  ") 
console.log(obj.a);  
console.log("value of 'a' in the Original Object after increment ") 
console.log(o1.a);

執行上述程式碼後,將顯示以下輸出。

Value of 'a' in the Merged object after increment 
11  
value of 'a' in the Original Object after increment 
11 

刪除屬性

您可以使用 `delete` 運算子刪除屬性。以下程式碼顯示瞭如何刪除屬性。

示例

// Creates a new object, myobj, with two properties, a and b. 
var myobj = new Object; 
myobj.a = 5; 
myobj.b = 12; 

// Removes the ‘a’ property 
delete myobj.a; 
console.log ("a" in myobj) // yields "false"

執行上述程式碼後,將顯示以下輸出。

false

程式碼片段從物件中刪除屬性。該示例列印 `false`,因為 `in` 運算子在物件中找不到該屬性。

比較物件

在 JavaScript 中,物件是引用型別。兩個不同的物件永遠不相等,即使它們具有相同的屬性。這是因為它們指向完全不同的記憶體地址。只有那些共享公共引用的物件在比較時才會返回 `true`。

示例 1 - 不同的物件引用

var val1 = {name: "Tom"}; 
var val2 = {name: "Tom"}; 
console.log(val1 == val2)  // return false 
console.log(val1 === val2)  // return false

在上述示例中,`val1` 和 `val2` 是兩個不同的物件,它們引用兩個不同的記憶體地址。因此,在比較相等性時,運算子將返回 `false`。

示例 2 - 單個物件引用

var val1 = {name: "Tom"}; 
var val2 = val1  

console.log(val1 == val2) // return true 
console.log(val1 === val2) // return true

在上述示例中,`val1` 中的內容被賦給 `val2`,即 `val1` 中屬性的引用與 `val2` 共享。由於物件現在共享對屬性的引用,因此對於引用兩個不同記憶體地址的兩個不同的物件,相等運算子將返回 `true`。因此,在比較相等性時,運算子將返回 `false`。

物件解構

`解構` 一詞指的是分解實體的結構。JavaScript 中的解構賦值語法可以將資料從陣列或物件提取到不同的變數中。以下示例說明了這一點。

示例 1

解構物件時,變數名和物件屬性名必須匹配。

<script>
let student = {
   rollno:20,
   name:'Prijin',
   cgpa:7.2
}

//destructuring to same property name
   let {name,cgpa} = student
   console.log(name)
   console.log(cgpa)

//destructuring to different name
   let {name:student_name,cgpa:student_cgpa}=student
   console.log(student_cgpa)
   console.log("student_name",student_name)
</script>

上述程式碼的輸出將如下所示:

Prijin
7.2
7.2
student_name Prijin

示例 2

如果變數和賦值在兩個不同的步驟中,則解構物件語法將被括號 `()` 包圍,如示例 `({rollno} = student)` 所示:

<script>
   let student = {
      rollno:20,
      name:'Prijin',
      cgpa:7.2
   }

   // destructuring to already declared variable
   let rollno;
   ({rollno} = student)
   console.log(rollno)

   // assign default values to variables

   let product ={ id:1001,price:2000} //discount is not product property
   let {id,price,discount=.10} = product
   console.log(id)
   console.log(price)
   console.log(discount)
</script>

上述程式碼的輸出如下所示:

20
1001
2000
0.1

示例 3

以下示例展示了使用 `rest` 運算子進行 `解構` 以及如何解構巢狀物件。

<script>
   // rest operator with object destructuring
   let customers= {
      c1:101,
      c2:102,
      c3:103
   }

   let {c1,...others} = customers
   console.log(c1)
   console.log(others)

   //nested objects
   let emp = {
      id:101,
      address:{
         city:'Mumbai',
         pin:1234
      }
   }
   let {address} = emp;

   console.log(address)
   let {address:{city,pin}} = emp
   console.log(city)
</script>

上述程式碼的輸出如下所示:

101
{c2: 102, c3: 103}
{city: "Mumbai", pin: 1234}
Mumbai

ES6 - 數字

Number 物件表示數值日期,可以是整數或浮點數。通常,您不需要擔心 Number 物件,因為瀏覽器會自動將數字字面量轉換為 Number 類例項。

以下是建立數字物件的語法。

var val = new Number(number); 

number的位置,如果提供任何非數字引數,則該引數無法轉換為number,它返回NaN(非數字)。

Number 屬性

序號 屬性 & 描述
1 Number.EPSILON

兩個可表示數字之間的最小間隔。

2 Number.MAX_SAFE_INTEGER

JavaScript 中的最大安全整數 (2^53 - 1)。

3 Number.MAX_VALUE

最大的正可表示數。

4 MIN_SAFE_INTEGER

JavaScript 中的最小安全整數 (-(2^53 - 1))。

5 Number.MIN_VALUE

最小的正可表示數——也就是最接近零的正數(但並非零)

6 Number.NaN

特殊的“非數字”值

7 Number.NEGATIVE_INFINITY

表示負無窮大的特殊值;溢位時返回

8 Number.POSITIVE_INFINITY

表示無窮大的特殊值;溢位時返回

9 Number.prototype

表示無窮大的特殊值;溢位時返回

Number 方法

序號 方法 & 描述
1 Number.isNaN()

確定傳遞的值是否為 NaN。

2 Number.isFinite()

確定傳遞的值是否為有限數。

3 Number.isInteger()

確定傳遞的值是否為整數。

4 Number.isSafeInteger()

確定傳遞的值是否為安全整數(介於 -(253 - 1) 和 253 - 1 之間的數)

5 Number.parseFloat()

值與全域性物件的 parseFloat() 相同

6 Number.parseInt()

值與全域性物件的 parseInt() 相同

Number 例項方法

Number 物件只包含作為每個物件定義一部分的預設方法。

序號 例項方法 & 描述
1 toExponential()

返回一個以指數表示法表示數字的字串

2 toFixed()

返回一個以定點表示法表示數字的字串

3 toLocaleString()

返回一個包含此數字的語言敏感表示形式的字串

4 toPrecision()

返回一個以定點或指數表示法表示指定精度的數字的字串

5 toString()

返回以指定的基數(進位制)表示指定物件的字串。

6 valueOf()

返回指定物件的原始值。

二進位制和八進位制字面量

在 ES6 之前,關於整數的二進位制或八進位制表示的最佳方法是將它們與基數一起傳遞給 parseInt()。在 ES6 中,您可以使用 0b 和 0o 字首分別表示二進位制和八進位制整數字面量。同樣,要表示十六進位制值,請使用0x字首。

字首可以是大寫或小寫。但是,建議堅持使用小寫版本。

示例 - 二進位制表示

console.log(0b001) 
console.log(0b010) 
console.log(0b011) 
console.log(0b100)

執行上述程式碼後,將顯示以下輸出。

1 
2 
3 
4

示例 - 八進位制表示

console.log(0o010)
console.log(0o100)

執行上述程式碼後,將顯示以下輸出。

8
64

示例 - 十六進位制表示

console.log(0x010)
console.log(0x100)

執行上述程式碼後,將顯示以下輸出。

255
384

物件字面量擴充套件

ES6 在物件字面量宣告中引入了以下語法更改

  • 物件屬性初始化程式語法
  • 計算屬性語法
  • 簡潔方法語法

物件屬性初始化程式

物件屬性初始化程式語法中,我們可以直接用變數初始化物件。這將建立屬性,其名稱與變數的名稱相同。

<script>
   let firstName = 'Tutorials',lastName='Point'
   let company = {
      firstName,
      lastName
   }
   console.log(company)
   console.log(company.firstName)
   console.log(company.lastName)
</script>

上述程式碼的輸出將如下所示:

{firstName: "Tutorials", lastName: "Point"}
Tutorials
Point

計算屬性

計算屬性語法中,物件的屬性可以根據變數動態建立。在下面的示例中,名為suffix的變數用於計算company物件。

<script>
   let suffix = 'Name'
   let company = {
      ['first'+suffix]:'Tutorials',
      ['last'+suffix]:'Point'
   }
   console.log(company)
   console.log(company['firstName'])
   console.log(company['lastName'])
</script>

上述程式碼的輸出將如下所示:

{firstName: "Tutorials", lastName: "Point"}
Tutorials
Point

簡潔方法語法中,我們可以直接使用和宣告方法,而無需使用function關鍵字。這是一種簡化的語法,用於在物件字面量中包含函式。

<script>
   let firstName = 'Tutorials',lastName='Point'
   let company = {
      firstName,
      lastName,
      getFullName(){
         return this.firstName+" - "+this.lastName
      }
   }
   console.log(company.getFullName())
   console.log(company)
</script>

上述程式碼的輸出如下所示:

Tutorials - Point
{firstName: "Tutorials", lastName: "Point", getFullName: ƒ}

ES6 - 布林值

布林物件表示兩個值,即“true”“false”。如果省略值引數或值為 0、-0、null、false、NaN、undefined 或空字串 (“”),則物件具有 false 的初始值。

使用以下語法建立一個布林物件

var val = new Boolean(value);

布林屬性

以下是布林物件屬性的列表。

序號 屬性 & 描述
1 constructor

返回對建立該物件的 Boolean 函式的引用。

2 prototype

prototype 屬性允許您向物件新增屬性和方法。

布林方法

以下是布林物件的方法及其描述的列表。

序號 方法 & 描述
1 toSource()

返回一個包含布林物件原始碼的字串;您可以使用此字串建立等效的物件。

2 toString()

返回一個“true”或“false”字串,具體取決於物件的值。

3 valueOf()

返回布林物件的原始值。

在以下部分中,我們將檢視一些示例以演示布林方法的使用。

ES6 - 字串

String 物件允許您使用一系列字元;它使用許多輔助方法包裝 JavaScript 的字串原始資料型別。

由於 JavaScript 會自動在字串基元和 String 物件之間進行轉換,因此您可以對字串基元呼叫 String 物件的任何輔助方法。

使用以下語法建立一個 String 物件。

var val = new String(string);

字串引數是一系列已正確編碼的字元。String。

String 屬性

以下是 String 物件屬性及其描述的列表。

序號 屬性 & 描述
1 constructor

返回對建立該物件的 String 函式的引用。

2 length

返回字串的長度。

3 Prototype

prototype 屬性允許您向物件新增屬性和方法。

String 方法

以下是 String 物件中可用方法及其描述的列表。

序號 方法 & 描述
1 charAt()

返回指定索引處的字元。

2 charCodeAt()

返回一個數字,指示給定索引處字元的 Unicode 值。

3 concat()

組合兩個字串的文字並返回一個新字串。

4 indexOf()

返回在呼叫 String 物件中指定值的第一次出現的索引,如果未找到則返回 -1。

5 lastIndexOf()

返回在呼叫 String 物件中指定值的最後一次出現的索引,如果未找到則返回 -1。

6 localeCompare()

返回一個數字,指示參考字串在排序順序中是在給定字串之前、之後還是與之相同。

7 match()

用於將正則表示式與字串匹配。

8 replace()

用於查詢正則表示式和字串之間的匹配項,並將匹配的子字串替換為新的子字串。

9 search()

執行對正則表示式和指定字串之間匹配項的搜尋。

10 slice()

提取字串的一部分並返回一個新字串。

11 split()

透過將字串分成子字串,將 String 物件拆分為字串陣列。

12 substr()

返回從指定位置開始的指定數量字元的字串中的字元。

13 substring()

返回字串中兩個索引之間的字元。

14 toLocaleLowerCase()

字串中的字元轉換為小寫,同時尊重當前區域設定。

15 toLocaleUpperCase()

字串中的字元轉換為大寫,同時尊重當前區域設定。

16 toLowerCase()

返回轉換為小寫的呼叫字串值。

17 toString()

返回表示指定物件的字串。

18 toUpperCase()

返回轉換為大寫的呼叫字串值。

19 valueOf()

返回指定物件的原始值。

ES6 - Symbol

Symbol 簡介

ES6 引入了一種稱為 Symbol 的新的原始型別。它們有助於在 JavaScript 程式中實現超程式設計。

語法

const mySymbol = Symbol()
const mySymbol = Symbol(stringDescription)

符號只是您可以儲存一些資料的記憶體片段。每個符號都將指向不同的記憶體位置。Symbol() 建構函式返回的值是唯一且不可變的。

示例

讓我們透過一個示例來理解這一點。最初,我們建立了兩個沒有描述的符號,然後是具有相同描述的符號。在這兩種情況下,當比較符號時,相等運算子都將返回 false。

<script>
   const s1 = Symbol();
   const s2 = Symbol();
   console.log(typeof s1)
   console.log(s1===s2)
   const s3 = Symbol("hello");//description
   const s4 = Symbol("hello");
   console.log(s3)
   console.log(s4)
   console.log(s3==s4)
</script>

上述程式碼的輸出如下所示:

symbol
false
Symbol(hello)
Symbol(hello)
false
序號 屬性 & 描述
1 Symbol.for(key)

在符號登錄檔中搜索具有給定鍵的現有符號並返回它(如果找到)。否則,將使用此鍵在全域性符號登錄檔中建立一個新的符號。

2 Symbol.keyFor(sym)

從全域性符號登錄檔中檢索給定符號的共享符號鍵。

Symbol & 類

符號可以與類一起使用來定義類中的屬性。優點是,如果屬性是如下所示的符號,則只有在知道符號名稱的情況下才能在包外部訪問該屬性。因此,當使用符號作為屬性時,資料得到了更好的封裝。

示例

<script>
   const COLOR = Symbol()
   const MODEL = Symbol()
   const MAKE = Symbol()
   class Bike {
      constructor(color ,make,model){
      this[COLOR] = color;
      this[MAKE] = make;
      this[MODEL] = model;
   }
}
let bike = new Bike('red','honda','cbr')
console.log(bike)
//property can be accessed ony if symbol name is known
console.log(bike[COLOR])
</script>

上述程式碼的輸出將如下所示:

Bike {Symbol(): "red", Symbol(): "honda", Symbol(): "cbr"}
red

ES6 - 新的字串方法

以下是方法及其描述的列表。

序號 方法 & 描述
1 String.prototype.startsWith(searchString, position = 0)

如果接收器以 searchString 開頭,則返回 true;position 允許您指定要檢查的字串的起始位置。

2 String.prototype.endsWith(searchString, endPosition = searchString.length)

如果接收器以 searchString 開頭,則返回 true;position 允許您指定要檢查的字串的起始位置。

3 String.prototype.includes(searchString, position = 0)

如果接收器包含 searchString,則返回 true;position 允許您指定要搜尋的字串的起始位置。

4 String.prototype.repeat(count)

返回接收器,連線 count 次。

模板字面量

模板字面量是允許嵌入表示式的字串字面量。模板字串使用反引號 (``) 而不是單引號或雙引號。因此,模板字串可以寫成:

var greeting = `Hello World!`; 

字串插值和模板字面量

模板字串可以使用 ${ } 語法使用佔位符進行字串替換,如下所示。

示例 1

var name = "Brendan"; 
console.log('Hello, ${name}!');

執行上述程式碼後,將顯示以下輸出。

Hello, Brendan!

示例 2:模板字面量和表示式

var a = 10; 
var b = 10; 
console.log(`The sum of ${a} and ${b} is  ${a+b} `);

執行上述程式碼後,將顯示以下輸出。

The sum of 10 and 10 is 20 

示例 3:模板字面量和函式表示式

function fn() { return "Hello World"; } 
console.log(`Message: ${fn()} !!`);

執行上述程式碼後,將顯示以下輸出。

Message: Hello World !!

多行字串和模板字面量

模板字串可以包含多行。

示例

var multiLine = `
   This is 
   a string 
   with multiple 
   lines`; 
console.log(multiLine)

執行上述程式碼後,將顯示以下輸出。

This is 
a string 
with multiple 
line

String.raw()

ES6 包含用於原始字串的標記函式 String.raw,其中反斜槓沒有任何特殊含義。String.raw 使我們能夠像在正則表示式字面量中一樣編寫反斜槓。考慮以下示例。

var text =`Hello \n World` 
console.log(text)  

var raw_text = String.raw`Hello \n World ` 
console.log(raw_text)

執行上述程式碼後,將顯示以下輸出。

Hello 
World 
Hello \n World

標記模板

標記是一個函式,它可以解釋和處理模板字面量。標記出現在模板字面量前面。語法如下所示。

語法

let output_fromTag = tagFunction `Template literal with ${variable1} , ${variable2}`

標記函式實現語法如下:

function tagFunction(literals,...variable_values){
   //process
   return "some result"
}

示例

以下示例定義了一個標記函式myTagFn()。它顯示傳遞給它的引數。顯示後,它將Done返回給呼叫方。

<script>
   function myTagFn(literals,...values){
      console.log("literal values are");
      for(let c of literals){
         console.log(c)
      }

      console.log("variable values are ");
      for(let c of values){
         console.log(c)
      }

      return "Done"
   }
   let company = `TutorialsPoint`
   let company_location = `Mumbai`
   let result = myTagFn `Hello this is ${company} from ${company_location}`

   console.log(result)

</script>

上述程式碼的輸出將如下所示:

//literal
literal values are
Hello this is
from
//values
variable values are
TutorialsPoint
Mumbai
Done

示例

以下標記函式採用模板字面量並將其轉換為大寫,如下所示:

<script>
   function convertToUpperTagFn(literals, ...values) {
      let result = "";
      for (let i = 0; i < literals.length; i++) {
         result += literals[i];
         if (i < values.length) {
            result += values[i];
         }
      }
      return result.toUpperCase();
   }
   let company = `TutorialsPoint`
   let company_location = `Mumbai`
   let result = convertToUpperTagFn `Hello this is ${company} from ${company_location}`

   console.log(result)

</script>

上述程式碼的輸出如下所示:

HELLO THIS IS TUTORIALSPOINT FROM MUMBAI

String.fromCodePoint()

靜態 String.fromCodePoint() 方法返回一個使用指定的 unicode 程式碼點序列建立的字串。如果傳遞無效的程式碼點,則該函式將丟擲 RangeError。

console.log(String.fromCodePoint(42))        
console.log(String.fromCodePoint(65, 90))

執行上述程式碼後,將顯示以下輸出。

* 
AZ

ES6 - 陣列

使用變數儲存值存在以下限制:

  • 變數本質上是標量的。換句話說,變數宣告一次只能包含一個值。這意味著要在程式中儲存 n 個值,需要 n 個變數宣告。因此,當需要儲存更大的值集合時,使用變數是不可行的。

  • 程式中的變數以隨機順序分配記憶體,從而難以按宣告順序檢索/讀取值。

JavaScript 引入了陣列的概念來解決這個問題。

陣列是同構的值集合。簡單來說,陣列是相同資料型別值的集合。它是一種使用者定義型別。

陣列的特性

  • 陣列宣告分配連續的記憶體塊。

  • 陣列是靜態的。這意味著一旦初始化,陣列就不能調整大小。

  • 每個記憶體塊代表一個數組元素。

  • 陣列元素由一個唯一的整數標識,稱為元素的下標/索引。

  • 陣列也像變數一樣,應該在使用前宣告。

  • 陣列初始化是指填充陣列元素。

  • 陣列元素的值可以更新或修改,但不能刪除。

宣告和初始化陣列

要在 JavaScript 中宣告和初始化陣列,請使用以下語法:

var array_name; //declaration 
array_name = [val1,val2,valn..]   //initialization 
OR 
var array_name = [val1,val2…valn]

注意 - [] 對稱為陣列的維度。

例如,像這樣的宣告:var numlist = [2,4,6,8] 將建立一個如下圖所示的陣列。

Initializing Arrays

訪問陣列元素

陣列名稱後跟下標用於引用陣列元素。

以下是該方法的語法。

array_name[subscript]

示例:簡單陣列

var alphas; 
alphas = ["1","2","3","4"] 
console.log(alphas[0]); 
console.log(alphas[1]);

執行上述程式碼後,將顯示以下輸出。

1 
2

示例:單語句宣告和初始化

var nums = [1,2,3,3] 
console.log(nums[0]); 
console.log(nums[1]); 
console.log(nums[2]); 
console.log(nums[3]);

執行上述程式碼後,將顯示以下輸出。

1 
2 
3 
3

陣列物件

也可以使用 Array 物件建立陣列。Array 建構函式可以作為以下引數傳遞:

  • 表示陣列大小的數值;或

  • 逗號分隔值的列表。

以下示例使用此方法建立陣列。

示例

var arr_names = new Array(4)  
for(var i = 0;i<arr_names.length;i++) { 
   arr_names[i] = i * 2 
   console.log(arr_names[i]) 
}

執行上述程式碼後,將顯示以下輸出。

0 
2 
4 
6 

示例:Array 建構函式接受逗號分隔的值

var names = new Array("Mary","Tom","Jack","Jill") 
for(var i = 0;i<names.length;i++) { 
   console.log(names[i]) 
}

執行上述程式碼後,將顯示以下輸出。

Mary 
Tom 
Jack 
Jill

陣列方法

以下是 Array 物件的方法列表及其描述。

序號 方法 & 描述
1 concat()

返回一個新陣列,該陣列由該陣列與其他陣列和/或值連線而成

2 every()

如果此陣列中的每個元素都滿足提供的測試函式,則返回 true。

3 filter()

建立一個新陣列,其中包含此陣列的所有元素,對於這些元素,提供的過濾函式返回 true。

4 forEach()

為陣列中的每個元素呼叫一個函式。

5 indexOf()

返回陣列中等於指定值的元素的第一個(最小)索引,如果未找到則返回 -1。

6 join()

將陣列的所有元素連線到一個字串中。

7 lastIndexOf()

返回陣列中等於指定值的元素的最後一個(最大)索引,如果未找到則返回 -1。

8 map()

建立一個新陣列,其中包含對該陣列中每個元素呼叫提供的函式的結果。

9 pop()

刪除陣列中的最後一個元素並返回該元素。

10 push()

向陣列末尾新增一個或多個元素,並返回陣列的新長度。

11 reduce()

同時對陣列的兩個值(從左到右)應用函式,以將其簡化為單個值。

12 reduceRight()

同時對陣列的兩個值(從右到左)應用函式,以將其簡化為單個值。

13 reverse()

反轉陣列元素的順序——第一個變為最後一個,最後一個變為第一個。

14 shift()

刪除陣列中的第一個元素並返回該元素 slice。

15 slice()

提取陣列的一部分並返回一個新陣列。

16 some()

如果此陣列中的至少一個元素滿足提供的測試函式,則返回 true。

17

toSource()

表示物件的原始碼。

18 sort()

對陣列的元素進行排序。

19 splice()

向陣列新增和/或刪除元素。

20 toString()

返回表示陣列及其元素的字串。

21 unshift()

向陣列前面新增一個或多個元素,並返回陣列的新長度。

ES6 - 陣列方法

以下是 ES6 中引入的一些新的陣列方法。

Array.prototype.find

find 允許你迭代陣列並返回導致給定回撥函式返回 true 的第一個元素。一旦找到元素,函式立即返回。這是一種有效的方法,可以獲取與給定條件匹配的第一個專案。

示例

var numbers = [1, 2, 3]; 
var oddNumber = numbers.find((x) => x % 2 == 1); 
console.log(oddNumber); // 1

執行上述程式碼後,將顯示以下輸出。

1

注意 - ES5 的 filter() 和 ES6 的 find() 不是同義詞。filter 總是返回匹配項的陣列(並將返回多個匹配項),find 總是返回實際的元素。

Array.prototype.findIndex

findIndex 的行為類似於 find,但它不返回匹配的元素,而是返回該元素的索引。

var numbers = [1, 2, 3]; 
var oddNumber = numbers.findIndex((x) => x % 2 == 1); 
console.log(oddNumber); // 0 

上面的例子將返回值 1 的索引 (0) 作為輸出。

Array.prototype.entries

entries 是一個函式,它返回一個 Array Iterator,可用於迴圈遍歷陣列的鍵和值。Entries 將返回一個數組的陣列,其中每個子陣列都是一個 [index, value] 陣列。

var numbers = [1, 2, 3]; 
var val = numbers.entries(); 
console.log(val.next().value);  
console.log(val.next().value);  
console.log(val.next().value);

執行上述程式碼後,將顯示以下輸出。

[0,1] 
[1.2] 
[2,3]

或者,我們也可以使用擴充套件運算子一次性獲得條目陣列。

var numbers = [1, 2, 3]; 
var val= numbers.entries(); 
console.log([...val]);

執行上述程式碼後,將顯示以下輸出。

[[0,1],[1,2],[2,3]]

Array.from

Array.from() 能夠根據類似陣列的物件建立一個新陣列。Array.from() 的基本功能是將兩種值轉換為陣列:

  • 類似陣列的值。

  • 可迭代的值,如 Set 和 Map。

示例

"use strict" 
for (let i of Array.from('hello')) { 
   console.log(i) 
}

執行上述程式碼後,將顯示以下輸出。

h                               
e                               
l                               
l                               
o

Array.prototype.keys()

此函式返回陣列索引。

示例

console.log(Array.from(['a', 'b'].keys()))

執行上述程式碼後,將顯示以下輸出。

[ 0, 1 ] 

使用 for…in 迴圈遍歷陣列

可以使用 for…in 迴圈遍歷陣列。

"use strict" 
var nums = [1001,1002,1003,1004] 
for(let j in nums) { 
   console.log(nums[j]) 
}

迴圈執行基於索引的陣列遍歷。上述程式碼成功執行後將顯示以下輸出。

1001 
1002 
1003 
1004

JavaScript 中的陣列

JavaScript 支援以下關於陣列的概念:

序號 概念和描述
1 多維陣列

JavaScript 支援多維陣列。多維陣列最簡單的形式是二維陣列

2 將陣列傳遞給函式

你可以透過指定陣列名稱而不指定索引來將指向陣列的指標傳遞給函式。

3 從函式返回陣列

允許函式返回陣列。

陣列解構

解構是指將陣列或物件中的各個值提取到不同的變數中。考慮一個需要將陣列的值分配給各個變數的場景。傳統的做法如下:

var a= array1[0]
var b= array1[1]
var c= array1[2]

解構有助於以簡潔的方式實現相同的功能。

語法

//destructuring an array
let [variable1,variable2]=[item1,item2]
//destructuring an object
let {property1,property2} = {property1:value1,property2:value2}

示例

<script>
   let names = ['Mohtashim','Kannan','Kiran']
   let [n1,n2,n3] = names;
   console.log(n1)
   console.log(n2)
   console.log(n3);
   //rest operator with array destructuring
   let locations=['Mumbai','Hyderabad','Chennai']
   let [l1,...otherValues] =locations
   console.log(l1)
   console.log(otherValues)
   //variables already declared
   let name1,name2;
   [name1,name2] =names
   console.log(name1)
   console.log(name2)
   //swapping
   let first=10,second=20;
   [second,first] = [first,second]
   console.log("second is ",second) //10
   console.log("first is ",first) //20
</script>

上述程式碼的輸出將如下所示:

Mohtashim
Kannan
Kiran
Mumbai
["Hyderabad", "Chennai"]
Mohtashim
Kannan
second is 10
first is 20

ES6 - 日期

Date 物件是 JavaScript 語言中內建的一種資料型別。Date 物件使用 new Date() 建立,如下面的語法所示。

建立 Date 物件後,許多方法允許你對其進行操作。大多數方法只需允許你獲取和設定物件的年、月、日、時、分、秒和毫秒欄位,使用本地時間或 UTC(通用時間或 GMT)時間。

ECMAScript 標準要求 Date 物件能夠表示 1970 年 1 月 1 日之前或之後 1 億天內的任何日期和時間,精確到毫秒。這是正負 273,785 年的範圍,因此 JavaScript 可以表示到 275755 年的日期和時間。

你可以使用以下任何語法使用 Date() 建構函式建立 Date 物件。

new Date( ) 
new Date(milliseconds) 
new Date(datestring) 
new Date(year,month,date[,hour,minute,second,millisecond ])

注意 - 方括號中的引數始終是可選的。

Date 屬性

以下是 Date 物件屬性的列表及其描述。

序號 屬性 & 描述
1 constructor

指定建立物件原型的函式

2 prototype

prototype 屬性允許你向物件新增屬性和方法

Date 方法

以下是不同日期方法的列表及其描述。

序號 方法 & 描述
1 Date()

返回今天的日期和時間

2 getDate()

根據本地時間返回指定日期的月份中的日期

3 getDay()

根據本地時間返回指定日期的一週中的日期

4 getFullYear()

根據本地時間返回指定日期的年份

5 getHours()

根據本地時間返回指定日期的小時

6 getMilliseconds()

根據本地時間返回指定日期的毫秒

7 getMinutes()

根據本地時間返回指定日期的分鐘

8 getMonth()

根據本地時間返回指定日期的月份

9 getSeconds()

根據本地時間返回指定日期的秒數

10 getTime()

返回指定日期的數值,為自 1970 年 1 月 1 日 00:00:00 UTC 以來以毫秒錶示的數字

11 getTimezoneOffset()

返回當前區域設定的時區偏移量(以分鐘為單位)

12 getUTCDate()

根據世界協調時間返回指定日期的月份中的日期

13 getUTCDay()

根據世界協調時間返回指定日期的一週中的日期

14 getUTCFullYear()

根據世界協調時間返回指定日期的年份

15 getutcHours()

根據世界協調時間返回指定日期的小時

16 getUTCMilliseconds()

根據世界協調時間返回指定日期的毫秒

17 getUTCMinutes()

根據世界協調時間返回指定日期的分鐘

18 getUTCMonth()

根據世界協調時間返回指定日期的月份

19 getUTCSeconds()

根據世界協調時間返回指定日期的秒數

20 setDate()

根據本地時間設定指定日期的月份中的日期

21 setFullYear()

根據本地時間設定指定日期的年份

22 setHours()

根據本地時間設定指定日期的小時

23 setMilliseconds()

根據本地時間設定指定日期的毫秒

24 setMinutes()

根據本地時間設定指定日期的分鐘

25 setMonth()

根據本地時間設定指定日期的月份

26 setSeconds()

根據本地時間設定指定日期的秒數

27 setTime()

將 Date 物件設定為自 1970 年 1 月 1 日 00:00:00 UTC 以來以毫秒錶示的時間

28 setUTCDate()

將 Date 物件設定為自 1970 年 1 月 1 日 00:00:00 UTC 以來以毫秒錶示的時間

29 setUTCFullYear()

根據世界協調時間設定指定日期的年份

30 setUTCHours()

根據世界協調時間設定指定日期的小時

31 setUTCMilliseconds()

根據世界協調時間設定指定日期的毫秒

32 setUTCMinutes()

根據世界協調時間設定指定日期的分鐘

33 setUTCMonth()

根據世界協調時間設定指定日期的月份

34 setUTCSeconds()

根據世界協調時間設定指定日期的秒數

35 toDateString()

將日期的“日期”部分作為人類可讀的字串返回

36 toLocaleDateString()

使用當前區域設定的約定將日期的“日期”部分作為字串返回

37 toLocaleString()

使用當前區域設定的約定將日期轉換為字串

38 toLocaleTimeString()

使用當前區域設定的約定將日期的“時間”部分作為字串返回

39 toString()

返回表示指定 Date 物件的字串

40 toTimeString()

將日期的“時間”部分作為人類可讀的字串返回

41 toUTCString()

使用世界協調時間約定將日期轉換為字串

42 valueOf()

返回 Date 物件的原始值

ES6 - 數學物件

Math 物件為你提供數學常數和函式的屬性和方法。與其他全域性物件不同,Math 不是建構函式。Math 的所有屬性和方法都是靜態的,可以使用 Math 作為物件來呼叫,而無需建立它。

Math 屬性

以下是所有 Math 屬性及其描述的列表。

序號 屬性 & 描述
1 E

尤拉常數和自然對數的底數,約為 2.718

2 LN2

2的自然對數,約等於0.693

3 LN10

10的自然對數,約等於2.302

4 LOG2E

E的以2為底的對數,約等於1.442

5 LOG10E

E的以10為底的對數,約等於0.434

6 PI

圓周率(圓周長與直徑之比),約等於3.14159

7 SQRT1_2

1/2的平方根;等效於1除以2的平方根,約等於0.707

8 SQRT2

2的平方根,約等於1.414

指數函式

基本的指數函式是Math.pow(),並且還有用於平方根、立方根和e的冪的便捷函式,如下表所示。

序號 函式及描述
1 Math.pow(x, y)

返回xy次冪

2 Math.sqrt(x)

返回數字x的平方根

3 Math.cbrt(x)

此方法返回數字x的立方根

4 Math.exp(x)

等效於Math.pow(Math.E, x)

5 Math.expm1(x)

等效於Math.exp(x) – 1

6 Math.hypot(x1, x2,...)

返回引數之和的平方根

對數函式

基本的自然對數函式是Math.log()。在JavaScript中,“log”表示“自然對數”。ES6為了方便引入了Math.log10。

序號 函式及描述
1 Math.log(x)

x的自然對數

2 Math.log10(x)

x的以10為底的對數

3 Math.log2(x)

x的以2為底的對數

4 Math.log1p(x)

1 + x的自然對數

其他代數函式

以下是其他代數函式及其描述的列表。

序號 函式及描述
1 Math.abs(x)

x的絕對值

2 Math.sign(x)

x的符號:如果x為負數,則為-1;如果x為正數,則為1;如果x為0,則為0

3 Math.ceil(x)

x的向上取整:大於或等於x的最小整數

4 Math.floor(x)

x的向下取整:小於或等於x的最大整數

5 Math.trunc(x)

x的整數部分(所有小數位都被移除)

6 Math.round(x)

四捨五入到最接近的整數

7 Math.min(x1, x2,...)

返回最小引數

8 Math.max((x1, x2,...))

返回最小引數

三角函式

Math庫中的所有三角函式都使用弧度,而不是角度。

序號 函式及描述
1 Math.sin(x)

x弧度的正弦值

2 Math.cos(x)

x弧度的餘弦值

3 Math.tan(x)

x弧度的正切值

4 Math.asin(x)

x的反正弦(arcsin)(結果以弧度表示)

5 Math.acos(x)

x的反餘弦(arccos)(結果以弧度表示)

6 Math.atan(x)

x的反正切(arctan)(結果以弧度表示)

7 Math.atan2(y, x0)

從x軸到點(x, y)的逆時針角度(以弧度表示)

Math.random()

Math.random()函式返回一個介於0(包含)和1(不包含)之間的偽隨機數。

示例:偽隨機數生成 (PRNG)

var value1 = Math.random();  
console.log("First Test Value : " + value1 ); 

var value2 = Math.random();  
console.log("Second Test Value : " + value2 ); 

var value3 = Math.random();  
console.log("Third Test Value : " + value3 ); 

var value4 = Math.random(); 
console.log("Fourth Test Value : " + value4 );

輸出

First Test Value : 0.5782922627404332 
Second Test Value : 0.5624510529451072 
Third Test Value : 0.9336334094405174 
Fourth Test Value : 0.4002739654388279

ES6 - 正則表示式

正則表示式是一個描述字元模式的物件。正則表示式通常縮寫為“regex”或“regexp”。

JavaScript的RegExp類表示正則表示式,String和RegExp都定義了使用正則表示式對文字執行強大的模式匹配和搜尋替換功能的方法。

正則表示式可以定義為:

var pattern = new RegExp(pattern, attributes); 
OR 
var pattern = /pattern/attributes;

屬性可以具有以下值的任何組合。

序號 屬性及描述
1

G

全域性匹配

2

I

忽略大小寫

3

M

多行;將開頭和結尾字元(^和$)視為作用於多行(即匹配每一行的開頭或結尾(由\n或\r分隔),而不僅僅是整個輸入字串的開頭或結尾)

4

U

Unicode;將模式視為Unicode程式碼點的序列

5

Y

粘性;僅匹配目標字串中此正則表示式的lastIndex屬性指示的索引(並且不嘗試從任何後面的索引匹配)

構造正則表示式

Brackets

括號([])在正則表示式上下文中具有特殊含義。它們用於查詢一系列字元。

序號 表示式及描述
1

[...]

括號內的任意一個字元

2

[^...]

括號外任意一個字元

3

[0-9]

匹配0到9之間的任何十進位制數字

4

[a-z]

匹配從小寫a到小寫z的任何字元

5

[A-Z]

匹配從大寫A到大寫Z的任何字元

6

[a-Z]

匹配從小寫a到大寫Z的任何字元

上面顯示的範圍是一般的;您也可以使用範圍[0-3]來匹配0到3之間的任何十進位制數字,或者使用範圍[b-v]來匹配從b到v之間的任何小寫字元。

量詞

括號字元序列和單個字元的頻率或位置可以用特殊字元表示。每個特殊字元都有其特定的含義。+、*、?$標誌都位於字元序列之後。

序號 表示式及描述
1

p+

匹配包含至少一個p的任何字串。

2

p*

匹配包含零個或多個p的任何字串

3

p?

匹配包含一個或多個p的任何字串

4

p{N}

匹配包含Np序列的任何字串

5

p{2,3}

匹配包含兩個或三個p序列的任何字串

6

p{2, }

匹配包含至少兩個p序列的任何字串

7

p$

匹配結尾為p的任何字串

8

^p

匹配開頭為p的任何字串

9

[^a-zA-Z]

匹配不包含從az和從AZ的任何字元的任何字串

10

p.p

匹配包含p,後跟任何字元,然後又是另一個p的任何字串

11

^.{2}$

匹配包含恰好兩個字元的任何字串

12

<b>(.*)</b>

匹配包含在<b>和</b>之間的任何字串

13

p(hp)*

匹配包含p後跟零個或多個hp序列的任何字串

字面字元

序號 字元及描述
1

字母數字

自身

2

\0

空字元 (\u0000)

3

\t

製表符 (\u0009)

4

\n

換行符 (\u000A)

5

\v

垂直製表符 (\u000B)

6

\f

換頁符 (\u000C)

7

\r

回車符 (\u000D)

8

\xnn

由十六進位制數nn指定的拉丁字元;例如,\x0A與\n相同

9

\uxxxx

由十六進位制數xxxx指定的Unicode字元;例如,\u0009與\t相同

10

\cX

控制字元^X;例如,\cJ相當於換行符\n

元字元

元字元只是一個以反斜槓開頭的字母字元,它賦予組合特殊的含義。

例如,您可以使用'\d'元字元搜尋一大筆錢:/([\d]+)000/。在這裡,\d將搜尋任何數字字元的字串。

下表列出了一組可在PERL風格正則表示式中使用的元字元。

序號 字元及描述
1

.

單個字元

2

\s

空格字元(空格、製表符、換行符)

3

\S

非空格字元

4

\d

數字 (0-9)

5

\D

非數字

6

\w

單詞字元 (a-z, A-Z, 0-9, _)

7

\W

非單詞字元

8

[\b]

字面退格符(特殊情況)

9

[aeiou]

匹配給定集合中的單個字元

10

[^aeiou]

匹配給定集合外的單個字元

11

(foo|bar|baz)

匹配指定的任何備選方案

RegExp 屬性

序號 屬性及描述
1 RegExp.prototype.flags

包含RegExp物件的標誌的字串

2 RegExp.prototype.global

是否針對字串中的所有可能匹配項測試正則表示式,還是僅針對第一個匹配項測試

3 RegExp.prototype.ignoreCase

在嘗試匹配字串時是否忽略大小寫

4 RegExp.prototype.lastIndex

RegExp物件的讀/寫屬性。

5 RegExp.prototype.multiline

是否在多行字串中搜索

6 RegExp.prototype.source

模式文字

RegExp 方法

序號 方法 & 描述
1 RegExp.prototype.exec()

在其字串引數中執行匹配搜尋

2 RegExp.prototype.test()

測試其字串引數中的匹配項

3 RegExp.prototype.match()

對給定字串執行匹配並返回匹配結果

4 RegExp.prototype.replace()

將給定字串中的匹配項替換為新的子字串

5 RegExp.prototype.search()

搜尋給定字串中的匹配項並返回模式在字串中找到的索引

6 RegExp.prototype.split()

透過將字串分成子字串來將給定字串分割成陣列

7 RegExp.prototype.toString()

返回表示指定物件的字串。覆蓋Object.prototype.toString()方法

ES6 - HTML DOM

每個網頁都位於瀏覽器視窗內,可以將其視為一個物件。

文件物件表示顯示在該視窗中的HTML文件。文件物件具有各種屬性,這些屬性引用其他物件,允許訪問和修改文件內容。

訪問和修改文件內容的方式稱為文件物件模型DOM。物件按層次結構組織。這種層次結構適用於網頁文件中物件的組織。

以下是一些重要物件的簡單層次結構:

HTML DOM

存在多個DOM。以下各節將詳細解釋這些DOM中的每一個,並描述如何使用它們來訪問和修改文件內容。

  • 傳統DOM - 這是在早期版本的JavaScript語言中引入的模型。它受到所有瀏覽器的良好支援,但僅允許訪問文件的某些關鍵部分,例如表單、表單元素和影像。

  • W3C DOM - 此文件物件模型允許訪問和修改所有文件內容,並由全球資訊網聯盟 (W3C) 標準化。此模型幾乎受到所有現代瀏覽器的支援。

  • IE4 DOM - 此文件物件模型是在Microsoft Internet Explorer瀏覽器的版本4中引入的。IE 5及更高版本包含對大多數基本W3C DOM功能的支援。

傳統DOM

這是在早期版本的JavaScript語言中引入的模型。它受到所有瀏覽器的良好支援,但僅允許訪問文件的某些關鍵部分,例如表單、表單元素和影像。

此模型提供了一些只讀屬性,例如title、URL和lastModified,這些屬性提供有關整個文件的資訊。除此之外,此模型還提供了各種方法,可用於設定和獲取文件屬性值。

傳統DOM中的文件屬性

以下是可以使用傳統DOM訪問的文件屬性列表。

序號 屬性 & 描述
1

alinkColor

已棄用 - 指定活動連結顏色的字串。

示例:document.alinkColor

2

anchors[ ]

錨物件的陣列,每個出現在文件中的錨點一個。

示例:document.anchors[0]、document.anchors[1]等等

3

applets[ ]

applet物件的陣列,文件中出現的每個applet一個。

示例:document.applets[0]、document.applets[1]等等

4

bgColor

已棄用 - 指定文件背景顏色的字串。

示例:document.bgColor

5

Cookie

具有特殊行為的字串值屬性,允許查詢和設定與此文件關聯的cookie。

示例:document.cookie

6

Domain

指定文件所屬網際網路域名的字串。用於安全目的。

示例:document.domain

7

embeds[ ]

一個物件陣列,表示文件中使用<embed>標籤嵌入的資料。它是plugins[ ]的同義詞。某些外掛和ActiveX控制元件可以使用JavaScript程式碼進行控制。

示例:document.embeds[0],document.embeds[1] 等等

8

fgColor

指定文件預設文字顏色的字串。

示例:document.fgColor

9

forms[ ]

一個表單物件陣列,每個物件對應文件中出現的HTML表單。

示例:document.forms[0],document.forms[1] 等等

10

images[ ]

一個表單物件陣列,每個物件對應文件中使用HTML <img> 標籤出現的影像。

示例:document.forms[0],document.forms[1] 等等

11

lastModified

一個只讀字串,指定文件最近一次修改的日期。

示例:document.lastModified

12

linkColor

已棄用 - 指定未訪問連結顏色的字串。

示例:document.linkColor

13

links[ ]

這是一個文件連結陣列。

示例:document.links[0],document.links[1] 等等

14

Location

文件的URL。已棄用,建議使用URL屬性。

示例:document.location

15

plugins[ ]

embeds[ ] 的同義詞。

示例:document.plugins[0],document.plugins[1] 等等

16

Referrer

一個只讀字串,包含當前文件連結到的文件(如果有)的URL。

示例:document.referrer

17

Title

<title>標籤的文字內容。

示例:document.title

18

URL

一個只讀字串,指定文件的URL。

示例:document.URL

19

vlinkColor

已棄用 - 指定已訪問連結顏色的字串。

示例:document.vlinkColor

傳統DOM中的文件方法

以下是傳統DOM支援的方法列表。

序號 屬性 & 描述
1

clear( )

已棄用 - 清除文件內容並返回空。

示例:document.clear( )

2

close( )

關閉使用open( )方法開啟的文件流,並返回空。

3

open( )

刪除現有文件內容並開啟一個流,可以向其中寫入新的文件內容。返回空。

示例:document.open( )

4

write( value, ...)

將指定的字串插入到當前正在解析的文件中,或者追加到使用open( )開啟的文件中。返回空。

示例:document.write( value, ...)

5

writeln( value, ...)

與write( )相同,只是它會在輸出中追加一個換行符。返回空。

示例:document.writeln( value, ...)

我們可以使用HTML DOM在任何HTML文件中定位任何HTML元素。例如,如果一個網頁文件包含一個表單元素,那麼使用JavaScript,我們可以將其引用為document.forms[0]。如果您的網頁文件包含兩個表單元素,則第一個表單被稱為document.forms[0],第二個被稱為document.forms[1]。

使用上面給出的層次結構和屬性,我們可以使用document.forms[0].elements[0]等等訪問第一個表單元素。

示例

以下是如何使用傳統DOM方法訪問文件屬性的示例。

<html> 
   <head> 
      <title> Document Title </title> 
      
      <script type = "text/javascript"> 
         <!--  
            function myFunc() {  
               var ret = document.title;  
               alert("Document Title : " + ret );  
               var ret = document.URL;  
               alert("Document URL : " + ret );  
               var ret = document.forms[0];  
               alert("Document First Form : " + ret );  
               var ret = document.forms[0].elements[1];  
               alert("Second element : " + ret );  
            } //
         --> 
      </script> 
   </head> 
   
   <body> 
      <h1 id = "title">This is main title</h1> 
      <p>Click the following to see the result:</p> 
      
      <form name = "FirstForm">
         <input type = "button" value = "Click Me" onclick = "myFunc();" /> 
         <input type = "button" value = "Cancel"> 
      </form> 

      <form name = "SecondForm"> 
         <input type = "button" value = "Don't ClickMe"/> 
      </form> 
   </body> 
   
</html> 

輸出

執行上述程式碼後,將顯示以下輸出。

legacy dom method

注意 - 此示例返回表單和元素的物件。我們將必須使用在本教程中未討論的物件屬性來訪問它們的值。

ES6 - 迭代器

迭代器簡介

迭代器是一個物件,它允許我們一次訪問一個物件集合。

以下內建型別預設情況下是可迭代的:

  • 字串
  • 陣列
  • 對映(Map)
  • 集合(Set)

如果物件實現了一個鍵為[Symbol.iterator]並返回迭代器的函式,則該物件被認為是可迭代的。可以使用for...of迴圈迭代集合。

示例

以下示例宣告一個數組marks,並使用for..of迴圈對其進行迭代。

<script>
   let marks = [10,20,30]
   //check iterable using for..of
   for(let m of marks){
      console.log(m);
   }
</script>

上述程式碼的輸出將如下所示:

10
20
30

示例

以下示例宣告一個數組marks並檢索一個迭代器物件。可以使用[Symbol.iterator]()檢索迭代器物件。迭代器的next()方法返回一個具有'value''done'屬性的物件。'done'是布林值,在讀取集合中的所有專案後返回true。

<script>
   let marks = [10,20,30]
   let iter = marks[Symbol.iterator]();
   console.log(iter.next())
   console.log(iter.next())
   console.log(iter.next())
   console.log(iter.next())
</script>

上述程式碼的輸出將如下所示:

{value: 10, done: false}
{value: 20, done: false}
{value: 30, done: false}
{value: undefined, done: true}

自定義可迭代物件

JavaScript中某些型別是可迭代的(例如Array、Map等),而另一些則不是(例如類)。預設情況下不可迭代的JavaScript型別可以使用可迭代協議進行迭代。

以下示例定義一個名為CustomerList的類,該類將多個客戶物件儲存為陣列。每個客戶物件都具有firstName和lastName屬性。

為了使此類可迭代,該類必須實現[Symbol.iterator]()函式。此函式返回一個迭代器物件。迭代器物件有一個函式next,它返回一個物件{value:'customer',done:true/false}

<script>
   //user defined iterable
   class CustomerList {
      constructor(customers){
         //adding customer objects to an array
         this.customers = [].concat(customers)
      }
      //implement iterator function
      [Symbol.iterator](){
         let count=0;
         let customers = this.customers
         return {
            next:function(){
            //retrieving a customer object from the array
               let customerVal = customers[count];
               count+=1;
               if(count<=customers.length){
                  return {
                     value:customerVal,
                     done:false
                  }
               }
               //return true if all customer objects are iterated
               return {done:true}
            }
         }
      }
   }
   //create customer objects
   let c1={
      firstName:'Sachin',
      lastName:'Tendulkar'
   }
   let c2={
      firstName:'Rahul',
      lastName:'Dravid'
   }
   //define a customer array and initialize it let customers=[c1,c2]
   //pass customers to the class' constructor
   let customersObj = new CustomerList(customers);
   //iterating using for..of
   for(let c of customersObj){
      console.log(c)
   }
   //iterating using the next() method
   let iter = customersObj[Symbol.iterator]();
   console.log(iter.next())
   console.log(iter.next())
   console.log(iter.next())
</script>

上述程式碼的輸出如下:

{firstName: "Sachin", lastName: "Tendulkar"}
{firstName: "Rahul", lastName: "Dravid"}
{
   done: false
   value: {
      firstName: "Sachin",
      lastName: "Tendulkar"
   }
}
{
   done: false
   value: {
      firstName: "Rahul",
      lastName: "Dravid"
   }
}
{done: true}

生成器

在ES6之前,JavaScript中的函式遵循執行到完成模型。ES6引入了稱為生成器的函式,這些函式可以中途停止,然後從停止的地方繼續。

生成器在函式名字首一個星號*字元,幷包含一個或多個yield語句。yield關鍵字返回一個迭代器物件。

語法

function * generator_name() {
   yield value1
   ...
   yield valueN
}

示例

此示例定義了一個生成器函式getMarks,其中包含三個yield語句。與普通函式不同,生成器函式getMarks()在呼叫時不會執行函式,而是返回一個迭代器物件,該物件有助於執行生成器函式內的程式碼。

在第一次呼叫markIter.next()時,開始處的操作將執行,而yield語句會暫停生成器的執行。隨後對markIter.next()的呼叫將恢復生成器函式,直到下一個yield表示式。

<script>
   //define generator function
   function * getMarks(){
      console.log("Step 1")
      yield 10
      console.log("Step 2")
      yield 20
      console.log("Step 3")
      yield 30
      console.log("End of function")
   }
   //return an iterator object
      let markIter = getMarks()
   //invoke statements until first yield
      console.log(markIter.next())
   //resume execution after the last yield until second yield expression
      console.log(markIter.next())
   //resume execution after last yield until third yield expression
      console.log(markIter.next())
      console.log(markIter.next()) // iteration is completed;no value is returned
</script>

上述程式碼的輸出如下所示:

Step 1
{value: 10, done: false}
Step 2
{value: 20, done: false}
Step 3
{value: 30, done: false}
End of function
{value: undefined, done: true}

示例

以下示例透過

* evenNumberGenerator生成器函式建立一個無限的偶數序列。

我們可以使用next()或使用for of迴圈迭代所有偶數,如下所示

<script>
   function * evenNumberGenerator(){
      let num = 0;
      while(true){
         num+=2
         yield num
      }
   }
   // display first two elements
   let iter = evenNumberGenerator();
   console.log(iter.next())
   console.log(iter.next())
   //using for of to iterate till 12
   for(let n of evenNumberGenerator()){
      if(n==12)break;
      console.log(n);
   }
</script>

上述程式碼的輸出如下:

{value: 2, done: false}
{value: 4, done: false}
2
4
6
8
10

ES6 - 集合

ES6引入了兩種新的資料結構:Map和Set。

  • Map - 此資料結構允許將鍵對映到值。

  • Set - Set類似於陣列。但是,Set不允許重複。

Map

Map物件是一個簡單的鍵/值對。Map中的鍵和值可以是原始值或物件。

以下是該方法的語法。

new Map([iterable]) 

引數iterable表示任何可迭代的物件,其元素包含鍵/值對。Map是有序的,即它們按插入順序遍歷元素。

Map屬性

序號 屬性 & 描述
1 Map.prototype.size

此屬性返回Map物件中鍵/值對的數量。

理解基本的Map操作

set()函式設定Map物件中鍵的值。set()函式接受兩個引數,即鍵及其值。此函式返回Map物件。

has()函式返回一個布林值,指示Map物件中是否存在指定的鍵。此函式接受一個鍵作為引數。

var map = new Map(); 
map.set('name','Tutorial Point'); 
map.get('name'); // Tutorial point

上面的示例建立一個map物件。該map只有一個元素。元素鍵用name表示。該鍵對映到值Tutorial point

注意 - Map區分類似的值,但具有不同的資料型別。換句話說,整數鍵1字串鍵“1”被認為是不同的。考慮以下示例以更好地理解這個概念

var map = new Map(); 
map.set(1,true); 
console.log(map.has("1")); //false 
map.set("1",true); 
console.log(map.has("1")); //true

輸出

false 
true 

set()方法也是可鏈的。考慮以下示例。

var roles = new Map(); 
roles.set('r1', 'User') 
.set('r2', 'Guest') 
.set('r3', 'Admin'); 
console.log(roles.has('r1'))

輸出

True 

上面的示例定義了一個map物件。該示例鏈式呼叫set()函式來定義鍵/值對。

get()函式用於檢索與指定鍵對應的值。

Map建構函式也可以傳遞一個數組。此外,map還支援使用擴充套件運算子來表示陣列。

示例

var roles = new Map([ 
   ['r1', 'User'], 
   ['r2', 'Guest'], 
   ['r3', 'Admin'], 
]);  
console.log(roles.get('r2'))

執行上述程式碼後,將顯示以下輸出。

Guest

注意 - 如果Map中不存在指定的鍵,則get()函式返回undefined。

如果鍵已存在於map中,則set()會替換該鍵的值。考慮以下示例。

var roles = new Map([ 
   ['r1', 'User'], 
   ['r2', 'Guest'], 
   ['r3', 'Admin'], 
]);  
console.log(`value of key r1 before set(): ${roles.get('r1')}`) 
roles.set('r1','superUser') 
console.log(`value of key r1 after set(): ${roles.get('r1')}`)

執行上述程式碼後,將顯示以下輸出。

value of key r1 before set(): User 
value of key r1 after set(): superUser

Map方法

序號 方法 & 描述
1 Map.prototype.clear()

刪除Map物件中的所有鍵/值對。

2 Map.prototype.delete(key)

刪除與鍵關聯的任何值,並返回Map.prototype.has(key)之前將返回的值。

Map.prototype.has(key)之後將返回false。

3 Map.prototype.entries()

返回一個新的迭代器物件,該物件包含Map物件中每個元素的[key, value]陣列,順序為插入順序。

4 Map.prototype.forEach(callbackFn[, thisArg])

為Map物件中存在的每個鍵值對呼叫callbackFn一次,順序為插入順序。如果向forEach提供thisArg引數,則它將用作每個回撥的“this”值。

5 Map.prototype.keys()

返回一個新的迭代器物件,該物件包含Map物件中每個元素的,順序為插入順序。

6 Map.prototype.values()

返回一個新的迭代器物件,該物件包含Map物件中每個元素的[key, value]陣列,順序為插入順序。

for…of迴圈

以下示例演示了使用for…of迴圈遍歷map。

'use strict' 
var roles = new Map([ 
   ['r1', 'User'], 
   ['r2', 'Guest'], 
   ['r3', 'Admin'], 
]);
for(let r of roles.entries()) 
console.log(`${r[0]}: ${r[1]}`);

執行上述程式碼後,將顯示以下輸出。

r1: User 
r2: Guest 
r3: Admin

弱Map(Weak Map)

弱Map與Map相同,但有以下例外:

  • 它的鍵必須是物件。

  • 弱Map中的鍵可以被垃圾回收。垃圾回收是清除程式中未引用物件佔用的記憶體的過程。

  • 弱Map不能被迭代或清除。

示例:弱Map

'use strict' 
let weakMap = new WeakMap(); 
let obj = {}; 
console.log(weakMap.set(obj,"hello"));  
console.log(weakMap.has(obj));// true

執行上述程式碼後,將顯示以下輸出。

WeakMap {} 
true

Set

Set是ES6資料結構。它類似於陣列,區別在於它不能包含重複項。換句話說,它允許您儲存唯一的值。Set支援原始值和物件引用。

與Map一樣,Set也是有序的,即元素按其插入順序進行迭代。可以使用以下語法初始化Set。

Set屬性

序號 屬性 & 描述
1 Set.prototype.size

返回Set物件中的值的數量。

Set方法

序號 方法 & 描述
1 Set.prototype.add(value)

將一個具有給定值的新元素新增到Set物件中。返回Set物件。

2 Set.prototype.clear()

刪除Set物件中的所有元素。

3 Set.prototype.delete(value)

刪除與值關聯的元素。

4 Set.prototype.entries()

返回一個新的迭代器物件,該物件包含Set物件中每個元素的[value, value]陣列,順序為插入順序。這與Map物件保持一致,因此每個條目的鍵和值在此處具有相同的值。

5 Set.prototype.forEach(callbackFn[, thisArg])

為Set物件中存在的每個值呼叫callbackFn一次,順序為插入順序。如果向forEach提供athisArg引數,則它將用作每個回撥的“this”值。

6 Set.prototype.has(value)

返回一個布林值,用於斷言Set物件中是否存在具有給定值或不存在的元素。

7 Set.prototype.values()

返回一個新的迭代器物件,該物件包含Set物件中每個元素的,順序為插入順序。

弱Set(Weak Set)

弱Set只能包含物件,並且它們包含的物件可以被垃圾回收。與弱Map一樣,弱Set也不能被迭代。

示例:使用弱Set

'use strict' 
   let weakSet = new WeakSet();  
   let obj = {msg:"hello"}; 
   weakSet.add(obj); 
   console.log(weakSet.has(obj)); 
   weakSet.delete(obj); 
   console.log(weakSet.has(obj));

執行上述程式碼後,將顯示以下輸出。

true 
false

迭代器

迭代器是一個物件,它允許一次訪問一個物件集合。Set和Map都具有返回迭代器的方法。

迭代器是具有next()方法的物件。當呼叫next()方法時,它會返回一個包含'value''done'屬性的物件。'done'是布林值,在讀取集合中的所有專案後將返回true。

示例1:集合和迭代器

var  set = new Set(['a','b','c','d','e']);  
var iterator = set.entries(); 
console.log(iterator.next())

執行上述程式碼後,將顯示以下輸出。

{ value: [ 'a', 'a' ], done: false } 

由於集合不儲存鍵/值對,因此值陣列包含相似的鍵和值。done 將為 false,因為還有更多元素需要讀取。

示例2:集合和迭代器

var  set = new Set(['a','b','c','d','e']);  
var iterator = set.values(); 
console.log(iterator.next());

執行上述程式碼後,將顯示以下輸出。

{ value: 'a', done: false }  

示例3:集合和迭代器

var  set = new Set(['a','b','c','d','e']);  
var iterator = set.keys(); 
console.log(iterator.next()); 

執行上述程式碼後,將顯示以下輸出。

{ value: 'a', done: false }  

示例4:對映和迭代器

var map = new Map([[1,'one'],[2,'two'],[3,'three']]); 
var iterator = map.entries(); 
console.log(iterator.next()); 

執行上述程式碼後,將顯示以下輸出。

{ value: [ 1, 'one' ], done: false }  

示例5:對映和迭代器

var map = new Map([[1,'one'],[2,'two'],[3,'three']]); 
var iterator = map.values(); 
console.log(iterator.next());  

執行上述程式碼後,將顯示以下輸出。

{value: "one", done: false} 

示例6:對映和迭代器

var map = new Map([[1,'one'],[2,'two'],[3,'three']]); 
var iterator = map.keys(); 
console.log(iterator.next());  

執行上述程式碼後,將顯示以下輸出。

{value: 1, done: false} 

ES6 - 類

面向物件是一種遵循現實世界建模的軟體開發正規化。面向物件將程式視為透過稱為方法的機制相互通訊的物件集合。ES6 也支援這些面向物件的元件。

面向物件程式設計概念

首先,讓我們瞭解

  • 物件- 物件是任何實體的即時表示。根據 Grady Brooch 的說法,每個物件據說具有 3 個特徵:

    • 狀態- 由物件的屬性描述。

    • 行為- 描述物件將如何行動。

    • 標識- 一個唯一值,將物件與一組類似的物件區分開來。

  • - 在 OOP 中,類是建立物件的藍圖。類封裝了物件的資料。

  • 方法- 方法促進物件之間的通訊。

讓我們將這些面向物件的概念轉化為現實世界中的概念。例如:汽車是一個物件,它具有資料(製造商、型號、車門數量、車輛號碼等)和功能(加速、換擋、開啟車門、開啟車燈等)。

在 ES6 之前,建立類是一件麻煩事。在 ES6 中,可以使用 class 關鍵字建立類。

類可以透過宣告它們或使用類表示式包含在程式碼中。

語法:宣告類

class Class_name {  
}

語法:類表示式

var var_name = new Class_name {  
} 

class 關鍵字後跟類名。命名類時必須考慮識別符號規則(已討論)。

類定義可以包含以下內容:

  • 建構函式- 負責為類的物件分配記憶體。

  • 函式- 函式表示物件可以執行的操作。它們有時也稱為方法。

這些元件組合在一起被稱為類的成員資料。

注意- 類體只能包含方法,不能包含資料屬性。

示例:宣告一個類

class Polygon { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

示例:類表示式

var Polygon = class { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

上面的程式碼片段表示一個未命名的類表示式。命名的類表示式可以寫成。

var Polygon = class Polygon { 
   constructor(height, width) { 
      this.height = height; 
      this.width = width; 
   } 
}

注意- 與變數和函式不同,類不能提升。

建立物件

要建立類的例項,請使用 new 關鍵字後跟類名。以下是相同的語法。

var object_name= new class_name([ arguments ]) 

其中,

  • new 關鍵字負責例項化。

  • 表示式的右側呼叫建構函式。如果建構函式是引數化的,則應向其傳遞值。

示例:例項化一個類

var obj = new Polygon(10,12)

訪問函式

可以透過物件訪問類的屬性和函式。使用“.”點表示法(稱為句點)來訪問類的成員資料。

//accessing a function 
obj.function_name()

示例:將它們放在一起

'use strict' 
class Polygon { 
   constructor(height, width) { 
      this.h = height; 
      this.w = width;
   } 
   test() { 
      console.log("The height of the polygon: ", this.h) 
      console.log("The width of the polygon: ",this. w) 
   } 
} 

//creating an instance  
var polyObj = new Polygon(10,20); 
polyObj.test();      

上面給出的示例聲明瞭一個名為“Polygon”的類。該類的建構函式接受兩個引數 - 高度和寬度。'this'關鍵字指的是類的當前例項。換句話說,上面的建構函式使用傳遞給建構函式的引數值初始化兩個變數 h 和 w。類中的test()函式列印高度和寬度的值。

為了使指令碼正常工作,建立了 Polygon 類的物件。該物件由polyObj變數引用。然後透過此物件呼叫該函式。

執行上述程式碼後,將顯示以下輸出。

The height of the polygon:  10 
The width of the polygon:  20 

設定器和獲取器

設定器

當嘗試設定屬性的值時,將呼叫 setter 函式。set 關鍵字用於定義 setter 函式。定義 setter 函式的語法如下:

{set prop(val) { . . . }}
{set [expression](val) { . . . }}

prop是要繫結到給定函式的屬性的名稱。val是持有嘗試分配給屬性的值的變數的別名。ES6 中的表示式可以用作要繫結到給定函式的屬性名。

示例

<script>
   class Student {
      constructor(rno,fname,lname){
         this.rno = rno
         this.fname = fname
         this.lname = lname
         console.log('inside constructor')
      }
      set rollno(newRollno){
         console.log("inside setter")
         this.rno = newRollno
      }
   }
   let s1 = new Student(101,'Sachin','Tendulkar')
   console.log(s1)
   //setter is called
   s1.rollno = 201
   console.log(s1)
</script>

上面的示例定義了一個名為 Student 的類,它具有三個屬性,即rno、fname 和 lname。setter 函式rollno()用於設定 rno 屬性的值。

上述程式碼的輸出將如下所示:

inside constructor
Student {rno: 101, fname: "Sachin", lname: "Tendulkar"}
inside setter
Student {rno: 201, fname: "Sachin", lname: "Tendulkar"}

示例

以下示例顯示瞭如何使用表示式作為具有setter 函式的屬性名。

<script>
   let expr = 'name';
      let obj = {
      fname: 'Sachin',
      set [expr](v) { this.fname = v; }
   };
   console.log(obj.fname);
   obj.name = 'John';
   console.log(obj.fname);
</script>

上述程式碼的輸出如下所示:

Sachin
John

獲取器

當嘗試獲取屬性的值時,將呼叫getter 函式get 關鍵字用於定義 getter 函式。定義 getter 函式的語法如下:

{get prop() { ... } }
{get [expression]() { ... } }

prop是要繫結到給定函式的屬性的名稱。

表示式- 從 ES6 開始,您還可以使用表示式作為屬性名來繫結到給定函式。

示例

<script>
   class Student {
      constructor(rno,fname,lname){
         this.rno = rno
         this.fname = fname
         this.lname = lname
         console.log('inside constructor')
      }
      get fullName(){
         console.log('inside getter')
         return this.fname + " - "+this.lname
      }
   }
   let s1 = new Student(101,'Sachin','Tendulkar')
   console.log(s1)
   //getter is called
   console.log(s1.fullName)
</script>

上面的示例定義了一個名為 Student 的類,它具有三個屬性,即rno、fname 和 lname。getter 函式fullName()連線fnamelname並返回一個新字串。

上述程式碼的輸出將如下所示:

inside constructor
Student {rno: 101, fname: "Sachin", lname: "Tendulkar"}
inside getter
Sachin - Tendulkar

示例

以下示例顯示瞭如何使用表示式作為具有 getter 函式的屬性名:

<script>
   let expr = 'name';
   let obj = {
      get [expr]() { return 'Sachin'; }
   };
   console.log(obj.name);
</script>

上述程式碼的輸出如下所示:

Sachin

static 關鍵字

static 關鍵字可以應用於類中的函式。靜態成員由類名引用。

示例

'use strict' 
class StaticMem { 
   static disp() { 
      console.log("Static Function called") 
   } 
} 
StaticMem.disp() //invoke the static metho

注意- 不必須包含建構函式定義。每個類預設都有一個建構函式。

執行上述程式碼後,將顯示以下輸出。

Static Function called

instanceof 運算子

如果物件屬於指定的型別,則 instanceof 運算子返回 true。

示例

'use strict' 
class Person{ } 
var obj = new Person() 
var isPerson = obj instanceof Person; 
console.log(" obj is an instance of Person " + isPerson); 

執行上述程式碼後,將顯示以下輸出。

obj is an instance of Person True 

類繼承

ES6 支援繼承的概念。繼承是程式從現有實體(此處為類)建立新實體的能力。擴充套件以建立新類的類稱為父類/超類。新建立的類稱為子類/子類

類使用“extends”關鍵字從另一個類繼承。子類繼承父類中的所有屬性和方法,除了建構函式。

以下是該方法的語法。

class child_class_name extends parent_class_name

示例:類繼承

'use strict' 
class Shape { 
   constructor(a) { 
      this.Area = a
   } 
} 
class Circle extends Shape { 
   disp() { 
      console.log("Area of the circle:  "+this.Area) 
   } 
} 
var obj = new Circle(223); 
obj.disp() 

上面的示例聲明瞭一個名為 Shape 的類。Circle 類擴充套件了該類。由於類之間存在繼承關係,因此子類,即 Circle 類,可以隱式訪問其父類的屬性,即 area。

執行上述程式碼後,將顯示以下輸出。

Area of Circle: 223

繼承可以分類為:

  • 單一繼承- 每個類最多可以從一個父類繼承。

  • 多重繼承- 一個類可以從多個類繼承。ES6 不支援多重繼承。

  • 多層繼承- 考慮以下示例。

'use strict' 
class Root { 
   test() { 
      console.log("call from parent class") 
   } 
} 
class Child extends Root {} 
class Leaf extends Child   

//indirectly inherits from Root by virtue of inheritance {} 
var obj = new Leaf();
obj.test() 

Leaf 類透過多層繼承從 Root 類和 Child 類派生屬性。

執行上述程式碼後,將顯示以下輸出。

call from parent class

類繼承和方法覆蓋

方法覆蓋是一種機制,子類透過該機制重新定義超類方法。以下示例說明了這一點:

'use strict' ;
class PrinterClass { 
   doPrint() { 
      console.log("doPrint() from Parent called… ");
   }
}
class StringPrinter extends PrinterClass { 
   doPrint() { 
      console.log("doPrint() is printing a string…"); 
   } 
} 
var obj = new StringPrinter(); 
obj.doPrint();

在上面的示例中,子類更改了超類函式的實現。

執行上述程式碼後,將顯示以下輸出。

doPrint() is printing a string… 

super 關鍵字

ES6 使子類能夠呼叫其父類的成員資料。這是透過使用super關鍵字實現的。super 關鍵字用於引用類的直接父類。

考慮以下示例:

'use strict' 
class PrinterClass { 
   doPrint() {
      console.log("doPrint() from Parent called…") 
   } 
}  
class StringPrinter extends PrinterClass { 
   doPrint() { 
      super.doPrint() 
      console.log("doPrint() is printing a string…") 
   } 
} 
var obj = new StringPrinter() 
obj.doPrint()

StringWriter 類中的doPrint()重新定義呼叫其父類版本。換句話說,super 關鍵字用於呼叫父類(PrinterClass)中的 doPrint() 函式定義。

執行上述程式碼後,將顯示以下輸出。

doPrint() from Parent called. 
doPrint() is printing a string. 

ES6 - 對映和集合

ES6 引入了兩種新的資料結構:對映集合。讓我們詳細瞭解它們。

Map

對映是有序的鍵值對集合。對映類似於物件。但是,對映和物件之間有一些區別。這些列在下面:

序號 物件 對映(Map)
1 鍵不能是物件型別 鍵可以是任何型別
2 鍵無序 鍵有序
3 不可迭代 可迭代

語法

Map 的語法如下:

let map = new Map([iterable])
let map = new Map()

示例

以下示例使用可迭代建構函式建立對映:

<script>
   let andy = {ename:"Andrel"},
      varun = {ename:"Varun"},
      prijin = {ename:"Prijin"}
   let empJobs = new Map([
   [andy,'Software Architect'],
   [varun,'Developer']]
   );
   console.log(empJobs)
</script>

上述程式碼的輸出如下所示:

{{…} => "Software Architect", {…} => "Developer"}

檢查對映的大小

size 屬性可用於確定對映中儲存的值的數量。

語法

檢查對映大小的語法如下:

map_name.size

示例

<script>
   let daysMap = new Map();
   daysMap.set('1', 'Monday');
   daysMap.set('2', 'Tuesday');
   daysMap.set('3', 'Wednesday');
   console.log(daysMap.size);
</script>

上述程式碼的輸出如下所示:

3

以下是一些可用於操作對映的常用方法:

序號 物件和對映
1 set(key,value)

將鍵和值新增到對映

2 get(key)

如果鍵匹配,則返回值

3 has(key)

如果存在具有指定鍵的元素,則返回 true;否則返回 false

4 keys()

返回一個迭代器,其中包含對映物件中每個元素的鍵

5 values()

返回一個迭代器,其中包含對映物件中每個元素的值

6 entries()

返回一個迭代器,其中包含 Map 中每個元素的鍵值對

7 delete(key)

從 Map 物件中刪除指定的元素

WeakMap

WeakMap 是 map 的一個小的子集。鍵是弱引用的,因此它只能是非原語的。如果沒有對物件鍵的引用,它將被垃圾回收。

  • 不可迭代
  • 每個鍵都是物件型別

如果鍵沒有引用,WeakMap 將允許垃圾回收。

語法

WeakMap 的語法如下:

new WeakMap([iterable])

示例 1

<script>
   let emp = new WeakMap();
   emp.set(10,'Sachin');// TypeError as keys should be object
</script>

示例 2

<script>
   let empMap = new WeakMap();
   // emp.set(10,'Sachin');// Error as keys should be object
   let e1= {ename:'Kiran'},
      e2 = {ename:'Kannan'},
      e3 = {ename:'Mohtashim'}

   empMap.set(e1,1001);
   empMap.set(e2,1002);
   empMap.set(e3,1003);

   console.log(empMap)
   console.log(empMap.get(e2))
   console.log(empMap.has(e2))
   empMap.delete(e1)
   console.log(empMap)
</script>

上面程式碼的輸出如下:

{{…} => 1002, {…} => 1003, {…} => 1001}
1002
true
{{…} => 1002, {…} => 1003}

集合(Set)

集合是唯一值的無序集合。此資料結構可以包含原始值和物件型別的值。

語法

Set 的語法如下:

new Set([iterable])
new Set()

示例

<script>
   let names = new Set(['A','B','C','D']);
   console.log(names)
</script>

上面程式碼的輸出如下:

{"A", "B", "C", "D"}

檢查集合的大小

Set 物件的 size 屬性可用於查詢 Set 中的元素數量。

語法

檢查集合大小的語法如下:

set.size

示例

<script>
   let names = new Set(['A','B','C','D']);
   console.log(names.size)
</script>

上面程式碼的輸出如下:

4

迭代集合

我們可以使用forEachfor..of迴圈來迭代 Set。這在下面的示例中顯示:

示例

<script>
   let names= new Set(['A','B','C','D']);
   //iterate using forEach
   console.log('forEach')
   names.forEach(n=>console.log(n))
   
   console.log('for of..')
   
   //iterate using for..of
   for(let n of names){
      console.log(n)
   }
</script>  

上面程式碼的輸出如下:

forEach
A
B
C
D
for of..
A
B
C
D

以下方法可用於操作集合:

序號 物件和對映
1 add(element)

向集合新增元素

2 has(element)

如果找到元素則返回 true;否則返回 false

3 delete(element)

從集合中刪除特定元素

4 clear()

清除集合中的所有元素

WeakSet

Weakset 弱持有物件,這意味著如果物件沒有被引用,則儲存在 WeakSet 中的物件將被垃圾回收。WeakSet 不可迭代並且沒有get方法。

<script>

   let e1 = {ename:'A'}
   let e2 ={ename:'B'}
   let e3 ={ename:'C'}

   let emps = new WeakSet();
   emps.add(e1);
   emps.add(e2)
   .add(e3);

   console.log(emps)
   console.log(emps.has(e1))
   emps.delete(e1);
   console.log(emps)
</script>

上述程式碼的輸出如下所示:

WeakSet {{…}, {…}, {…}}
true
WeakSet {{…}, {…}}

ES6 - Promise

Promise 語法

下面提到了與 Promise 相關的語法,其中,p 是 Promise 物件,resolve 是 Promise 成功執行時應呼叫的函式,reject 是 Promise 遇到錯誤時應呼叫的函式。

let p = new Promise(function(resolve,reject){
   let workDone = true; // some time consuming work
      if(workDone){
      //invoke resolve function passed
      
	  resolve('success promise completed')
   }
   else{
      reject('ERROR , work could not be completed')
   }
})

示例

下面的示例展示了一個函式 add_positivenos_async(),它非同步地將兩個數字相加。如果傳遞正值,則 Promise 被 resolve;如果傳遞負值,則 Promise 被 reject。

<script>   
   function add_positivenos_async(n1, n2) {
      let p = new Promise(function (resolve, reject) {
         if (n1 >= 0 && n2 >= 0) {
            //do some complex time consuming work
            resolve(n1 + n2)
         }
         else
            reject('NOT_Postive_Number_Passed') 
         })
         return p;
   }

   add_positivenos_async(10, 20)
      .then(successHandler) // if promise resolved
      .catch(errorHandler);// if promise rejected

   add_positivenos_async(-10, -20)
      .then(successHandler) // if promise resolved
      .catch(errorHandler);// if promise rejected

   function errorHandler(err) {
      console.log('Handling error', err)
   }
   function successHandler(result) {
      console.log('Handling success', result)
   }

   console.log('end')
</script> 

上述程式碼的輸出如下所示:

end
Handling success 30
Handling error NOT_Postive_Number_Passed

Promise 鏈式呼叫

當我們需要按順序執行一系列非同步任務時,可以使用Promise 鏈式呼叫。當一個 Promise 依賴於另一個 Promise 的結果時,就會進行 Promise 鏈式呼叫。這在下面的示例中有所體現。

示例

在下面的示例中,add_positivenos_async() 函式非同步地將兩個數字相加,如果傳遞負值則被 reject。當前非同步函式呼叫的結果作為引數傳遞給後續的函式呼叫。注意每個then()方法都有一個 return 語句。

<script>   
   function add_positivenos_async(n1, n2) {
      let p = new Promise(function (resolve, reject) {
         if (n1 >= 0 && n2 >= 0) {
            //do some complex time consuming work
            resolve(n1 + n2)
         }
         else
            reject('NOT_Postive_Number_Passed')
      })
      return p;
   }

   add_positivenos_async(10,20)
   .then(function(result){
      console.log("first result",result)
      return add_positivenos_async(result,result)
   }).then(function(result){
   console.log("second result",result)
      return add_positivenos_async(result,result)
   }).then(function(result){
      console.log("third result",result)
   })

   console.log('end')
</script> 

上述程式碼的輸出將如下所示:

end
first result 30
second result 60
third result 120

下面詳細討論 Promise 物件的一些常用方法:

promise.all()

此方法可用於聚合多個 Promise 的結果。

語法

promise.all() 方法的語法如下所示,其中,iterable 是一個可迭代物件,例如陣列。

Promise.all(iterable);

示例

下面的示例執行一系列非同步操作 [add_positivenos_async(10,20),add_positivenos_async(30,40),add_positivenos_async(50,60)]。當所有操作完成後,Promise 完全 resolve。

<script>   
   function add_positivenos_async(n1, n2) {
      let p = new Promise(function (resolve, reject) {
         if (n1 >= 0 && n2 >= 0) {
            //do some complex time consuming work
            resolve(n1 + n2)
         }
         else
            reject('NOT_Postive_Number_Passed')
      })

      return p;
   }
   //Promise.all(iterable)

Promise.all([add_positivenos_async(10,20),add_positivenos_async(30,40),add_positivenos_async(50,60)])
   .then(function(resolveValue){
      console.log(resolveValue[0])
      console.log(resolveValue[1])
      console.log(resolveValue[2])
      console.log('all add operations done')
   })
   .catch(function(err){
      console.log('Error',err)
   })
   console.log('end')
</script> 

上述程式碼的輸出如下:

end
30
70
110
all add operations done

promise.race()

此函式接受一個 Promise 陣列,並返回第一個完成的 Promise。

語法

promise.race() 函式的語法如下所示,其中,iterable 是一個可迭代物件,例如陣列。

Promise.race(iterable)

示例

下面的示例接受一個非同步運算元組 [add_positivenos_async(10,20),add_positivenos_async(30,40)]

只要任何一個加法操作完成,Promise 就會 resolve。Promise 不會等待其他非同步操作完成。

<script>   
   function add_positivenos_async(n1, n2) {
      let p = new Promise(function (resolve, reject) {
         if (n1 >= 0 && n2 >= 0) {
            //do some complex time consuming work
            resolve(n1 + n2)
         } else
            reject('NOT_Postive_Number_Passed')
      })

      return p;
   }

   //Promise.race(iterable)
   Promise.race([add_positivenos_async(10,20),add_positivenos_async(30,40)])
   .then(function(resolveValue){
      console.log('one of them is done')
      console.log(resolveValue)
   }).catch(function(err){
      console.log("Error",err)
   })

   console.log('end')
</script> 

上述程式碼的輸出如下:

end
one of them is done
30

Promise 是在 JavaScript 中實現非同步程式設計的一種簡潔方法(ES6 的新特性)。在 Promise 之前,使用回撥函式來實現非同步程式設計。讓我們首先了解什麼是非同步程式設計及其使用回撥函式的實現。

理解回撥函式

一個函式可以作為引數傳遞給另一個函式。這種機制被稱為回撥函式。回撥函式在事件處理中很有用。

以下示例將幫助我們更好地理解這個概念。

<script>   
   function notifyAll(fnSms, fnEmail) {   
      console.log('starting notification process');   
      fnSms();   
      fnEmail();   
   }   
   notifyAll(function() {   
      console.log("Sms send ..");   
   }, 
   function() {   
      console.log("email send ..");   
   });   
   console.log("End of script"); 
   //executes last or blocked by other methods   
</script> 

在上例所示的notifyAll() 方法中,通知是透過傳送簡訊和傳送電子郵件來實現的。因此,notifyAll 方法的呼叫者必須傳遞兩個函式作為引數。每個函式承擔單一職責,例如傳送簡訊和傳送電子郵件。

執行上述程式碼後,將顯示以下輸出。

starting notification process 
Sms send .. 
Email send .. 
End of script 

在上述程式碼中,函式呼叫是同步的。這意味著 UI 執行緒將等待整個通知過程完成。同步呼叫會變成阻塞呼叫。現在讓我們瞭解非阻塞或非同步呼叫。

理解非同步回撥

考慮上面的例子。

為了啟用指令碼,對 notifyAll() 方法執行非同步或非阻塞呼叫。我們將使用 JavaScript 的setTimeout() 方法。此方法預設情況下是非同步的。

setTimeout() 方法接受兩個引數:

  • 一個回撥函式。

  • 呼叫方法後的秒數。

在這種情況下,通知過程已被包裝在超時中。因此,它將延遲兩秒鐘,由程式碼設定。notifyAll() 將被呼叫,主執行緒繼續執行其他方法。因此,通知過程不會阻塞主 JavaScript 執行緒。

<script>   
   function notifyAll(fnSms, fnEmail) {   
      setTimeout(function() {   
         console.log('starting notification process');   
         fnSms();   
         fnEmail();   
      }, 2000);   
   }   
   notifyAll(function() {   
      console.log("Sms send ..");   
   },  
   function() {   
      console.log("email send ..");   
   });   
   console.log("End of script"); //executes first or not blocked by others   
</script>

執行上述程式碼後,將顯示以下輸出。

End of script 
starting notification process 
Sms send .. 
Email send .. 

如果有多個回撥函式,程式碼看起來會很嚇人。

<script>   
   setTimeout(function() {   
      console.log("one");   
      setTimeout(function() {   
         console.log("two");   
         setTimeout(function() {   
            console.log("three");   
         }, 1000);   
      }, 1000);   
   }, 1000);   
</script>

ES6 透過引入 Promise 的概念來解決這個問題。Promise 是“延續事件”,它們幫助你以更簡潔的程式碼風格一起執行多個非同步操作。

示例

讓我們用一個例子來理解這一點。以下是相同的語法。

var promise = new Promise(function(resolve , reject) {    
   // do a thing, possibly async , then..  
   if(/*everthing turned out fine */)    resolve("stuff worked");  
   else     
   reject(Error("It broke"));  
});  
return promise;
// Give this to someone

實現 Promise 的第一步是建立一個將使用 Promise 的方法。假設在這個例子中,getSum() 方法是非同步的,即它的操作不應該阻塞其他方法的執行。一旦此操作完成,它稍後將通知呼叫者。

以下示例(步驟 1)聲明瞭一個 Promise 物件“var promise”。Promise 建構函式首先接收兩個函式,一個是用於工作成功完成,另一個是用於發生錯誤。

Promise 透過使用 resolve 回撥並傳入結果(即 n1+n2)來返回計算結果。

步驟 1 − resolve(n1 + n2);

如果 getSum() 遇到錯誤或意外情況,它將呼叫 Promise 中的 reject 回撥方法,並將錯誤資訊傳遞給呼叫者。

步驟 2 − reject(Error("Negatives not supported"));

方法實現如下程式碼所示(步驟 1)。

function getSum(n1, n2) {   
   varisAnyNegative = function() {   
      return n1 < 0 || n2 < 0;   
   }   
   var promise = new Promise(function(resolve, reject) {   
      if (isAnyNegative()) {   
         reject(Error("Negatives not supported"));   
      }   
      resolve(n1 + n2)
   });   
   return promise;   
} 

第二步詳細介紹了呼叫者的實現(步驟 2)。

呼叫者應該使用“then”方法,該方法接受兩個回撥方法——第一個用於成功,第二個用於失敗。每個方法都接受一個引數,如下程式碼所示。

getSum(5, 6)   
.then(function (result) {   
   console.log(result);   
},   
function (error) {   
   console.log(error);   
});

執行上述程式碼後,將顯示以下輸出。

11 

由於 getSum() 的返回型別是 Promise,我們實際上可以有多個“then”語句。第一個“then”將有一個 return 語句。

getSum(5, 6)   
.then(function(result) {   
   console.log(result);   
   returngetSum(10, 20); 
   // this returns another promise   
},   
function(error) {   
   console.log(error);   
})   
.then(function(result) {   
   console.log(result);   
}, 
function(error) {   
   console.log(error);
});    

執行上述程式碼後,將顯示以下輸出。

11
30

以下示例使用 getSum() 方法發出三個 then() 呼叫。

<script>   
   function getSum(n1, n2) {   
      varisAnyNegative = function() {   
         return n1 < 0 || n2 < 0;   
      }   
      var promise = new Promise(function(resolve, reject) {   
         if (isAnyNegative()) {   
            reject(Error("Negatives not supported"));   
         }   
         resolve(n1 + n2);   
      });   
      return promise;   
   }   
   getSum(5, 6)   
   .then(function(result) {   
      console.log(result);   
      returngetSum(10, 20); 
      //this returns another Promise   
   },   
   function(error) {   
      console.log(error);   
   })
   .then(function(result) {   
      console.log(result);   
      returngetSum(30, 40); 
      //this returns another Promise   
   }, 
   function(error) {   
      console.log(error);   
   })   
   .then(function(result) {   
      console.log(result);   
   }, 
   function(error) {         
      console.log(error);   
   });   
   console.log("End of script ");   
</script> 

執行上述程式碼後,將顯示以下輸出。

程式首先顯示“指令碼結束”,然後逐個顯示呼叫 getSum() 方法的結果。

End of script  
11 
30 
70

這表明 getSum() 是以非同步方式或非阻塞方式呼叫的。Promise 提供了一種簡潔有效的方法來處理回撥函式。

ES6 - 模組

介紹

考慮這樣一種情況:需要重用 JavaScript 程式碼的部分。ES6 透過模組的概念來解決這個問題。

模組組織了一組相關的 JavaScript 程式碼。模組可以包含變數和函式。模組只不過是一個檔案中編寫的 JavaScript 程式碼塊。預設情況下,模組的變數和函式不可用。模組中的變數和函式應該匯出,以便可以從其他檔案中訪問它們。ES6 中的模組僅在嚴格模式下工作。這意味著在模組中宣告的變數或函式將不會全域性可用。

匯出模組

export 關鍵字可以用來匯出模組中的元件。模組中的匯出可以分為以下幾類:

  • 命名匯出
  • 預設匯出

命名匯出

命名匯出由它們的名稱區分。一個模組中可以有多個命名匯出。模組可以使用以下語法匯出選定的元件:

語法 1

//using multiple export keyword
export component1
export component2
...
...
export componentN

語法 2

或者,模組中的元件也可以使用單個 export 關鍵字和 {} 繫結語法匯出,如下所示:

//using single export keyword

export {component1,component2,....,componentN}

預設匯出

只需要匯出單個值的模組可以使用預設匯出。每個模組只能有一個預設匯出。

語法

export default component_name

但是,一個模組可以同時具有預設匯出和多個命名匯出。

匯入模組

為了能夠使用模組,可以使用import 關鍵字。一個模組可以有多個import 語句

匯入命名匯出

匯入命名匯出時,相應元件的名稱必須匹配。

語法

import {component1,component2..componentN} from module_name

但是,匯入命名匯出時,可以使用 as 關鍵字重新命名它們。使用以下語法:

import {original_component_name as new_component_name }

可以使用星號 * 運算子將所有命名匯出匯入到一個物件中。

import * as variable_name from module_name

匯入預設匯出

與命名匯出不同,預設匯出可以使用任何名稱匯入。

語法

import any_variable_name from module_name

示例:命名匯出

步驟 1 − 建立一個檔案 company1.js 並新增以下程式碼:

let company = "TutorialsPoint"

let getCompany = function(){
   return company.toUpperCase()
}

let setCompany = function(newValue){
   company = newValue
}

export {company,getCompany,setCompany}

步驟 2 − 建立一個檔案 company2.js。此檔案使用 company1.js 檔案中定義的元件。可以使用以下任何一種方法匯入模組。

方法 1

import {company,getCompany} from './company1.js'

console.log(company)
console.log(getCompany())

方法 2

import {company as x, getCompany as y} from './company1.js'

console.log(x)
console.log(y())

方法 3

import * as myCompany from './company1.js'

console.log(myCompany.getCompany())
console.log(myCompany.company)

步驟 3 − 使用 HTML 檔案執行模組

為了執行這兩個模組,我們需要建立一個如下所示的 html 檔案,並在活動伺服器上執行它。注意,我們應該在 script 標籤中使用屬性 type="module"

<!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>
</head>
<body>
   <script src="./company2.js" type="module"></script>
</body>
</html>

上述程式碼的輸出將如下所示:

TutorialsPoint
TUTORIALSPOINT

預設匯出

步驟 1 − 建立一個檔案company1.js 並新增以下程式碼:

let name = 'TutorialsPoint'

let company = {
   getName:function(){
      return name
   },
   setName:function(newName){
      name = newName
   }
}

export default company

步驟 2 − 建立一個檔案company2.js。此檔案使用 company1.js 檔案中定義的元件。

import c from './company1.js'
console.log(c.getName())
c.setName('Google Inc')
console.log(c.getName())

步驟 3 − 使用HTML 檔案執行模組

為了執行這兩個模組,我們需要建立一個如下所示的 html 檔案,並在活動伺服器上執行它。注意,我們應該在 script 標籤中使用屬性 type="module"

<!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>
</head>
<body>
   <script src="./company2.js" type="module"></script>
</body>
</html>

上述程式碼的輸出如下所示:

TutorialsPoint
Google Inc

示例:組合預設匯出和命名匯出

步驟 1 − 建立一個檔案company1.js 並新增以下程式碼:

//named export
export let name = 'TutorialsPoint'

let company = {
   getName:function(){
      return name
   },
   setName:function(newName){
      name =newName
   }
}
//default export
export default company

步驟 2 − 建立一個檔案company2.js。此檔案使用company1.js檔案中定義的元件。先匯入預設匯出,然後匯入命名匯出。

import c, {name} from './company1.js'

console.log(name)
console.log(c.getName())
c.setName("Mohtashim")
console.log(c.getName())

步驟 3 − 使用 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>
   </head>
   <body>
      <script src="company2.js" type="module"></script>
   </body>
</html>

上述程式碼的輸出將如下所示:

TutorialsPoint
TutorialsPoint
Mohtashim

ES6 - 錯誤處理

程式設計中有三種類型的錯誤:語法錯誤、執行時錯誤和邏輯錯誤。

語法錯誤

語法錯誤,也稱為解析錯誤,在傳統的程式語言中發生在編譯時,在 JavaScript 中發生在解釋時。當 JavaScript 中發生語法錯誤時,只有與語法錯誤位於同一執行緒中的程式碼受影響,其他執行緒中的其餘程式碼將繼續執行,假設它們不依賴於包含錯誤的程式碼。

執行時錯誤

執行時錯誤,也稱為異常,發生在執行期間(編譯/解釋之後)。異常也會影響發生它們的執行緒,允許其他 JavaScript 執行緒繼續正常的執行。

邏輯錯誤

邏輯錯誤可能是最難追蹤的錯誤型別。這些錯誤不是語法錯誤或執行時錯誤的結果。相反,當你在驅動指令碼的邏輯中犯錯並且沒有得到預期的結果時,就會發生這些錯誤。

你無法捕獲這些錯誤,因為這取決於你的業務需求,你想要在程式中使用哪種邏輯。

當發生執行時錯誤時,JavaScript 會丟擲 Error 物件的例項。下表列出了 Error 物件的預定義型別。

序號 Error 物件和描述
1

EvalError

建立一個例項,表示關於全域性函式eval()發生的錯誤。

2

RangeError

建立一個例項,表示當數值變數或引數超出其有效範圍時發生的錯誤。

3

ReferenceError

建立一個例項,表示取消引用無效引用時發生的錯誤。

4

SyntaxError

建立一個例項,表示在解析程式碼時發生的語法錯誤。

5

TypeError

建立一個例項,表示當變數或引數型別無效時發生的錯誤。

6

URIError

建立一個例項,表示當encodeURI()decodeURI() 傳遞無效引數時發生的錯誤。

丟擲異常

可以使用throw 語句引發錯誤(預定義或使用者定義)。稍後可以捕獲這些異常,並採取相應的措施。以下是相同的語法。

語法:丟擲通用異常

throw new Error([message]) 
OR 
throw([message])

語法:丟擲特定異常

throw new Error_name([message]) 

異常處理

異常處理透過try...catch 語句完成。當程式遇到異常時,程式將以不友好的方式終止。為了防止這種意外錯誤,我們可以將程式碼包裝在 try...catch 語句中。

try 塊必須後跟一個 catch 塊或一個 finally 塊(或兩者都有)。當 try 塊中發生異常時,異常將放入 e 中,並執行 catch 塊。可選的 finally 塊在 try/catch 後無條件執行。

以下是該方法的語法。

try {  
   // Code to run  
   [break;]  
} catch ( e ) {  
   // Code to run if an exception occurs
   [break;]  
}[ finally {  
   // Code that is always executed regardless of  
   // an exception occurring  
}]  

示例

var a = 100; 
var b = 0; 
try { 
   if (b == 0 ) { 
      throw(“Divide by zero error.”); 
   } else { 
      var c = a / b; 
   } 
} 
catch( e ) { 
   console.log("Error: " + e ); 
}

輸出

執行上述程式碼後,將顯示以下輸出。

Error: Divide by zero error

注意 − 注意:你可以在一個函式中引發異常,然後可以使用try...catch 塊在同一個函式或呼叫函式中捕獲該異常。

onerror() 方法

onerror 事件處理程式是 JavaScript 中第一個用於處理錯誤的功能。每當頁面上發生異常時,就會在 window 物件上觸發 error 事件。

示例

<html> 
   <head> 
      <script type = "text/javascript"> 
         window.onerror  =  function () {  
            document.write ("An error occurred.");  
         } 
      </script> 
   </head> 

   <body> 
      <p>Click the following to see the result:</p> 
      <form> 
         <input type = "button" value = "Click Me" onclick = "myFunc();" /> 
      </form> 
   </body> 
</html> 

輸出

執行上述程式碼後,將顯示以下輸出。

one error method

onerror 事件處理程式提供三條資訊來識別錯誤的確切性質:

  • 錯誤資訊 − 瀏覽器為給定錯誤顯示的相同訊息。

  • URL − 發生錯誤的檔案。

  • 行號 − 給定 URL 中導致錯誤的行號。

以下示例顯示如何提取此資訊。

示例

<html> 
   <head> 
      <script type = "text/javascript"> 
         window.onerror  =  function (msg, url, line) {  
            document.write ("Message : " + msg );  
            document.write ("url : " + url );  
            document.write ("Line number : " + line );  
         } 
      </script> 
   </head> 

   <body> 
      <p>Click the following to see the result:</p> 
      <form> 
         <input type = "button" value = "Click Me" onclick = "myFunc();" /> 
      </form> 
   </body> 
</html> 

自定義錯誤

JavaScript 支援自定義錯誤的概念。以下示例說明了這一點。

示例 1:帶有預設訊息的自定義錯誤

function MyError(message) { 
   this.name = 'CustomError'; 
   this.message = message || 'Error raised with default message'; 
} 
try { 
   throw new MyError(); 
} catch (e) {  
   console.log(e.name);      
   console.log(e.message);  // 'Default Message' 
}

執行上述程式碼後,將顯示以下輸出。

CustomError 
Error raised with default message

示例 2:帶有使用者定義錯誤訊息的自定義錯誤

function MyError(message) { 
   this.name = 'CustomError'; 
   this.message = message || 'Default Error Message';  
} try { 
   throw new MyError('Printing Custom Error message'); 
} 
catch (e) { 
   console.log(e.name);      
   console.log(e.message);  
}

執行上述程式碼後,將顯示以下輸出。

CustomError 
Printing Custom Error message

ES6 - 物件擴充套件

字串擴充套件

ES6 中新增到 String 物件的一些常用方法:

序號 方法 & 描述
1 str.startsWith(searchString[, position])

確定字串是否以指定字串的字元開頭。返回 true 或 false。

2 str.endsWith(searchString[, length])

確定字串是否以指定字串的字元結尾。返回 true/false。

3 str.includes(searchString[, position])

確定一個字串是否可以在另一個字串中找到。

4 str.repeat(count)

構造並返回一個新字串,該字串包含呼叫它的字串的指定數量的副本,連線在一起。

正則表示式擴充套件

例如,在正則表示式/[A-Z]/g中,開頭和結尾的 / 稱為定界符。結束定界符後的任何內容都稱為修飾符。ES6 添加了一個新的修飾符/g,其中g代表全域性。這將匹配字串中模式的所有例項,而不僅僅是一個。

示例

以下示例搜尋並返回字串中的所有大寫字元。

<script>
   let str = 'JJavascript is Fun to Work , very Fun '
   let regex = /[A-Z]/g // g stands for global matches
   let result = str.match(regex);
   console.log(result)
</script>

上述程式碼的輸出將如下所示:

["J", "J", "F", "W", "F"]

正則表示式搜尋區分大小寫。要關閉區分大小寫,請使用/i 修飾符。

示例

以下示例執行不區分大小寫的全域性匹配。該示例將fun替換為enjoyable

<script>
   // /gi global match ignore case

   let str = 'Javascript is fun to Work , very Fun '
   let regex = /Fun/gi;
   console.log(str.replace(regex,'enjoyable'));
   console.log(str)
   console.log(str.search(regex))
</script>

上述程式碼的輸出將如下所示:

Javascript is enjoyable to Work , very enjoyable
Javascript is fun to Work , very Fun
15

數字

ES6 中新增到Number 物件的一些常用方法:

序號 方法 & 描述
1 Number.isFinite(value)

方法確定傳遞的值是否為有限數字。返回 true/false。

2 Number.isNaN(value)

如果給定值為 NaN 且其型別為 Number,則返回 true;否則返回 false。

3 Number.parseFloat(string)

從給定值解析的浮點數。如果該值無法轉換為數字,則返回 NaN。

4 Number.parseInt(string,[ radix])

方法解析字串引數並返回指定基數或基數的整數。

Math

ES6 中新增到Math 物件的一些常用方法:

序號 方法 & 描述
1 Math.sign()

函式返回數字的符號,指示數字是正數、負數還是零。

2 Math.trunc()

函式透過刪除任何小數位來返回數字的整數部分。

ES6 中 Array 的方法

下表重點介紹了 ES6 中的不同陣列方法及其描述。

序號 方法 & 描述
1 copyWithin()

將陣列的一部分淺複製到同一陣列中的另一個位置,並返回它,而不會修改其長度。

2 entries()

方法返回一個新的 Array Iterator 物件,其中包含陣列中每個索引的鍵/值對。

3 find()

方法返回陣列中第一個滿足提供的測試函式的元素的值。否則返回 undefined。

4 fill()

方法使用靜態值填充陣列從起始索引到結束索引的所有元素。它返回修改後的陣列。

5 Array.of()

方法根據引數的數量和型別,從可變數量的引數建立一個新的 Array 例項。

6 Array.from()

方法從類似陣列或可迭代物件建立淺複製。

物件

與 Object 函式相關的方法如下表所示,以及相應的描述。

序號 方法 & 描述
1 Object.is()

方法確定兩個值是否相同。

2 Object.setPrototypeOf()

方法將指定物件的原型設定為另一個物件或 null。

3 Object.assign()

方法用於將一個或多個源物件的所有可列舉自身屬性的值複製到目標物件。它將返回目標物件。

ES6 - Reflect API

ES6 引入了圍繞超程式設計的新功能,超程式設計涉及檢查或修改程式的結構,或更改語言本身的工作方式。

以下是超程式設計的三種形式:

  • 自省 − 自省是指程式收集有關自身的資訊。一些用於自省的 JavaScript 運算子示例是typeof、instanceof等。

  • 自我修改 − 自我修改是指在執行時修改程式的結構。它涉及在執行時訪問或建立新屬性。換句話說,自我修改是指某些程式碼修改自身。

  • 攔截 − 指的是程式碼修改程式語言的預設行為。攔截涉及修改程式語言的語義或在執行時向程式新增新的構造。

ES6 引入了支援超程式設計的 Reflect 應用程式程式設計介面 (Reflect API) 和 Proxy API。

使用 Reflect API 進行超程式設計

ES6 中的 Reflect API 允許我們在執行時檢查或修改程式的類、物件、屬性和方法。Reflect API 提供全域性 Reflect 物件,該物件具有可用於自省的靜態方法。這些方法用於發現有關程式碼的底層資訊。Reflect API 可用於構建在執行時檢查和自省程式的自動化測試框架。

下面給出 Reflect 物件的一些常用方法:

序號 方法 & 描述
1 Reflect.apply()

使用 args 引數中指定的引數呼叫目標函式。

2 Reflect.construct()

等效於呼叫 new target(...args) 類物件。

3 Reflect.get()

返回屬性值的函式。

4 Reflect.set()

為屬性賦值的函式。返回一個布林值,如果更新成功則為 true。

5 Reflect.has()

in 運算子作為函式。返回一個布林值,指示是否存在自身或繼承的屬性。

ES6 - Proxy API

ES6 使用 Proxy 實現攔截形式的超程式設計。與 ReflectAPI 類似,Proxy API 是在 ES6 中實現超程式設計的另一種方法。Proxy 物件用於為基本操作定義自定義行為。代理物件代表實際物件執行某些操作。

下面給出與 ES6 代理相關的各種術語。

序號 方法 & 描述
1

handler

包含陷阱的佔位符物件。

2

traps

提供屬性訪問的方法。這類似於作業系統中陷阱的概念。

1

target

代理虛擬化的物件。它通常用作代理的後端儲存。

語法

下面是 Proxy API 的語法,其中,target可以是任何型別的物件,如陣列、函式或另一個代理,而handler是一個其屬性為函式的物件。這定義了代理的行為。

const proxy = new Proxy(target,handler)

Handler 方法

handler 物件包含 Proxy 的陷阱。所有陷阱都是可選的。如果未定義陷阱,則預設行為是將操作轉發到目標。一些常見的處理程式方法如下:

序號 方法 & 描述
1 handler.apply()

函式呼叫的陷阱。

2 handler.construct()

new 運算子的陷阱。

3 handler.get()

獲取屬性值的陷阱。

4 handler.set()

設定屬性值的陷阱。

5 handler.has()

in 運算子的陷阱。

ES6 - 資料驗證

表單驗證通常發生在伺服器端,在客戶端輸入所有必要資料並按下“提交”按鈕之後。如果客戶端輸入的資料不正確或丟失,伺服器必須將所有資料傳送回客戶端,並請求使用正確的資訊重新提交表單。這是一個非常冗長的過程,它會給伺服器帶來很大的負擔。

JavaScript 提供了一種在將表單資料傳送到 Web 伺服器之前驗證客戶端計算機上表單資料的方法。表單驗證通常執行兩個功能。

  • 基本驗證 − 首先,必須檢查表單以確保所有必填欄位都已填寫。這隻需要迴圈遍歷表單中的每個欄位並檢查資料。

  • 資料格式驗證 − 其次,必須檢查輸入資料的正確格式和值。你的程式碼必須包含適當的邏輯來測試資料的正確性。

示例

我們將透過一個示例來了解驗證過程。這是一個簡單的 html 格式表單。

<html>
 
   <head> 
      <title>Form Validation</title> 
      <script type = "text/javascript"> 
         <!--  
            // Form validation code will come here.  
            //
         --> 
      </script> 
   </head> 

   <body> 
      <form action = "/cgi-bin/test.cgi" name = "myForm" onsubmit = "return(validate());"> 
         <table cellspacing = "2" cellpadding = "2" border = "1"> 
            <tr> 
               <td align = "right">Name</td> 
               <td><input type = "text" name = "Name" /></td>
            </tr> 
            <tr> 
               <td align = "right">EMail</td> 
               <td><input type = "text" name = "EMail" /></td> 
            </tr> 
            <tr> 
               <td align = "right">Zip Code</td> 
               <td><input type = "text" name = "Zip" /></td> 
            </tr> 
            <tr> 
               <td align = "right">Country</td> 
               <td> 
                  <select name = "Country"> 
                     <option value = "-1" selected>[choose yours]</option> 
                     <option value = "1">USA</option> 
                     <option value = "2">UK</option> 
                     <option value = "3">INDIA</option> 
                  </select> 
               </td> 
            </tr> 
            <tr> 
               <td align = "right"></td> 
               <td><input type = "submit" value = "Submit" /></td> 
            </tr> 
         </table> 
      </form> 
   </body> 
   
</html> 

輸出

執行上述程式碼後,將顯示以下輸出。

form validation

基本表單驗證

首先讓我們看看如何進行基本的表單驗證。在上表中,我們在發生onsubmit事件時呼叫validate()來驗證資料。以下程式碼顯示了此 validate() 函式的實現。

<script type = "text/javascript"> 
   <!--  
      // Form validation code will come here. function validate() {    
         if( document.myForm.Name.value == "" ) {  
            alert( "Please provide your name!" );      
            document.myForm.Name.focus() ;      
            return false;  
         }  
         if( document.myForm.EMail.value == "" ) {  
            alert( "Please provide your Email!" );      
            document.myForm.EMail.focus() ;      
            return false; 
         }  
         if( document.myForm.Zip.value == "" ||            
         isNaN( document.myForm.Zip.value ) ||            
         document.myForm.Zip.value.length != 5 ) {  
            alert( "Please provide a zip in the format #####." );      
            document.myForm.Zip.focus() ;      
            return false;  
         }  
         if( document.myForm.Country.value == "-1" ) {  
            alert( "Please provide your country!" );      
            return false;  
         }  
         return( true );  
      }  
      //
   --> 
</script>

資料格式驗證

現在我們將看到如何在將其提交到 Web 伺服器之前驗證輸入的表單資料。

以下示例顯示如何驗證輸入的電子郵件地址。電子郵件地址必須至少包含一個“@”符號和一個點(.)。此外,“@”不能是電子郵件地址的第一個字元,最後一個點必須至少在“@”符號之後一個字元。

示例

嘗試以下用於電子郵件驗證的程式碼。

<script type = "text/javascript"> 
   <!--  
      function validateEmail() { 
         var emailID = document.myForm.EMail.value;    
         atpos = emailID.indexOf("@");    
         dotpos = emailID.lastIndexOf(".");    
         
         if (atpos < 1 || ( dotpos - atpos < 2 )) {       
            alert("Please enter correct email ID")         
            document.myForm.EMail.focus() ;         
            return false;    
         }     
         return( true );  
      } 
      //
   --< 
</script>

ES6 - 動畫

您可以使用 JavaScript 建立一個複雜的動畫,其中包括但不限於以下元素:

  • 煙火
  • 淡出效果
  • 淡入或淡出
  • 頁面淡入或頁面淡出
  • 物件移動

在本章中,我們將瞭解如何使用 JavaScript 建立動畫。

JavaScript 可用於根據邏輯方程或函式確定的某種模式,在頁面周圍移動多個 DOM 元素(<img />、<div>或任何其他 HTML 元素)。

JavaScript 提供以下函式,這些函式經常用於動畫程式中。

  • setTimeout(function, duration) − 此函式在從現在起 duration 毫秒後呼叫該函式。

  • setInterval(function, duration) − 此函式每隔 duration 毫秒呼叫一次該函式。

  • clearTimeout(setTimeout_variable) − 此函式清除由 setTimeout() 函式設定的任何計時器。

JavaScript 還可以設定 DOM 物件的許多屬性,包括其在螢幕上的位置。您可以設定物件的 top 和 left 屬性以將其放置在螢幕上的任何位置。以下是相同的語法。

// Set distance from left edge of the screen.  
object.style.left = distance in pixels or points;    
or  
// Set distance from top edge of the screen.  
object.style.top = distance in pixels or points;

手動動畫

因此,讓我們使用 DOM 物件屬性和 JavaScript 函式實現一個簡單的動畫,如下所示。以下列表包含不同的 DOM 方法。

  • 我們使用 JavaScript 函式 getElementById() 獲取 DOM 物件,然後將其賦值給全域性變數 imgObj

  • 我們定義了一個初始化函式 init() 來初始化 imgObj,在其中我們設定了它的 position 和 left 屬性。

  • 我們在視窗載入時呼叫初始化函式。

  • 我們呼叫 moveRight() 函式將左側距離增加 10 畫素。您也可以將其設定為負值以將其移動到左側。

示例

嘗試以下示例

<html> 
   <head> 
      <title>JavaScript Animation</title> 
      <script type = "text/javascript"> 
         <!--  
            var imgObj = null; function init(){  
               imgObj = document.getElementById('myImage');
               imgObj.style.position = 'relative';     
               imgObj.style.left = '0px';   
            }     
            function moveRight(){  
               imgObj.style.left = parseInt(
               imgObj.style.left) + 10 + 'px';  
            }  
            window.onload = init;  
            //
         --> 
      </script> 
   </head> 
   
   <body> 
      <form> 
         <img id = "myImage" src = "/images/html.gif" /> 
         <p>Click button below to move the image to right</p> 
         <input type = "button" value = "Click Me" onclick = "moveRight();" /> 
      </form>
   </body>
   
</html>

自動動畫

在上面的示例中,我們看到了影像如何透過每次點擊向右移動。我們可以使用 JavaScript 函式 setTimeout() 自動執行此過程,如下所示。

這裡我們添加了更多方法。所以,讓我們看看這裡有什麼新內容。

  • moveRight() 函式呼叫 setTimeout() 函式來設定 imgObj 的位置。

  • 我們添加了一個新函式 stop() 來清除由 setTimeout() 函式設定的計時器,並將物件設定在其初始位置。

示例

嘗試以下示例程式碼。

<html> 
   <head> 
      <title>JavaScript Animation</title> 
      <script type = "text/javascript"> 
         <!--  
            var imgObj = null; var animate ; function init(){  
               imgObj = document.getElementById('myImage');     
               imgObj.style.position = 'relative';    
               imgObj.style.left = '0px'; 
            }  
            function moveRight(){  
               imgObj.style.left = parseInt(imgObj.style.left) + 10 + 'px';    
               animate = setTimeout(moveRight,20); 
               // call moveRight in 20msec  
            }  
            function stop() {     
               clearTimeout(animate);    
               imgObj.style.left = '0px';   
            }  
            window.onload = init;  
            //
         --> 
      </script> 
   </head> 

   <body> 
      <form> 
         <img id = "myImage" src = "/images/html.gif" /> 
         <p>Click the buttons below to handle animation</p> 
         <input type="button" value="Start" onclick = "moveRight();" /> 
         <input type = "button" value="Stop" onclick = "stop();" /> 
      </form>    
   </body> 
</html>

滑鼠事件的懸停效果

這是一個簡單的示例,顯示了滑鼠事件的影像懸停效果。

讓我們看看我們在以下示例中使用了什麼 -

  • 載入此頁面時,“if”語句檢查影像物件是否存在。如果影像物件不可用,則不會執行此程式碼塊。

  • Image() 建構函式建立並預載入一個名為 image1 的新影像物件。

  • src 屬性被賦值為名為 /images/html.gif 的外部影像檔案的名稱。

  • 類似地,我們建立了 image2 物件,並在該物件中賦值了 /images/http.gif

  • #(井號)停用連結,以便瀏覽器在單擊時不會嘗試轉到 URL。此連結是一個影像。

  • 當用戶的滑鼠移動到連結上時,將觸發 onMouseOver 事件處理程式;當用戶的滑鼠移開連結(影像)時,將觸發 onMouseOut 事件處理程式。

  • 當滑鼠移到影像上時,HTTP 影像會從第一張影像更改為第二張影像。當滑鼠移開影像時,將顯示原始影像。

  • 當滑鼠移開連結時,初始影像 html.gif 將重新出現在螢幕上。

<html> 
   <head> 
      <title>Rollover with a Mouse Events</title> 
      <script type = "text/javascript"> 
         <!--  
            if(document.images) {  
               var image1 = new Image();       
               // Preload an image image1.src = "/images/html.gif";  
                  
               var image2 = new Image();       
               // Preload second image image2.src = "/images/http.gif";  
            }  
            //
         -->
      </script> 
   </head> 

   <body> 
      <p>Move your mouse over the image to see the result</p>
      <a href = "#" onMouseOver = "document.myImage.src = image2.src;"      
         onMouseOut = "document.myImage.src = image1.src;"> 
         <img name = "myImage" src = "/images/html.gif" /> 
      </a> 
   </body>
   
</html>

ES6 - 多媒體

JavaScript navigator 物件包含一個名為 plugins 的子物件。此物件是一個數組,每個安裝在瀏覽器上的外掛都有一個條目。navigator.plugins 物件僅受 Netscape、Firefox 和 Mozilla 支援。

示例

以下示例顯示瞭如何列出安裝在瀏覽器中的所有外掛。

<html> 
   <head> 
      <title>List of Plug-Ins</title> 
   </head> 
   <body> 
      <table border = "1"> 
         <tr>
            <th>Plug-in Name</th>
            <th>Filename</th>
            <th>Description</th>
         </tr> 
         <script LANGUAGE = "JavaScript" type = "text/javascript"> 
            for (i = 0; i<navigator.plugins.length; i++) {    
               document.write("<tr><td>");  
               document.write(navigator.plugins[i].name);    
               document.write("</td><td>");  
               document.write(navigator.plugins[i].filename); 
               document.write("</td><td>");  
               document.write(navigator.plugins[i].description);    
               document.write("</td></tr>");  
            }  
         </script> 
      </table> 
   </body>
   
</html>

輸出

執行上述程式碼後,將顯示以下輸出。

pluggins list

檢查外掛

每個外掛在陣列中都有一個條目。每個條目都有以下屬性 -

  • name − 外掛的名稱。

  • filename − 載入以安裝外掛的可執行檔案。

  • description − 開發人員提供的外掛說明。

  • mimeTypes − 一個數組,其中包含外掛支援的每個 MIME 型別的一個條目。

您可以在指令碼中使用這些屬性來查詢已安裝的外掛,然後使用 JavaScript 播放相應的媒體檔案。檢視以下程式碼。

<html> 
   <head> 
      <title>Using Plug-Ins</title> 
   </head> 
   
   <body> 
      <script language = "JavaScript" type = "text/javascript"> 
         media  =  navigator.mimeTypes["video/quicktime"]; if (media) {  
            document.write("<embed src = 'quick.mov' height = 100 width = 100>");  
         } else {  
            document.write("<img src = 'quick.gif' height = 100 width = 100>");  
         }  
      </script> 
   </body>
</html>

注意 − 在這裡,我們使用 HTML <embed> 標籤來嵌入多媒體檔案。

控制多媒體

讓我們來看一個幾乎在所有瀏覽器中都能工作的實際示例。

<html> 
   <head> 
      <title>Using Embeded Object</title> 
      
      <script type = "text/javascript"> 
         <!--  
            function play() {  
               if (!document.demo.IsPlaying()) {      
                  document.demo.Play();  
               }  
            }  
            function stop() {  
               if (document.demo.IsPlaying()){      
                  document.demo.StopPlay();  
               }  
            }  
            function rewind() { 
               if (document.demo.IsPlaying()){      
                  document.demo.StopPlay();  
               }  
               document.demo.Rewind();  
            } 
            //
         --> 
      </script> 
   </head> 
   <body> 
      <embed id = "demo" name = "demo"
         src = "http://www.amrood.com/games/kumite.swf" 
         width = "318" height = "300" play = "false" loop = "false"     
         pluginspage = "http://www.macromedia.com/go/getflashplayer"     
         swliveconnect = "true"> 
      </embed> 
      
      <form name = "form" id = "form" action = "#" method = "get"> 
         <input type = "button" value = "Start" onclick = "play();" /> 
         <input type = "button" value = "Stop" onclick = "stop();" /> 
         <input type = "button" value = "Rewind" onclick = "rewind();" /> 
      </form>
   </body> 
</html>

ES6 - 除錯

開發人員在編碼時偶爾會犯錯誤。程式或指令碼中的錯誤稱為bug(錯誤)。

查詢和修復錯誤的過程稱為debugging(除錯),是開發過程的正常部分。本章介紹可以幫助您進行除錯任務的工具和技術。

IE 中的錯誤訊息

跟蹤錯誤的最基本方法是在瀏覽器中開啟錯誤資訊。預設情況下,當頁面上發生錯誤時,Internet Explorer 會在狀態列中顯示一個錯誤圖示。

Error Icon

雙擊此圖示將帶您進入一個對話方塊,其中顯示有關已發生特定錯誤的資訊。

由於此圖示很容易被忽略,因此 Internet Explorer 提供了在每次發生錯誤時自動顯示錯誤對話方塊的選項。

要啟用此選項,請選擇工具→Internet 選項→高階選項卡,然後最後選中“顯示每個指令碼錯誤的通知”複選框選項,如下面的螢幕截圖所示。

Internet Options

Firefox 或 Mozilla 中的錯誤訊息

其他瀏覽器(如 Firefox、Netscape 和 Mozilla)會將錯誤訊息傳送到一個名為JavaScript 控制檯錯誤控制檯的特殊視窗。要檢視控制檯,請選擇工具→錯誤控制檯或Web 開發

不幸的是,由於這些瀏覽器在發生錯誤時不會提供任何視覺指示,因此您必須保持控制檯開啟並監視指令碼執行期間的錯誤。

Error Console

錯誤通知

在控制檯或透過 Internet Explorer 對話方塊顯示的錯誤通知是語法錯誤和執行時錯誤的結果。這些錯誤通知包括髮生錯誤的行號。

如果您使用的是 Firefox,則可以單擊錯誤控制檯中提供的錯誤以轉到指令碼中包含錯誤的確切行。

除錯指令碼

有多種方法可以除錯 JavaScript。以下是一些方法。

使用 JavaScript 驗證器

檢查 JavaScript 程式碼中是否存在奇怪錯誤的一種方法是,將其執行透過一個程式進行檢查,以確保其有效且遵循該語言的官方語法規則。這些程式稱為驗證解析器或簡稱驗證器,通常包含在商業 HTML 和 JavaScript 編輯器中。

JavaScript 最方便的驗證器是 Douglas Crockford 的 JavaScript Lint,可在 Douglas Crockford 的 JavaScript Lint 免費獲得。

只需訪問網頁,將您的 JavaScript(僅 JavaScript)程式碼貼上到提供的文字區域中,然後單擊jslint按鈕。此程式將解析您的 JavaScript 程式碼,確保所有變數和函式定義都遵循正確的語法。它還將檢查 JavaScript 語句(例如 if 和 while),以確保它們也遵循正確的格式。

向程式新增除錯程式碼

您可以在程式中使用alert()document.write()方法來除錯程式碼。例如,您可以編寫如下內容 -

var debugging = true; var whichImage = "widget"; 
if( debugging )  
   alert( "Calls swapImage() with argument: " + whichImage ); 
   var swapStatus = swapImage( whichImage ); 
if( debugging )  
alert( "Exits swapImage() with swapStatus=" + swapStatus ); 

透過檢查 alert() 的內容和順序,您可以很容易地檢查程式的執行狀況。

使用 JavaScript 偵錯程式

偵錯程式是一個應用程式,它將指令碼執行的所有方面都置於程式設計師的控制之下。偵錯程式透過一個介面提供對指令碼狀態的細粒度控制,允許您檢查和設定值以及控制執行流程。

將指令碼載入到偵錯程式後,可以逐行執行它,或者指示它在某些斷點處停止。一旦執行停止,程式設計師就可以檢查指令碼及其變數的狀態,以確定是否存在問題。您還可以監視變數的變化。

適用於 Mozilla 和 Netscape 瀏覽器的最新版 Mozilla JavaScript 偵錯程式(代號為 Venkman)可從以下網址下載:www.hacksrus.com/~ginda/venkman

開發人員的實用技巧

您可以記住以下技巧,以減少指令碼中的錯誤數量並簡化除錯過程 -

  • 使用大量的註釋。註釋使您可以解釋編寫指令碼的方式以及解釋程式碼的難點部分。

  • 始終使用縮排使程式碼易於閱讀。縮排語句還可以使您更輕鬆地匹配起始和結束標籤、花括號和其他 HTML 和指令碼元素。

  • 編寫模組化程式碼。儘可能將語句分組到函式中。函式允許您對相關語句進行分組,並輕鬆測試和重用程式碼部分。

  • 命名變數和函式的方式要一致。嘗試使用足夠長的名稱,這些名稱要有意義並且描述變數的內容或函式的目的。

  • 命名變數和函式時使用一致的語法。換句話說,全部小寫或全部大寫;如果您更喜歡 Camel-Back 表示法,則始終如一地使用它。

  • 以模組化方式測試長指令碼。換句話說,不要嘗試在測試任何部分之前編寫整個指令碼。編寫一部分並使其工作,然後再新增下一部分程式碼。

  • 使用描述性的變數和函式名稱,避免使用單字元名稱。

  • 注意您的引號。請記住,引號成對地用於字串周圍,並且兩個引號必須是相同風格的(單引號或雙引號)。

  • 注意您的等號。不應將單個 = 用於比較目的。

  • 使用var關鍵字顯式宣告變數。

使用 Node.js 進行除錯

Node.js 包含一個功能齊全的除錯實用程式。要使用它,請使用 debug 引數啟動 Node.js,後跟要除錯的指令碼的路徑。

node debug test.js

將啟動一個指示偵錯程式已成功啟動的提示。

要在指定位置應用斷點,請在原始碼中呼叫偵錯程式,如下面的程式碼所示。

// myscript.js 
x = 5; 
setTimeout(() => { 
   debugger; 
   console.log('world'); 
}, 1000); 
console.log('hello'); 

以下是一組可以使用 Node 的單步執行命令。

序號 單步執行命令和說明
1

cont,c

繼續

2

next,n

下一頁

3

step,s

單步進入

4

out,o

單步跳出

5

pause

暫停程式碼。類似於開發者工具中的暫停

Node 的所有除錯命令列表可以在此處找到 − https://nodejs.org/api/debugger.html.

Visual Studio Code 和除錯

Visual Studio Code 的關鍵特性之一就是其強大的內建 Node.js 執行時除錯支援。對於其他語言的程式碼除錯,它提供了偵錯程式擴充套件。

App Ts

偵錯程式提供了許多功能,允許我們啟動配置檔案,應用/刪除/停用和啟用斷點、變數或啟用資料檢查等。

使用 VS Code 進行除錯的詳細指南可以在此處找到 − https://vscode.com.tw/docs/editor/debugging

ES6 - 圖片地圖

您可以使用 JavaScript 建立客戶端影像對映。客戶端影像對映透過 <img /> 標籤的 usemap 屬性啟用,並由特殊的 <map> 和 <area> 擴充套件標籤定義。

構成地圖的影像像往常一樣使用 <img /> 元素插入到頁面中,只是它帶有一個額外的屬性 usemap。usemap 屬性的值是 <map> 元素的 name 屬性的值,前面帶有井號或磅字元。

<map> 元素實際上建立影像的地圖,通常緊跟在 <img /> 元素之後。它充當 <area /> 元素的容器,這些元素實際上定義了可點選的熱點。<map> 元素只有一個屬性,即 name 屬性,它是標識地圖的名稱。這就是 <img /> 元素知道使用哪個 <map> 元素的方式。

<area> 元素指定定義每個可點選熱點邊界的形狀和座標。

以下程式碼將影像對映和 JavaScript 結合起來,當滑鼠移動到影像的不同部分時,在文字框中顯示訊息。

<html> 
   <head> 
      <title>Using JavaScript Image Map</title>
      
      <script type="text/javascript"> 
         <!--  
            function showTutorial(name) {  
               document.myform.stage.value = name  
            }  
            //
         --> 
      </script> 
   </head> 

   <body> 
      <form name = "myform"> 
         <input type = "text" name = "stage" size = "20" /> 
      </form> 
      
      <!-- Create  Mappings --> 
      <img src = "//images/usemap.gif" alt = "HTML Map" 
         border = "0" usemap = "#tutorials"/> 
      <map name = "tutorials"> 
         <area shape = "poly" 
            coords = "74,0,113,29,98,72,52,72,38,27" 
            href = "/perl/index.htm" alt = "Perl Tutorial" 
            target = "_self" 
            onMouseOver = "showTutorial('perl')" 
            onMouseOut = "showTutorial('')"/>
         <area shape = "rect"   
            coords = "22,83,126,125"  
            href = "/html/index.htm" alt = "HTML Tutorial" target = "_self"   
            onMouseOver = "showTutorial('html')"         
            onMouseOut = "showTutorial('')"/>  
         <area shape = "circle"  coords = "73,168,32"  
            href = "/php/index.htm" alt = "PHP Tutorial" target = "_self"   
            onMouseOver = "showTutorial('php')"       
            onMouseOut = "showTutorial('')"/> 
      </map> 
   </body>
   
</html>

成功執行上述程式碼後將顯示以下輸出。您可以將滑鼠游標放在影像物件上來感受地圖的概念。

image map

ES6 - 瀏覽器相容性

瞭解不同瀏覽器之間的差異以按照預期的方式處理每個瀏覽器非常重要。因此,瞭解您的網頁正在執行的瀏覽器非常重要。要獲取有關網頁當前正在執行的瀏覽器的資訊,請使用內建的 navigator 物件。

Navigator 屬性

您可以在網頁中使用多個與 Navigator 相關的屬性。以下是名稱及其說明的列表。

序號 屬性 & 描述
1

appCodeName

此屬性是一個字串,包含瀏覽器的程式碼名稱,Netscape 用於 Netscape,Microsoft Internet Explorer 用於 Internet Explorer。

2

appVersion

此屬性是一個字串,包含瀏覽器的版本以及其他有用資訊,例如其語言和相容性。

3

language

此屬性包含瀏覽器使用的語言的兩位字母縮寫。僅限 Netscape。

4

mimTypes[]

此屬性是一個數組,包含客戶端支援的所有 MIME 型別。僅限 Netscape。

5

platform[]

此屬性是一個字串,包含為其編譯瀏覽器的平臺。“Win32”用於 32 位 Windows 作業系統。

6

plugins[]

此屬性是一個數組,包含已安裝在客戶端上的所有外掛。僅限 Netscape。

7

userAgent[]

此屬性是一個字串,包含瀏覽器的程式碼名稱和版本。此值將傳送到源伺服器以識別客戶端。

Navigator 方法

有幾種特定於 Navigator 的方法。以下是它們的名稱和說明的列表。

序號 方法和說明
1

javaEnabled()

此方法確定 JavaScript 是否在客戶端啟用。如果啟用了 JavaScript,則此方法返回 true;否則,返回 false。

2

plugings.refresh

此方法使新安裝的外掛可用,並使用所有新的外掛名稱填充 plugins 陣列。僅限 Netscape

3

preference(name,value)

此方法允許簽名指令碼獲取和設定一些 Netscape 首選項。如果省略第二個引數,則此方法將返回指定首選項的值;否則,它將設定該值。僅限 Netscape

4

taintEnabled()

如果啟用了資料汙染,此方法返回 true;否則返回 false

瀏覽器檢測

以下 JavaScript 程式碼可用於找出瀏覽器的名稱,然後相應地向用戶提供 HTML 頁面。

<html> 
   <head> 
      <title>Browser Detection Example</title> 
   </head> 

   <body> 
      <script type = "text/javascript"> 
         <!--  
            var userAgent   = navigator.userAgent;  
            var opera       = (userAgent.indexOf('Opera') 
            ! = -1); var ie          = (userAgent.indexOf('MSIE') 
            != -1); var gecko        = (userAgent.indexOf('Gecko') 
            ! = -1); var netscape    = (userAgent.indexOf('Mozilla') 
            ! = -1); var version     = navigator.appVersion;  

            if (opera) {  
               document.write("Opera based browser");    
               // Keep your opera specific URL here.  
            } else if (gecko) {
               document.write("Mozilla based browser");   
               // Keep your gecko specific URL here.  
            } else if (ie) {   
               document.write("IE based browser");    
               // Keep your IE specific URL here.  
            } else if (netscape) {  
               document.write("Netscape based browser");    
               // Keep your Netscape specific URL here.  
            } else {  
               document.write("Unknown browser");  
            }   
            // You can include version to along with any above condition. 
            document.write("<br /> Browser version info : " + version );  
            //
         --> 
      </script> 
   </body> 
   
</html>

執行上述程式碼後,將顯示以下輸出。

Mozilla based browser  
Browser version info : 5.0 

(Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36

ES7 - 新特性

本章介紹 ES7 的新特性。

指數運算子

ES7 引入了一種新的數學運算子,稱為指數運算子。此運算子類似於使用 Math.pow() 方法。指數運算子由雙星號 ** 表示。此運算子只能與數值一起使用。使用指數運算子的語法如下所示 −

語法

指數運算子的語法如下所示 −

base_value ** exponent_value

示例

以下示例使用 Math.pow() 方法和 指數運算子計算數字的指數。

<script>
   let base = 2
   let exponent = 3
   console.log('using Math.pow()',Math.pow(base,exponent))
   console.log('using exponentiation operator',base**exponent)
</script>

上述程式碼片段的輸出如下所示 −

using Math.pow() 8
using exponentiation operator 8

Array Includes

ES7 中引入的 Array.includes() 方法有助於檢查陣列中是否存在元素。在 ES7 之前,可以使用 Array 類的 indexof() 方法來驗證陣列中是否存在值。如果找到資料,indexof() 返回陣列中元素第一次出現的索引,否則如果資料不存在,則返回 -1。

Array.includes() 方法接受一個引數,檢查作為引數傳遞的值是否存在於陣列中。如果找到該值,此方法返回 true,否則如果該值不存在,則返回 false。使用 Array.includes() 方法的語法如下所示 −

語法

Array.includes(value)

Array.includes(value,start_index)

第二種語法檢查值是否存在於指定的索引中。

示例

以下示例宣告一個數組 marks 並使用 Array.includes() 方法來驗證陣列中是否存在值。

<script>
   let marks = [50,60,70,80]
   //check if 50 is included in array
   if(marks.includes(50)){
      console.log('found element in array')
   }else{
      console.log('could not find element')
   }

   // check if 50 is found from index 1
   if(marks.includes(50,1)){ //search from index 1
      console.log('found element in array')
   }else{
      console.log('could not find element')
   }

   //check Not a Number(NaN) in an array
   console.log([NaN].includes(NaN))

   //create an object array
   let user1 = {name:'kannan'},
   user2 = {name:'varun'},
   user3={name:'prijin'}
   let users = [user1,user2]

   //check object is available in array
   console.log(users.includes(user1))
   console.log(users.includes(user3))
</script>

上述程式碼的輸出將如下所示:

found element in array
could not find element
true
true
false

ES8 - 新特性

本章重點介紹 ES8 的新特性。

填充字串

ES8 引入了兩個字串處理函式來填充字串。這些函式可用於在字串值的開頭和結尾新增空格或任何所需的字元集。

String.padStart()

此函式使用給定的輸入字串從開頭重複填充當前字串,直到當前字串達到給定的長度。padStart() 函式的語法如下所示 −

語法

string_value.padStart(targetLength [, padString])

padStart() 函式接受兩個引數,如下所示 −

  • targetLength − 一個數值,表示填充後字串的目標長度。如果此引數的值小於或等於字串的現有長度,則按原樣返回字串值。

  • padString − 這是一個可選引數。此引數指定應使用哪些字元來填充字串。如果未將任何值傳遞給此引數,則字串值將用空格填充。

示例

以下示例宣告一個字串變數 product_cost。該變數將從左側用零填充,直到字串的總長度為七。該示例還說明了如果未將任何值傳遞給第二個引數,padStart() 函式的行為。

<script>

   //pad the String with 0
   let product_cost = '1699'.padStart(7,0)
   console.log(product_cost)
   console.log(product_cost.length)

   //pad the String with blank spaces
   let product_cost1 = '1699'.padStart(7)
   console.log(product_cost1)
   console.log(product_cost1.length)
</script>

上述程式碼的輸出將如下所示:

0001699
7
1699
7

String.padEnd()

此函式使用給定的輸入字串從結尾重複填充當前字串,直到當前字串達到指定的長度。

padEnd() 函式的語法如下所示 −

語法

string_value.padEnd(targetLength [, padString])

padEnd() 函式接受兩個引數 −

  • targetLength − 一個數值,表示填充後字串的目標長度。如果此引數的值小於或等於字串的現有長度,則按原樣返回字串值。

  • padString − 這是一個可選引數。此引數指定應使用哪些字元來填充字串。如果未將任何值傳遞給此引數,則字串值將用空格填充。

示例

以下示例宣告一個字串變數 product_cost。該變數將從右側用零填充,直到字串的總長度為七。該示例還說明了如果未將任何值傳遞給第二個引數,padStart() 函式的行為。

<script>

   //pad the string with x
   let product_cost = '1699'.padEnd(7,'x')
   console.log(product_cost)
   console.log(product_cost.length)
   
   //pad the string with spaces
   let product_cost1 = '1699'.padEnd(7)
   console.log(product_cost1)
   console.log(product_cost1.length)
</script>

上述程式碼的輸出如下所示:

1699xxx
7
1699
7

尾隨逗號

尾隨逗號只是列表中最後一項後的逗號。尾隨逗號也稱為最終逗號。

尾隨逗號和陣列

使用 Array.prototype.forEach 迴圈時,將跳過陣列中的尾隨逗號。

示例

以下示例使用 foreach 迴圈迭代帶有尾隨逗號的陣列。

<script>

   let marks = [100,90,80,,]
   console.log(marks.length)
   console.log(marks)
   marks.forEach(function(e){ //ignores empty value in array
      console.log(e)
   })
</script>

上述程式碼的輸出將如下所示:

4
[100, 90, 80, empty]
100
90
80

尾隨逗號和函式呼叫

在定義或呼叫函式時,作為引數傳遞的尾隨逗號將被 JavaScript 執行時引擎忽略。但是,有兩個例外 −

  • 僅包含逗號的函式定義或呼叫將導致 SyntaxError。例如,以下程式碼段將引發錯誤 −

function test(,){} // SyntaxError: missing formal parameter
(,)=>{}; //SyntaxError: expected expression, got ','
test(,) //SyntaxError: expected expression, got ','
  • 尾隨逗號不能與 rest 引數一起使用。

function test(...arg1,){} // SyntaxError: parameter after rest parameter
(...arg1,)=>{} // SyntaxError: expected closing parenthesis, got ','

示例

以下示例宣告一個在引數列表中帶有尾隨逗號的函式。

<script>

   function sumOfMarks(marks,){ // trailing commas are ignored
      let sum=0;
      marks.forEach(function(e){
         sum+=e;
      })
      return sum;
   }

   console.log(sumOfMarks([10,20,30]))
   console.log(sumOfMarks([1,2,3],))// trailing comma is ignored
</script>

上述程式碼的輸出如下所示 −

60
6

Object:entries() 和 values()

ES8 向內建 Object 型別引入了以下新方法 −

  • Object.entries − Object.entries() 方法可用於訪問物件的全部屬性。

  • Object.values() − Object.values() 方法可用於訪問物件所有屬性的值。

  • Object.getOwnPropertyDescriptors() − 此方法返回一個物件,其中包含物件的全部自有屬性描述符。如果物件沒有任何屬性,則可能會返回一個空物件。

示例

<script>
   const student ={
      firstName:'Kannan',
      lastName:'Sudhakaran'
   }
   console.log(Object.entries(student))
   console.log(Object.values(student))
</script>

上述程式碼的輸出如下:

[
["firstName", "Kannan"],
["lastName", "Sudhakaran"],
]
["Kannan", "Sudhakaran"]

示例

<script>
   const marks = [10,20,30,40]
   console.log(Object.entries(marks))
   console.log(Object.values(marks))
</script>

上述程式碼的輸出將如下所示:

["0", 10],
["1", 20],
["2", 30],
["3", 40]
]
[10, 20, 30, 40]

示例

<script>
   const student = {
      firstName : 'Mohtashim',
      lastName: 'Mohammad',
      get fullName(){
         return this.firstName + ':'+ this.lastName
      }
   }
   console.log(Object.getOwnPropertyDescriptors(student))
</script>

上述程式碼的輸出如下所示:

{firstName: {value: "Mohtashim", writable: true, enumerable: true, configurable: true}
fullName: {get: ƒ, set: undefined, enumerable: true, configurable: true}
lastName: {value: "Mohammad", writable: true, enumerable: true, configurable: true}
}

Async 和 Await

Async/Await 是 ES8 中一項非常重要的特性。它是 JavaScript 中 Promise 的語法糖。await 關鍵字與 promise 一起使用。此關鍵字可用於暫停函式的執行,直到 promise 完成為止。如果 promise 已解決,則 await 關鍵字返回 promise 的值,而如果 promise 已拒絕,則丟擲錯誤。await 函式只能在標記為 async 的函式內使用。使用 async 關鍵字宣告的函式始終返回一個 promise。

語法

帶有 await 的 async 函式的語法如下所示 −

async function function_name(){
   let result_of_functionCall = await longRunningMethod();
}
//invoking async function

function_name().then(()=>{})
   .catch(()=>{})

考慮一個示例,該示例具有一個非同步函式,該函式需要兩秒鐘才能執行並返回一個字串值。該函式可以透過兩種方式呼叫,如下所示

  • 使用 promise.then()
  • 使用 aync/await。

以下程式碼顯示了使用傳統的 ES6 語法 - promise.then() 呼叫非同步函式

<script>
   function fnTimeConsumingWork(){
      return new Promise((resolve,reject)=>{
         setTimeout(() => {
            resolve('response is:2 seconds have passed')
         }, 2000);
      })
   }

   fnTimeConsumingWork().then(resp=>{
      console.log(resp)
   })
   console.log('end of script')
</script>

上述程式碼的輸出如下:

end of script
response is:2 seconds have passed

以下程式碼顯示了使用 ES8 語法 - async/await 呼叫非同步函式的更清晰的方法

<script>
   function fnTimeConsumingWork(){
      return new Promise((resolve,reject)=>{
         setTimeout(() => {
            resolve('response is:2 seconds have passed')
         }, 2000);
      })
   }
   async function my_AsyncFunc(){
      console.log('inside my_AsyncFunc')
      const response = await fnTimeConsumingWork();// clean and readable
      console.log(response)
   }
   my_AsyncFunc();
   console.log("end of script")
</script>

上述程式碼的輸出如下所示:

inside my_AsyncFunc
end of script
response is:2 seconds have passed

使用 Async/await 進行 Promise 鏈式呼叫

以下示例使用 async/await 語法實現 Promise 鏈式呼叫。

在此示例中,add_positivenos_async() 函式非同步新增兩個數字,如果傳遞負值則拒絕。當前非同步函式呼叫的結果將作為引數傳遞給後續的函式呼叫。

<script>
   function add_positivenos_async(n1, n2) {
      let p = new Promise(function (resolve, reject) {
         if (n1 >= 0 && n2 >= 0) {
            //do some complex time consuming work
            resolve(n1 + n2)
         } else
            reject('NOT_Postive_Number_Passed')
      })
      return p;
   }
   async function addInSequence() {
      let r1 = await add_positivenos_async(10, 20)
      console.log("first result", r1);
      let r2 = await add_positivenos_async(r1, r1);
      console.log("second result", r2)
      let r3 = await add_positivenos_async(r2, r2);
      console.log("third result", r3)
      return "Done Sequence"
   }
   addInSequence().then((r)=>console.log("Async :",r));
   console.log('end')
</script>

上述程式碼的輸出將如下所示 −

end
first result 30
second result 60
third result 120
Async : Done Sequence

ES9 - 新特性

在這裡,我們將學習 ES9 的新特性。讓我們從瞭解非同步生成器開始。

非同步生成器和迭代

可以使用 async 關鍵字使非同步生成器變為非同步。定義非同步生成器的 語法如下所示 −

async function* generator_name() {
   //statements
}

示例

以下示例顯示了一個非同步生成器,它在每次呼叫生成器的 next() 方法時返回 Promise。

<script>
   async function* load(){
      yield await Promise.resolve(1);
      yield await Promise.resolve(2);
      yield await Promise.resolve(3);
   }
   
   let l = load();
   l.next().then(r=>console.log(r))
   l.next().then(r=>console.log(r))
   l.next().then(r=>console.log(r))
   l.next().then(r=>console.log(r))
</script>

上述程式碼的輸出如下:

{value: 1, done: false}
{value: 2, done: false}
{value: 3, done: false}
{value: undefined, done: true}

for await of 迴圈

非同步迭代器不能使用傳統的 for..of 迴圈語法進行迭代,因為它們返回 promise。ES9 引入了 for await of 迴圈來支援 非同步迭代

for await of 迴圈的語法如下所示:

  • 每次迭代,一個不同屬性的值都會賦值給變數,並且可以使用 const、let 或 var 宣告變數。

  • iterable − 要迭代其可迭代屬性的物件。
for await (variable of iterable) {
   statement
}

示例

以下示例演示瞭如何使用 for await of 迴圈迭代非同步生成器。

<script>
   async function* load(){
      yield await Promise.resolve(1);
      yield await Promise.resolve(2);
      yield await Promise.resolve(3);
   }

   async function test(){
      for await (const val of load()){
         console.log(val)
      }
   }
   test();
   console.log('end of script')
</script>

上述程式碼的輸出將如下所示:

end of script
1
2
3

示例

以下示例使用 for await of 迴圈迭代陣列。

<script>
   async function fntest(){
      for await (const val of [10,20,30,40]){
         console.log(val)
      }
   }
   fntest();
   console.log('end of script')
</script>

上述程式碼的輸出如下:

end of script
10
20
30
40

剩餘/展開屬性

ES9 支援在物件中使用剩餘和展開運算子。

示例:物件和剩餘運算子

以下示例演示瞭如何在物件中使用剩餘運算子。student 物件的 age 屬性的值被複制到 age 變數中,而其餘屬性的值使用剩餘語法 `...` 複製到 other 變數中。

<script>
   const student = {
      age:10,
      height:5,
      weight:50
   }
   const {age,...other} = student;
   console.log(age)
   console.log(other)
</script>

上述程式碼的輸出將如下所示:

10
{height: 5, weight: 50}

示例:物件和展開運算子

展開運算子可以用於組合多個物件或克隆物件。以下示例對此進行了演示。

<script>
   //spread operator
   const obj1 = {a:10,b:20}
   const obj2={c:30}
   //clone obj1
   const clone_obj={...obj1}
   //combine obj1 and obj2
   const obj3 = {...obj1,...obj2}
   console.log(clone_obj)
   console.log(obj3)
</script>

上述程式碼的輸出將如下所示:

{a: 10, b: 20}
{a: 10, b: 20, c: 30}

Promise: finally()

無論 Promise 的結果如何,finally() 都會在 Promise 完成時執行。此函式返回一個 Promise。它可以用於避免在 Promise 的 then()catch() 處理程式中重複程式碼。

語法

以下是 finally() 函式的語法。

promise.finally(function() {
});
promise.finally(()=> {
});

示例

以下示例聲明瞭一個非同步函式,該函式在延遲 3 秒後返回正數的平方。如果傳遞負數,則該函式會丟擲錯誤。無論 Promise 被拒絕還是已解決,finally 塊中的語句都會執行。

<script>
   let asyncSquareFn = function(n1){
      return new Promise((resolve,reject)=>{
         setTimeout(()=>{
            if(n1>=0){
               resolve(n1*n1)
            }
            else reject('NOT_POSITIVE_NO')
         },3000)
      })
   }
   console.log('Start')

   asyncSquareFn(10)//modify to add -10
   .then(result=>{
      console.log("result is",result)
   }).catch(error=>console.log(error))
   .finally(() =>{
      console.log("inside finally")
      console.log("executes all the time")
   })

   console.log("End");
</script>

以上程式碼的輸出將如下所示

Start
End
//after 3 seconds
result is 100
inside finally
executes all the time

模板字面量修訂

從 ES7 開始,標記模板符合以下轉義序列的規則:

  • Unicode 轉義序列使用 "\u" 表示,例如 \u2764\uFE0F

  • Unicode 程式碼點轉義序列使用 "\u{}" 表示,例如 \u{2F}

  • 十六進位制轉義序列使用 "\x" 表示,例如 \xA8

  • 八進位制字面量轉義序列使用 "" 表示,後跟一個或多個數字,例如 \125

在 ES2016 及更早版本中,如果帶標記函式使用無效的轉義序列,則會丟擲語法錯誤,如下所示:

//tagged function with an invalid unicode sequence
myTagFn`\unicode1`
// SyntaxError: malformed Unicode character escape sequence

但是,與早期版本不同,ES9 將無效的 Unicode 序列解析為 undefined,並且不會丟擲錯誤。以下示例對此進行了演示:

<script>
   function myTagFn(str) {
      return { "parsed": str[0] }
   }
   let result1 =myTagFn`\unicode1` //invalid unicode character
   console.log(result1)
   let result2 =myTagFn`\u2764\uFE0F`//valid unicode
   console.log(result2)
</script>

上述程式碼的輸出將如下所示:

{parsed: undefined}
{parsed: "❤️"}

原始字串

ES9 引入了一個特殊屬性 raw,它在標記函式的第一個引數中可用。此屬性允許您訪問原始字串,就像輸入時一樣,無需處理轉義序列。

示例

<script>
   function myTagFn(str) {
      return { "Parsed": str[0], "Raw": str.raw[0] }
   }
   let result1 =myTagFn`\unicode`
   console.log(result1)

   let result2 =myTagFn`\u2764\uFE0F`
   console.log(result2)
</script>

上述程式碼的輸出如下:

{Parsed: undefined, Raw: "\unicode"}
{Parsed: "❤️", Raw: "\u2764\uFE0F"}

正則表示式特性

在正則表示式中,點運算子或句點用於匹配單個字元。. 點運算子跳過換行符,例如 \n、\r,如下例所示:

console.log(/Tutorials.Point/.test('Tutorials_Point')); //true
console.log(/Tutorials.Point/.test('Tutorials\nPoint')); //false
console.log(/Tutorials.Point/.test('Tutorials\rPoint')); //false

正則表示式模式表示為 / regular_expression /。test() 方法採用字串引數並搜尋正則表示式模式。在上面的示例中,test() 方法搜尋以 Tutorials 開頭、後跟任何單個字元並以 Point 結尾的模式。如果我們在 Tutorials 和 Point 之間的輸入字串中使用 \n\r,則 test() 方法將返回 false。

true
false
false

ES9 引入了一個新的標誌 - DotAllFlag (\s),可與 Regex 一起使用以匹配行終止符和表情符號。以下示例對此進行了演示:

console.log(/Tutorials.Point/s.test('Tutorials\nPoint'));
console.log(/Tutorials.Point/s.test('Tutorials\rPoint'));

上述程式碼的輸出如下所示:

true
true

命名捕獲組

在 ES9 之前,捕獲組是透過索引訪問的。ES9 允許我們為捕獲組分配名稱。其語法如下所示:

(?<Name1>pattern1)

示例

const birthDatePattern = /(?<myYear>[0-9]{4})-(?<myMonth>[0-9]{2})/;
const birthDate = birthDatePattern.exec('1999-04');
console.log(birthDate.groups.myYear);
console.log(birthDate.groups.myMonth);

上述程式碼的輸出如下所示:

1999
04
廣告