ES6 - 快速指南

ES6 - 概述

ECMAScript (ES) 是由 ECMAScript International 标准化的脚本语言规范。应用程序使用它来启用客户端脚本。该规范受到 Self、Perl、Python、Java 等编程语言的影响。JavaScript、Jscript 和 ActionScript 等语言受此规范的约束。

本教程向您介绍 JavaScript 中的 ES6 实现。

JavaScript

JavaScript 由 Netscape Communications Corporation 的开发人员 Brendan Eich 于 1995 年开发。JavaScript 最初名为 Mocha,曾短暂命名为 LiveScript,后来正式更名为 JavaScript。它是一种由浏览器(即客户端)执行的脚本语言。它与 HTML 结合使用,以开发响应式网页。

此处讨论的 ECMA Script6 实现涵盖以下新功能 −

  • 支持常量
  • 块范围
  • 箭头函数
  • 扩展参数处理
  • 模板文字
  • 扩展文字
  • 增强对象属性
  • 解构赋值
  • 模块
  • 迭代器
  • 生成器
  • 集合
  • 各种类的内置新方法
  • 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 5.1 版于 2011 年发布,略有改动以满足 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、Notepad++、Emacs、vim 或 vi 等。使用的编辑器可能因操作系统而异。源文件通常以 extension.js 命名

安装 Node.js

Node.js 是一个用于服务器端 JavaScript 的开源、跨平台运行时环境。运行 JavaScript 需要 Node.js,而无需浏览器支持。它使用 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 并单击安装按钮下载最新软件包。

最新软件包

按照安装向导从 .dmg 安装软件包,安装向导将安装 nodenpm。 npm 是 Node 包管理器,它有助于安装 Node.js 的其他包。

安装 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://code.visualstudio.com 上获取。

在 Windows 上安装

下载适用于 Windows 的 Visual Studio Code。

适用于 Windows 的 Visual Studio Code

双击 VSCodeSetup.exe VSCodeSetup 以启动安装过程。这只需要一分钟。

安装向导

以下是 IDE 的屏幕截图。

IDE 屏幕截图

您可以通过右键单击文件并在命令提示符中打开直接遍历到文件的路径。同样,在资源管理器中显示选项会在文件资源管理器中显示该文件。

在资源管理器中显示

在 Mac OS X 上安装

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

在 Linux 上安装

Visual Studio Code 的 Linux 特定安装指南可在 https://code.visualstudio.com/Docs/editor/setup. 找到

Brackets

Brackets 是由 Adob​​e 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 支持以下类型的注释 −

  • 单行注释 (//) − // 和行尾之间的任何文本均视为注释。

  • 多行注释 (/* */) −这些注释可能跨越多行。

示例

//这是单行注释
/* 这是
多行注释
*/

您的第一个 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 团队认为它们不稳定。

  • 正在进行中 − 这些功能应仅用于测试目的。

第一类功能完全受支持,并且由 node 默认启用。阶段性功能需要运行时 - - harmony 标志才能执行。

可在此处找到 Node.js 组件特定 CLI 标志列表 − https://nodejs.org/api/cli.html

严格模式

ECMAScript 规范第五版引入了严格模式。严格模式对 JavaScript 施加了一层约束。它对正常的 JavaScript 语义进行了几项更改。

通过包含以下 −,可以将代码转换为在严格模式下工作

// 整个脚本严格模式语法
"use strict";
v = "Hi! I'm a strict mode script!"; // 错误:变量 v 未声明

在上面的代码片段中,整个代码作为 JavaScript 的受限变体运行。

JavaScript 还允许将严格模式限制在块的范围内,就像限制在函数的范围内一样。如下所示 −

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

在上面的代码片段中,函数之外的任何代码都将在非严格模式下运行。函数内的所有语句都将在严格模式下执行。

ES6 和提升

JavaScript 引擎默认将声明移至顶部。此功能称为提升。此功能适用于变量和函数。提升允许 JavaScript 在声明组件之前使用它。但是,提升的概念不适用于在严格模式下运行的脚本。

变量提升和函数提升将在后续章节中解释。

ES6 - 变量

根据定义,变量是存储值的"内存中的命名空间"。换句话说,它充当程序中值的容器。变量名称为标识符。以下是标识符的命名规则 −

  • 标识符不能是关键字。

  • 标识符可以包含字母和数字。

  • 标识符不能包含空格和特殊字符,下划线 (_) 和美元 ($) 符号除外。

  • 变量名不能以数字开头。

类型语法

变量在使用前必须声明。ES5 语法使用 var 关键字来实现相同的功能。声明变量的 ES5 语法如下。

//使用 var 关键字声明
var variable_name

ES6 引入了以下变量声明语法 −

  • 使用 let。
  • 使用 const。

变量初始化是指将值存储在变量中的过程。变量可以在声明时初始化,也可以在稍后的时间点初始化。

声明和初始化变量的传统 ES5 类型语法如下 −

//使用 var 关键字声明
var variable_name = value

示例:使用变量

var name = "Tom"
console.log("变量中的值为:"+name)

上述示例声明了一个变量并打印其值。

执行成功后将显示以下输出。

变量中的值为 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 时,会返回全局作用域实例。

成功执行后将显示以下输出。

test() 外 num 的值 10
test() 内 num 的值 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

Example: let v/s 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 // 数字类型
    console.log(typeof balance)
    let balance = {message:"hello"} // 将数字更改为对象类型
    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++){
      //for循环括号内,计数值从1开始
      console.log("count value inside loop is ",count);
   }
   //在 for 循环括号外,计数值为 100
   console.log("count value after loop is",count);

   if(count == 100){
      //如果括号内,计数值为 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 // 将导致错误!!

上述代码将返回错误,因为常量不能重新赋值。常量变量是不可变的。

常量是不可变的

与使用 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); // 在声明之前使用变量
    var company = "TutorialsPoint"; // 在此处声明和初始化
    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 在 for 循环中使用 var 关键字声明。变量 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
++ 递增

将变量的值增加一。

a++ 为 11
-- 递减

将变量的值减一。

a-- 为 9

关系运算符

关系运算符测试或定义两个实体之间的关系类型。关系运算符返回布尔值,即 true/false。

假设 A 的值为 10,B 的值为 20。

显示示例

运算符 描述 示例
> 大于 (A > B) 为假
< 小于 (A < B) 为真
>= 大于或等于 (A >= B) 为假
<= 小于或等于 (A <= B) 为真
== 相等 (A == B) 为假
!= 不等于 (A!= B) 为真

逻辑运算符

逻辑运算符用于组合两个或多个条件。逻辑运算符也返回布尔值。假设变量 A 的值为 10,B 的值为 20。

显示示例

运算符 描述 示例
&&

仅当所有指定表达式都返回 true 时,运算符才返回 true。

(A > 10 && B > 10) 为 False
||

如果指定的表达式中至少有一个返回 true,则运算符返回 true。

(A > 10 || B > 10) 为 True
! 不是

运算符返回表达式结果的逆。例如:!(7>5) 返回 false。

!(A > 10) 为 True

按位运算符

JavaScript 支持以下按位运算符。下表总结了 JavaScript 的按位运算符。

显示示例

运算符 用法 说明
按位与 a & b 在两个操作数的相应位均为 1 的每个位位置上返回 1
按位或 a | b 返回每个位位置上的 1,其中任一或两个操作数的对应位为 1
按位异或 a^b 返回每个位位置上的 1,其中任一但不是两个操作数的对应位为 1
按位非 ~ a 反转其操作数的位
左移 a << b 将二进制表示中的 a 向左移动 b (< 32) 位,从右侧移入零
符号传播右移 a >> b 将二进制表示中的 a 向右移动 b (< 32) 位,丢弃移出的位
零填充右移 a >>> b 将二进制表示中的 a 向右移动 b (< 32) 位,丢弃移出的位,并从左侧移入零

赋值运算符

下表总结了赋值运算符。

显示示例

Sr.No 运算符和说明
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("x 的值: ",x); //输出 4
console.log("y 的值: ",y); //输出 -4

成功执行上述程序后,将显示以下输出。

x 的值:4
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 "number"
String "string"
Boolean "boolean"
Object "object"

以下示例代码将数字显示为输出。

var num = 12
console.log(typeof num); //输出: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>
   //使用扩展运算符复制数组
   let source_arr = [10,20,30]
   let dest_arr = [...source_arr]
   console.log(dest_arr)
	
   //连接两个数组
   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>
   //复制对象
   let student1 ={firstName:'Mohtashim',company:'TutorialsPoint'}
   let student2 ={...student1}
   console.log(student2)
   //连接对象
   let student3 = {lastName:'Mohammad'}
   let student4 = {...student1,...student3}
   console.log(student4)
</script>

上述代码的输出如下所示 −

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

ES6 - 决策

条件/决策构造在执行指令之前评估条件。

决策

JavaScript 中的条件构造在下表中分类。

Sr.No 语句 &描述
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
}   
Sr.No 明确循环 &描述
1 "for"循环

for 循环按指定次数执行代码块。

2 for…in 循环

for…in 循环用于循环遍历对象的属性。

3 for…of循环

for…of 循环用于迭代可迭代对象,而不是对象文字。

无限循环

当循环中的迭代次数不确定或未知时,使用无限循环。

可以使用 − 实现无限循环

Sr.No 无限循环 &描述
1 while 循环

每次指定的条件计算结果为真时,while 循环都会执行指令。

2 do…while 循环

do…while 循环与 while 循环类似,不同之处在于 do...while 循环在第一次执行循环时不会计算条件。

循环控制语句

Sr.No 循环控制语句 &描述
1 break 语句

break 语句用于将控制权从构造中移出。

2 continue 语句

continue 语句跳过当前迭代中的后续语句并将控制权返回到循环的开头。

使用标签控制流程

标签只是一个标识符,后跟一个冒号 (:),应用于语句或代码块。标签可以与 breakcontinue 一起使用,以更精确地控制流程。

'continue''break' 语句与其标签名称之间不允许换行。此外,标签名称和相关循环之间不应有任何其他语句

Sr.No 标签 &描述
1 带 Break 的标签

标签可以与 break 和 continue 一起使用,以更精确地控制流程。

2 带 Continue 的标签

"continue"或"break"语句与其标签名称之间不允许换行。

ES6 - 函数

函数是可读、可维护和可重用的构建块代码。函数使用 function 关键字定义。以下是定义标准函数的语法。

function function_name() { 
   // 函数体
} 

要强制执行函数,必须调用该函数。这称为函数调用。以下是调用函数的语法。

function_name()

示例:简单函数定义

//定义一个函数
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,它接受两个参数 n1n2 并打印它们的和。调用函数时,参数值将传递给该函数。

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 中,如果未向函数传递任何值或函数未定义,则允许使用默认值初始化函数参数。以下代码说明了这一点。

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() 构造函数和 new 运算符动态定义函数。

以下是使用 Function() 构造函数和 new 运算符创建函数的语法。

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

Function() 构造函数需要任意数量的字符串参数。最后一个参数是函数的主体 - 它可以包含任意 JavaScript 语句,彼此之间用分号分隔。

Function() 构造函数不会传递任何为其创建的函数指定名称的参数。

示例 − 函数构造函数

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

在上面的例子中,Function() 构造函数用于定义一个匿名函数。该函数接受两个参数并返回它们的乘积。

成功执行上述代码后将显示以下输出。

乘积: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 函数有 3 个部分 −

  • 参数 −函数可以有参数。

  • 粗箭头符号/lambda 符号 (=>):也称为转到运算符。

  • 语句 − 表示函数的指令集。

提示 − 按照惯例,建议使用单个字母参数,以实现紧凑而精确的函数声明。

Lambda 表达式

它是一个指向一行代码的匿名函数表达式。以下是其语法。

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

示例 − Lambda 表达式

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

The Example declares a lambda expression function. The function returns the sum of 10 and the argument passed.

成功执行上述代码后将显示以下输出。

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() 不是函数
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 中的生成器,调用函数现在可以控制被调用函数的执行。生成器类似于常规函数,不同之处在于 −

  • 该函数可以在任何时候将控制权交还给调用者。

  • 调用生成器时,它不会立即运行。相反,您会得到一个迭代器。该函数会在您调用迭代器的下一个方法时运行。

生成器通过在 function 关键字后加上星号来表示;否则,它们的语法与常规函数相同。

以下示例说明了这一点。

"use strict" 
function* rainbow() { 
   // 星号标记这是一个生成器
   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() 产生"你的名字是什么"。生成器暂停。这是通过yield关键字完成的。

  • 调用it.next("Ethan")将值Ethan分配给变量name并产生"你最喜欢的运动是什么?"生成器再次暂停。

  • 调用it.next("Cricket")将值Cricket分配给变量sport并执行后续的返回语句。

因此,上述代码的输出将是 −

{ 
   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 秒后显示以下输出 −

在 TutorialsPoint 学习很有趣!!

箭头函数语法

ES6 引入了 箭头函数 的概念,以简化 匿名函数 的使用。箭头函数分为 3 个部分,如下所示 −

  • 参数 − 箭头函数可以有参数

  • 粗箭头符号 (=>) −它也被称为转到运算符

  • 语句 − 表示函数的指令集

提示 − 按照惯例,鼓励使用单个字母参数进行紧凑而精确的箭头函数声明。

语法

//指向单行代码的箭头函数
()=>some_expression

OR

//指向代码块的箭头函数
()=> { //一些语句 }`

//带参数的箭头函数
(param1,param2)=>{//一些语句}

示例:ES6 中的箭头函数

以下示例使用箭头函数定义了两个函数表达式 addisEven

<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>
   //构造函数
   function Student(rollno,firstName,lastName) {
      this.rollno = rollno;
      this.firstName = firstName;
      this.lastName = lastName;
      this.fullNameUsingAnonymous = function(){
         setTimeout(function(){
            //创建此的新实例,隐藏此的外部范围
            console.log(this.firstName+ " "+this.lastName)
         },2000)
      }
      this.fullNameUsingArrow = function(){
         setTimeout(()=>{
            //使用外部范围的这个实例
            console.log(this.firstName+ " "+this.lastName)
         },3000)
      }
   }
   const s1 = new Student(101,'Mohammad','Mohtashim')
   s1.fullNameUsingAnonymous();
   s1.fullNameUsingArrow();
</script>

当匿名函数与 setTimeout() 一起使用时,该函数将在 2000 毫秒后被调用。将创建一个新的 "this" 实例,它将遮蔽 Student 函数的实例。因此,this.firstNamethis.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 事件类型

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 script 文档离线时触发
onabort script 在中止事件上触发
onafterprint script 文档打印后触发
onbeforeonload script 文档加载前触发
onbeforeprint script 文档打印前触发
onblur script 窗口失去焦点时触发
oncanplay script 当媒体可以开始播放但可能必须停止缓冲时触发
oncanplaythrough script 当媒体可以播放到结尾而无需停止缓冲时触发
onchange script 当元素更改时触发
onclick script 在鼠标单击
oncontextmenu script 触发上下文菜单时触发
ondblclick script 鼠标双击时触发
ondrag script 拖动元素时触发
ondragend script 拖动结束时触发操作
ondragenter script 当元素被拖到有效的放置目标时触发
ondragleave script 当元素离开有效的放置目标时触发
ondragover script 当元素被拖到有效的放置目标上时触发
ondragstart script 在拖动操作开始时触发
ondrop script 在拖动元素被放下时触发
ondurationchange script 在媒体长度改变时触发
onemptied script 在媒体资源元素突然变空时触发
onended script 当媒体到达末尾时触发
onerror script 当发生错误时触发
onfocus script 当窗口获得焦点时触发
onformchange script 当表单更改时触发
onforminput script 当表单获得用户输入时触发
onhaschange script 当文档发生更改时触发
oninput script 当元素获得用户输入时触发
oninvalid script 当元素无效时触发
onkeydown script 按下某个键时触发
onkeypress script 按下并释放某个键时触发
onkeyup script 释放某个键时触发
onload script 文档加载时触发
onloadeddata script 媒体数据加载时触发
onloadedmetadata script 媒体元素的时长和其他媒体数据加载时触发
onloadstart script 浏览器开始加载媒体数据时触发
onmessage script 消息触发时触发
onmousedown script 鼠标按钮按下时触发
onmousemove script 鼠标指针移动时触发
onmouseout script 鼠标指针移出元素时触发
onmouseover script 鼠标指针移到元素上时触发
onmouseup script 鼠标按钮释放时触发
onmousewheel script 鼠标滚轮旋转时触发
onoffline script 文档离线时触发
ononline script 文档在线时触发
onpagehide script 窗口隐藏时触发
onpageshow script 当窗口可见时触发
onpause script 当媒体数据暂停时触发
onplay script 当媒体数据即将开始播放时触发
onplaying script 当媒体数据开始播放时触发
onpopstate script 窗口历史记录改变时触发
onprogress script 浏览器获取媒体数据时触发
onratechange script 媒体数据的播放速率改变时触发
onreadystatechange script 当就绪状态改变时触发
onredo script 当文档执行重做时触发
onresize script 当窗口调整大小时触发
onscroll script 当元素的滚动条正在滚动时触发
onseeked script 当媒体元素的搜索属性不再为真,且搜索已结束时触发
onseeking script 当媒体元素的搜索属性为真,且搜索已开始时触发
onselect script 选择元素时触发
onstalled script 获取媒体数据时出错时触发
onstorage script 文档加载时触发
onsubmit script 表单提交时触发
onsuspend script 浏览器已获取媒体数据但在获取整个媒体文件之前停止时触发
ontimeupdate script 媒体改变播放位置时触发
onundo script 当文档执行撤消时触发
onunload script 当用户离开文档时触发
onvolumechange script 当媒体改变音量时触发,当音量设置为"静音"时也触发
onwaiting script 当媒体停止播放但预计会恢复时触发

ES6 - Cookies

Web 浏览器和服务器使用 HTTP 协议进行通信。HTTP 是无状态协议,即它不会在客户端发出的多个请求中维护客户端的数据。客户端和服务器之间的完整请求-响应周期定义为 会话。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。您可以使用多个以逗号分隔的 key = value 对来设置多个 cookie。

读取 Cookie

读取 cookie 与写入 cookie 一样简单,因为 document.cookie 对象的值就是 cookie。因此,无论何时想要访问 cookie,都可以使用此字符串。document.cookie 字符串将保留一个以分号分隔的 name = value 对列表,其中 name 是 cookie 的名称,value 是其字符串值。

您可以使用字符串的 split() 函数将字符串分解为键和值,如以下示例所示。

示例

<html> 
   <head> 
      <script type = "text/javascript"> 
         function ReadCookie() {  
            var allcookies  =  document.cookie;  
            document.write ("All Cookies : " + allcookies ); 
         } 
         // 获取数组中的所有 cookie 对
         cookiearray = allcookies.split(';');  
         
         // 现在从该数组中取出键值对
         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>

成功执行上述代码后将显示以下输出。

删除 Cookie

ES6 - 页面重定向

重定向是一种将用户和搜索引擎发送到与他们最初请求的 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 中可用,因此您应避免在跨浏览器开发中使用它。

Following is the syntax for the same.

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 dialog box

确认对话框

确认对话框主要用于征求用户对任何选项的同意。它显示一个带有两个按钮的对话框:确定和取消。

如果用户单击确定按钮,窗口方法 confirm() 将返回 true。如果用户单击取消按钮,则 confirmed() 将返回 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> 

成功执行上述代码后将显示以下输出。

确认对话框

提示对话框

当您想要弹出文本框以获取用户输入时,提示对话框非常有用。因此,它使您能够与用户交互。用户需要填写字段,然后单击"确定"。

此对话框使用名为 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 dialog box

ES6 - void 关键字

void 是 JavaScript 中的一个重要关键字,可用作出现在其单个操作数之前的一元运算符,该操作数可以是任何类型。此运算符指定要评估的表达式而不返回值。该运算符评估给定的表达式,然后返回未定义。

以下是相同的语法。

void 表达式

void 和立即调用的函数表达式

使用立即调用的函数表达式时,可以使用 void 强制将函数关键字视为表达式而不是声明。

考虑以下示例 −

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

成功执行上述代码后将显示以下输出。

hello world

Void 和 JavaScript URI

JavaScript: URI 是 HTML 页面中常见的语法。浏览器评估 URI 并用返回的值替换页面内容。除非返回的值未定义,否则此操作为真。此运算符最常见的用途是在客户端 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 运算符返回未定义,因此页面上不会显示任何结果。

另一方面,单击第二个超链接时会显示一个警报对话框。

ES6 - 页面打印

很多时候,您希望在网页上放置一个按钮,以通过实际打印机打印该网页的内容。JavaScript 可帮助您使用 window 对象的打印函数实现此功能。

JavaScript 打印函数 window.print() 在执行时会打印当前网页。您可以直接使用 onclick 事件调用此函数,如下例所示。

示例

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

成功执行上述代码后将显示以下输出。

page printing

ES6 - 对象

JavaScript 支持扩展数据类型。JavaScript 对象是定义自定义数据类型的绝佳方式。

对象 是包含一组键值对的实例。与原始数据类型不同,对象可以表示多个或复杂的值,并且可以在其生命周期内发生变化。这些值可以是标量值或函数,甚至是其他对象的数组。

定义对象的语法变化将进一步讨论。

对象初始化器

与原始类型一样,对象具有文字语法:花括号v({and})。以下是定义对象的语法。

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 引擎会在包含范围中查找具有相同名称的变量。如果找到,则将该变量的值分配给属性。如果未找到,则抛出引用错误。

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"; //定义一个对象
myCar.model = "Mustang";
myCar.year = 1987;

console.log(myCar["make"]) //访问对象属性
console.log(myCar["model"]) 
console.log(myCar["year"])

成功执行上述代码后将显示以下输出。

Ford 
Mustang 
1987

未分配的对象属性是未定义的。

示例

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 − 使用新语法创建对象的实例。

var Object_name= new function_name()
//访问属性值

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 role = {
    type: "Admin", // 属性的默认值
    displayType : function() {
        // 将显示角色类型的方法
        console.log(this.type);
    }
}
// 创建名为 super_role 的新角色类型
var super_role = Object.create(roles);
super_role.displayType(); // 输出:Admin

// 创建名为 Guest 的新角色类型
var guest_role = Object.create(roles);
guest_role.type = "Guest";
guest_role.displayType(); // 输出: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 运算符删除属性。以下代码显示如何删除属性。

示例

// 创建一个新对象 myobj,它具有两个属性 a 和 b。
var myobj = new Object;
myobj.a = 5;
myobj.b = 12;

// 删除"a"属性
delete myobj.a;
console.log ("a" in myobj) // 得出"false"

成功执行上述代码后将显示以下输出。

false

该代码片段从对象中删除属性。该示例打印 false,因为 in 运算符未在对象中找到该属性。

比较对象

在 JavaScript 中,对象是引用类型。两个不同的对象永远不会相等,即使它们具有相同的属性。这是因为它们指向完全不同的内存地址。只有那些共享公共引用的对象才会在比较时产生 true。

示例 1 − 不同的对象引用

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

在上面的例子中,val1val2 是两个不同的对象,它们引用两个不同的内存地址。因此,在比较相等性时,运算符将返回 false。

示例 2 − 单个对象引用

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

console.log(val1 == val2) // 返回 true
console.log(val1 === val2) // 返回 true

在上面的例子中,val1 中的内容被分配给 val2,即 val1 中属性的引用与 val2 共享。由于对象现在共享对属性的引用,因此相等运算符将对引用两个不同内存地址的两个不同对象返回 true。因此,在比较相等性时,运算符将返回 false。

对象解构

术语解构是指分解实体的结构。JavaScript 中的解构赋值语法可以将数据从数组或对象提取到不同的变量中。以下示例说明了这一点。

示例 1

解构对象时,变量名称和对象属性名称必须匹配。

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

//解构为相同的属性名
   let {name,cgpa} = student
   console.log(name)
   console.log(cgpa)

//解构为不同的名称
   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
   }

   // 解构到已声明的变量
   let rollno;
   ({rollno} = student)
   console.log(rollno)

   // 为变量分配默认值

   let product ={ id:1001,price:2000} //折扣不是产品属性
   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 运算符
   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 属性

Sr.No 属性 &描述
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

表示无穷大的特殊值;溢出时返回

数字方法

Sr.No 方法 &描述
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 对象仅包含作为每个对象定义一部分的默认方法。

Sr.No 实例方法和说明
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);

布尔值属性

以下是布尔值对象的属性列表。

Sr.No 属性和说明
1 constructor

返回对创建该对象的布尔函数的引用。

2 prototype

prototype 属性允许您向对象添加属性和方法。

布尔方法

以下是布尔对象的方法列表及其说明。

Sr.No 方法 &描述
1 toSource()

返回包含布尔对象源的字符串;您可以使用此字符串创建一个等效对象。

2 toString()

根据对象的值返回"true"或"false"字符串。

3 valueOf()

返回布尔对象的原始值。

在以下部分中,我们将看几个例子来演示布尔方法。

ES6 - 字符串

String 对象允许您处理一系列字符;它使用许多辅助方法包装 JavaScript 的字符串原始数据类型。

由于 JavaScript 会自动在字符串原始类型和 String 对象之间进行转换,因此您可以在字符串原始类型上调用 String 对象的任何辅助方法。

使用以下语法创建 String 对象。

var val = new String(string);

字符串参数是经过正确编码的一系列字符。字符串。

字符串属性

以下是字符串对象的属性列表及其说明。

Sr.No 属性 &描述
1 构造函数

返回对创建对象的 String 函数的引用。

2 长度

返回字符串的长度。

3 原型

原型属性允许您添加对象的属性和方法。

字符串方法

以下是字符串对象中可用的方法及其说明的列表。

Sr.No 方法 &描述
1 charAt()

返回指定索引处的字符。

2 charCodeAt()

返回一个数字,表示给定索引处字符的 Unicode 值。

3 concat()

合并两个字符串的文本并返回一个新字符串。

4 indexOf()

返回调用字符串对象中第一次出现指定值的索引,如果未找到则返回 -1。

5 lastIndexOf()

返回调用字符串对象中最后一次出现指定值的索引,如果未找到则返回 -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 只是一块内存,您可以在其中存储一些数据。每个符号将指向不同的内存位置。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
Sr.No 属性和说明
1 Symbol.for(key)

使用给定的键在符号注册表中搜索现有符号,如果找到则返回。否则,将使用此键在全局符号注册表中创建一个新符号。

2 Symbol.keyFor(sym)

从全局符号注册表中检索给定符号的共享符号键。

符号和类

符号可以与类一起使用来定义类中的属性。优点是,如果属性是如下所示的符号,则只有知道符号名称才能在包外部访问该属性。因此,当符号用作属性时,数据被封装得更好。

示例

<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)
//仅当知道符号名称时才可以访问属性
console.log(bike[COLOR])
</script>

上述代码的输出将如下所示 −

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

ES6 - 新的字符串方法

以下是方法及其说明的列表。

Sr.No 方法和说明
1 String.prototype.startsWith(searchString, position = 0)

如果接收器以 searchString 开头,则返回 true;位置允许您指定要检查的字符串的开始位置。

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

如果接收器以 searchString 开头,则返回 true;位置允许您指定要检查的字符串的开始位置。

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 
 World` 
console.log(text)  

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

成功执行上述代码后将显示以下输出。

Hello 
World 
Hello 
 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; //声明
array_name = [val1,val2,valn..] //初始化
或
var array_name = [val1,val2…valn]

注意 − [] 对称为数组的维度。

例如,像 var numlist = [2,4,6,8] 这样的声明将创建一个数组,如下图所示。

初始化数组

访问数组元素

数组名称后跟下标用于引用数组元素。

以下是相同的语法。

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

数组对象

也可以使用数组对象创建数组。数组构造函数可以作为 − 传递

  • 表示数组大小的数值。

  • 逗号分隔值的列表。

以下示例使用此方法创建数组。

示例

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 

示例:数组构造函数接受逗号分隔的值

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

成功执行上述代码后将显示以下输出。

Mary 
Tom 
Jack 
Jill

数组方法

以下是数组对象的方法列表及其说明。

Sr.No 方法 &描述
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()

从数组中删除第一个元素并返回该元素切片。

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 是一个返回数组迭代器的函数,可用于循环遍历数组的键和值。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 支持以下有关数组的概念 −

Sr.No 概念与描述
1 多维数组

JavaScript 支持多维数组。多维数组的最简单形式是二维数组

2 将数组传递给函数

您可以通过指定数组的名称(不带索引)将指向数组的指针传递给函数。

3 从函数返回数组

允许函数返回数组。

数组解构

解构是指将数组或对象中的单个值提取到不同的变量中。考虑这样一种情况,其中需要将数组的值分配给单个变量。传统的执行方式如下 −

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

解构有助于以简洁的方式实现相同的目的。

语法

//解构数组
let [variable1,variable2]=[item1,item2]
//解构对象
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 运算符
    let locations=['Mumbai','Hyderabad','Chennai']
    let [l1,...otherValues] =locations
    console.log(l1)
    console.log(otherValues)
    //已声明的变量
    let name1,name2;
    [name1,name2] =names
    console.log(name1)
    console.log(name2)
    //交换
    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 语言内置的数据类型。日期对象使用 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 对象的属性列表及其说明。

Sr.No 属性 &描述
1 constructor

指定创建对象原型的函数

2 prototype

原型属性允许您向对象添加属性和方法

日期方法

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

Sr.No 方法 &描述
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()

返回日期对象的原始值

ES6 - 数学

数学对象为您提供以下属性和方法数学常数和函数。与其他全局对象不同,Math 不是构造函数。Math 的所有属性和方法都是静态的,可以通过使用 Math 作为对象来调用,而无需创建它。

数学属性

以下是所有数学属性及其说明的列表。

Sr.No 属性 &描述
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 的幂的便捷函数,如下表所示。

Sr.No 函数和说明
1 Math.pow(x, y)

返回 x 的 y 次方

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 以方便使用。

Sr.No Function &描述
1 Math.log(x)

x 的自然对数

2 Math.log10(x)

x 的以 10 为底的对数

3 Math.log2(x)

以 2 为底的 x 对数

4 Math.log1p(x)

1 + x 的自然对数

杂项代数函数

以下是杂项代数函数及其说明的列表。

Sr.No 函数与说明
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)

x 四舍五入到最接近的整数

7 Math.min(x1, x2,...)

返回最小参数

8 Math.max((x1, x2,...)

返回最小参数

三角函数

Math 库中的所有三角函数都以弧度而不是度数进行运算。

Sr.No 函数和说明
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("第一个测试值:" + value1 );

var value2 = Math.random();
console.log("第二个测试值:" + value2 );

var value3 = Math.random();
console.log("第三个测试值:" + value3 );

var value4 = Math.random();
console.log("第四个测试值:" + value4 );

输出

第一个测试值:0.5782922627404332
第二个测试值:0.5624510529451072
第三个测试值:0.9336334094405174
第四个测试值:0.4002739654388279

ES6 - RegExp

正则表达式是描述字符模式的对象。正则表达式通常缩写为"regex"或"regexp"。

JavaScript RegExp 类表示正则表达式,String 和 RegExp 都定义了使用正则表达式对文本执行强大的模式匹配和搜索替换功能的方法。

正则表达式可以定义为 −

var pattern = new RegExp(pattern, attributed);
或
var pattern = /pattern/attributes;

该属性可以具有以下值的任意组合。

Sr.No 属性 &描述
1

G

全局匹配

2

I

忽略大小写

3

M

多行;将开始和结束字符(^ 和 $)视为跨多行工作(即匹配每行的开头或结尾(以 或 分隔),而不仅仅是整个输入字符串的开头或结尾)

4

U

Unicode;将模式视为 unicode 代码点序列

5

Y

粘性;仅从目标字符串中此正则表达式的 lastIndex 属性指示的索引进行匹配(并且不会尝试从任何后续索引进行匹配)

构造正则表达式

括号

括号 ([]) 在正则表达式中使用时具有特殊含义。它们用于查找字符范围。

Sr.No 表达 &描述
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 的任何小写字符。

量词

括号字符序列和单个字符的频率或位置可以用特殊字符表示。每个特殊字符都有特定的含义。+、*、?$ 标志都遵循字符序列。

Sr.No 表达式 &描述
1

p+

它匹配任何包含至少一个 p 的字符串。

2

p*

它匹配任何包含零个或多个 p 的字符串

3

p?

它匹配任何包含一个或多个 p 的字符串

4

p{N}

它匹配任何包含 N p 序列的字符串

5

p{2,3>

它匹配任何包含两个或三个 p 序列的字符串

6

p{2, >

它匹配任何包含至少两个 p 序列的字符串

7

p$

它匹配任何以 p 结尾的字符串

8

^p

它匹配任何以 p 开头的字符串

9

[^a-zA-Z]

它匹配任何不包含从 azAZ

10

p.p

它匹配任何包含 p 的字符串,后跟任意字符,再后跟另一个 p

11

^.{2}$

它匹配任何包含两个字符的字符串

12

<b>(.*)</b>

它匹配任何包含在 <b> 和 </b> 内的字符串

13

p(hp)*

它匹配任何包含 p 且后跟零个或多个序列 hp 实例的字符串

文字字符

Sr.No 字符 &描述
1

字母数字

本身

2

\0

NULL 字符 (\u0000)

3

Tab (\u0009)

4

换行符 (\u000A)

5

\v

垂直制表符 (\u000B)

6

\f

换页符 (\u000C)

7

回车符 (\u000D)

8

\xnn

十六进制数 nn 指定的拉丁字符;例如,\x0A 与 相同

9

\uxxxx

十六进制数 xxxx 指定的 Unicode 字符;例如,\u0009 与 相同

10

\cX

控制字符 ^X;例如,\cJ 相当于换行符

元字符

元字符只是一个字母字符,前面有一个反斜杠,用于赋予组合特殊含义。

例如,您可以使用'\d'元字符搜索一大笔钱:/([\d]+)000/。这里,\d将搜索任何数字字符串。

下表列出了一组可用于 PERL 样式正则表达式的元字符。

Sr.No 字符 &描述
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 属性

Sr.No 属性 &描述
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 方法

Sr.No 方法 &描述
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

每个网页都位于浏览器窗口内,可将其视为一个对象。

document 对象 表示在该窗口中显示的 HTML 文档。document 对象具有引用其他对象的各种属性,允许访问和修改文档内容。

访问和修改文档内容的方式称为 Document Object ModelDOM。对象按层次结构组织。这种层次结构适用于 Web 文档中对象的组织。

以下是一些重要对象的简单层次结构 −

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 访问的文档属性列表。

Sr.No 属性和说明
1

alinkColor

已弃用 − 指定激活链接颜色的字符串。

示例:document.alinkColor

2

anchors[ ]

锚点对象数组,每个锚点对应文档中出现的锚点。

示例:document.anchors[0]、document.anchors[1] 等等

3

applets[ ]

applet 对象数组,每个小程序对应文档中出现的小程序。

示例:document.applets[0]、document.applets[1] 等等

4

bgColor

已弃用− 指定文档背景颜色的字符串。

示例:document.bgColor

5

Cookie

具有特殊行为的字符串值属性,允许查询和设置与此文档关联的 cookie。

示例:document.cookie

6

指定文档来自的 Internet 域的字符串。用于安全目的。

示例: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 表单都有一个,这些表单以 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

位置

文档的 URL。已弃用,改用 URL 属性。

示例:document.location

15

plugins[ ]

embeds[ ] 的同义词

示例:document.plugins[0]、document.plugins[1] 等等

16

Referrer

一个只读字符串,包含当前文档所链接的文档的 URL(如果有)。

示例 : document.referrer

17

标题

<title> 的文本内容标签。

示例:document.title

18

URL

指定文档 URL 的只读字符串。

示例:document.URL

19

vlinkColor

已弃用 −指定已访问链接颜色的字符串。

示例:document.vlinkColor

旧版 DOM 中的文档方法

以下是旧版 DOM 支持的方法列表。

Sr.No 属性和说明
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 元素。例如,如果 Web 文档包含表单元素,则使用 JavaScript,我们可以将其引用为 document.forms[0]。如果您的 Web 文档包含两个表单元素,则第一个表单称为 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> 

Output

成功执行上述代码后将显示以下输出。

legacy dom method

注意 − 此示例返回表单和元素的对象。我们必须使用本教程中未讨论的对象属性来访问它们的值。

ES6 - 迭代器

迭代器简介

迭代器是一个允许我们一次访问一个对象集合的对象。

以下内置类型默认为可迭代 −

  • String
  • Array
  • Map
  • Set

如果对象实现了一个函数,其键为 [Symbol.iterator] 并返回一个迭代器,则该对象被视为 可迭代。 for...of 循环可用于迭代集合。

示例

以下示例声明一个数组、标记并使用 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

示例

以下示例声明一个数组,标记并检索迭代器对象。[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 中的某些类型是可迭代的(例如数组、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 引入了称为 Generator 的函数,它可以在中途停止,然后从停止的地方继续。

生成器在函数名称前加上星号 * 字符,并包含一个或多个 yield 语句。yield 关键字返回一个迭代器对象。

语法

function * generator_name() {
    yield value1
    ...
    yield valueN
}

示例

该示例使用三个 Yield 语句定义了一个生成器函数 getMarks。与普通函数不同,生成器函数 getMarks() 在调用时不会执行该函数,而是返回一个迭代器对象,该对象可帮助您执行生成器函数内的代码。

第一次调用 markIter.next() 时,开头的操作将运行,yield 语句将暂停生成器的执行。后续调用 markIter.next() 将恢复生成器函数,直到下一个 yield 表达式。

<script>
   	//定义生成器函数
   	function * getMarks(){
      console.log("步骤 1")
      yield 10
      console.log("步骤 2")
      yield 20
      console.log("步骤 3")
      yield 30
      console.log("函数结束")
   	}
    //返回一个迭代器对象
    let markIter = getMarks()
    //调用语句直到第一个yield
    console.log(markIter.next())
    //在最后一个yield之后恢复执行直到第二个yield表达式
    console.log(markIter.next())
    //在最后一个yield之后恢复执行直到第三个yield表达式
    console.log(markIter.next())
    console.log(markIter.next()) // 迭代完成;没有返回任何值
</script>

上述代码输出将概要 −

步骤 1
{value: 10, done: false}
步骤 2
{value: 20, done: false}
步骤 3
{value: 30, done: false}
函数结束
{value: undefined, done: true}

示例

以下示例通过

* evenNumberGenerator 生成器函数创建一个无限偶数序列。

我们可以使用 next() 或使用 for of 循环遍历所有偶数,如下所示

<script>
   function * evenNumberGenerator(){
      let num = 0;
      while(true){
         num+=2
         yield num
      }
   }
   // 显示前两个元素
   let iter = evenNumberGenerator();
   console.log(iter.next())
   console.log(iter.next())
   //使用 for of 迭代到 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 引入了两种新的数据结构:Maps 和 Sets。

  • Maps − 此数据结构支持将键映射到值。

  • Sets − 集合类似于数组。但是,集合不鼓励重复。

Maps

Map 对象是一个简单的键/值对。Map 中的键和值可以是原始的,也可以是对象。

以下是其语法。

new Map([iterable])

参数 iterable 表示任何可迭代对象,其元素由键/值对组成。 Map 是有序的,即它们按照插入的顺序遍历元素。

Map 属性

Sr.No 属性和说明
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

Output

false 
true 

set() 方法也是可链接的。请考虑以下示例。

var role = new Map();
r​​ole.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

注意 − 如果指定的键在映射中不存在,则 get() 函数返回 undefined。

如果键的值已存在于映射中,则 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

映射方法

Sr.No 方法 &描述
1 Map.prototype.clear()

从 Map 对象中删除所有键/值对。

2 Map.prototype.delete(key)

删除与键关联的任何值并返回 Map.prototype.has(key) 之前返回的值。

Map.prototype.has(key) 将返回 false之后。

3 Map.prototype.entries()

返回一个新的 Iterator 对象,该对象包含 Map 对象中每个元素的 [key, value] 数组(按插入顺序排列)。

4 Map.prototype.forEach(callbackFn[, thisArg])

对 Map 对象中存在的每个键值对调用一次 callbackFn,插入顺序。如果为 forEach 提供了 thisArg 参数,它将用作每个回调的"this"值。

5 Map.prototype.keys()

返回一个新的 Iterator 对象,该对象按插入顺序包含 Map 对象中每个元素的 keys

6 Map.prototype.values()

返回一个新的 Iterator 对象,该对象包含数组of [key, value] 按插入顺序对 Map 对象中的每个元素执行此操作。

for…of 循环

以下示例说明如何使用 for…of 循环遍历映射。

'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

弱映射

弱映射与映射相同,但有以下例外 −

  • 其键必须是对象。

  • 弱映射中的键可以被垃圾收集。垃圾收集是清除程序中未引用对象占用的内存的过程。

  • 弱映射无法迭代或清除。

示例:弱映射

'use strict' 
let weakMap = new WeakMap(); 
let obj = {}; 
console.log(weakMap.set(obj,"hello"));  
console.log(weakMap.has(obj));// true

成功执行上述代码后将显示以下输出。

WeakMap {} 
true

集合

集合是 ES6 数据结构。它类似于数组,但不能包含重复项。换句话说,它允许您存储唯一值。集合支持原始值和对象引用。

与映射一样,集合也是有序的,即元素按其插入顺序进行迭代。可以使用以下语法初始化集合。

集合属性

Sr.No 属性 &描述
1 Set.prototype.size

返回 Set 对象中的值的数量。

Set 方法

Sr.No 方法 &描述
1 Set.prototype.add(value)

将具有给定值的新元素附加到 Set 对象。返回 Set 对象。

2 Set.prototype.clear()

从 Set 对象中删除所有元素。

3 Set.prototype.delete(value)

删除与值关联的元素。

4 Set.prototype.entries()

返回一个新的 Iterator 对象,该对象包含 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()

返回一个新的 Iterator 对象,该对象按插入顺序包含 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)

访问函数

可以通过对象访问类的属性和函数。使用"."点符号(称为句点)访问类的数据成员。

//访问函数
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) 
   } 
} 

//创建实例
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 和 Getter

Setter

当尝试设置属性值时,将调用 setter 函数。set 关键字用于定义 setter 函数。定义 setter 函数的语法如下 −

{set prop(val) { . . . }}
{set [expression](val) { . . . }}

prop 是要绑定到给定函数的属性的名称。 val 是保存试图分配给属性的值的变量的别名。expression 使用 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

Getters

当尝试获取属性的值时,将调用 getter 函数get 关键字 用于定义 getter 函数。定义 getter 函数的语法如下所示 −

{get prop() { ... } }
{get [expression]() { ... } }

prop 是要绑定到给定函数的属性的名称。

expression − 从 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 连接起来并返回一个新字符串。

上述代码输出的概要 −

构造函数内部
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

strict 静态关键字

静态关键字可应用于类中的函数。静态成员由类名引用。

示例

'use strict' 
class StaticMem { 
   static disp() { 
      console.log("Static Function called") 
   } 
} 
StaticMem.disp() //调用静态方法

注意 − 不强制包含构造函数定义。每个类默认都有一个构造函数。

成功执行上述代码后将显示以下输出。

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("圆的面积:  "+this.Area) 
   } 
} 
var obj = new Circle(223); 
obj.disp() 

上述示例声明了一个 Shape 类。该类由 Circle 类扩展。由于类之间存在继承关系,子类(即 Circle 类)可以隐式访问其父类属性(即 area)。

成功执行上述代码后将显示以下输出。

圆的面积:223

继承可以归类为 −

  • − 每个类最多可以从一个父类扩展。

  • − 一个类可以从多个类继承。ES6 不支持多重继承。

  • 多级 − 考虑以下示例。

'use strict' 
class Root { 
   test() { 
      console.log("从父类调用") 
   } 
} 
class Child extends Root {} 
class Leaf extends Child   

//通过继承间接继承自 Root {}
var obj = new Leaf();
obj.test()

Leaf 类通过多级继承从 Root 和 Child 类派生属性。

成功执行上述代码后将显示以下输出。

从父类调用

类继承和方法重写

方法重写是一种子类重新定义超类方法的机制。以下示例说明了相同的−

'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() 从 Parent 调用。
doPrint() 正在打印一个字符串。

ES6 - 映射和集合

ES6 引入了两个新的数据结构 − 映射集合。让我们详细了解它们。

映射

映射是 键值对 的有序集合。映射类似于对象。但是,映射和对象之间存在一些差异。这些列在下面 −

Sr.No Object Map
1 键不能是 Object 类型 键可以是任何类型
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

以下是一些可用于操作映射的常用方法 −

Sr.No Object &映射
1 set(key,value)

将键和值添加到映射

2 get(key)

如果键匹配,则返回值

3 has(key)

如果具有指定键的元素存在;否则返回 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,因为键应该是对象
</script>

示例 2

<script>
   let empMap = new WeakMap();
   // emp.set(10,'Sachin');// 错误,因为键应该是对象
   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.size

示例

<script>
   let names = new Set(['A','B','C','D']);
   console.log(names.size)
</script>

上述代码的输出如下所示 −

4

迭代集合

我们可以使用 forEachfor..of 循环来迭代集合。如下面的示例所示 −

示例

<script>
   let names= new Set(['A','B','C','D']);
   //使用 forEach 进行迭代
   console.log('forEach')
   names.forEach(n=>console.log(n))
   
   console.log('for of..')
   
   //使用 for..of 进行迭代
   for(let n of names){
      console.log(n)
   }
</script>  

上述代码的输出如下 −

forEach
A
B
C
D
for of..
A
B
C
D

可以使用以下方法来操作集合 −

Sr.No Object & Map
1 add(element)

向集合中添加元素

2 has(element)

如果找到元素,则返回 true;否则返回 false

3 delete(element)

从 Set 中删除特定元素

4 clear()

从 Set 中清除所有元素

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 - Promises

Promise 语法

下面提到了与 promise 相关的语法,其中 p 是 promise 对象,resolve 是 promise 成功执行时应调用的函数,reject 是 promise 遇到错误时应调用的函数。

let p = new Promise(function(resolve,reject){
    let workDone = true; // 一些耗时的工作
    if(workDone){
        //调用 resolve 函数已传递
        
        resolve('success promise 已完成')
    }
    else{
        rejection('ERROR ,工作无法完成')
    }
})

示例

下面给出的示例显示了一个函数 add_positivenos_async(),它异步添加两个数字。如果传递了正值,则Promise将被解决。如果传递了负值,则Promise将被拒绝。

<script>   
   function add_positivenos_async(n1, n2) {
      let p = new Promise(function (resolve, reject) {
         if (n1 >= 0 && n2 >= 0) {
            //做一些复杂耗时的工作
            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

Promises 链式执行

Promises 链式执行可用于需要依次执行一系列异步任务的情况。当一个 Promises 依赖于另一个 Promises 的结果时,Promises 链式执行。如下面的示例所示

示例

在下面的示例中,add_positivenos_async() 函数异步添加两个数字,如果传递了负值,则拒绝。当前异步函数调用的结果作为参数传递给后续函数调用。注意,每个 then() 方法都有一个 return 语句。

<script>   
   function add_positivenos_async(n1, n2) {
      let p = new Promise(function (resolve, reject) {
         if (n1 >= 0 && n2 >= 0) {
            //做一些复杂耗时的工作
            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就完全解决了。

<script>   
   function add_positivenos_async(n1, n2) {
      let p = new Promise(function (resolve, reject) {
         if (n1 >= 0 && n2 >= 0) {
            //做一些复杂耗时的工作
            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就会得到解决。Promise不会等待其他异步操作完成。

<script>   
   function add_positivenos_async(n1, n2) {
      let p = new Promise(function (resolve, reject) {
         if (n1 >= 0 && n2 >= 0) {
            //做一些复杂耗时的工作
            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

Promises 是在 JavaScript 中实现异步编程的一种简洁方法(ES6 新功能)。在 Promises 之前,回调用于实现异步编程。让我们首先了解什么是异步编程及其使用回调的实现。

了解回调

函数可以作为参数传递给另一个函数。这种机制称为 回调。回调在事件中很有用。

以下示例将帮助我们更好地理解这个概念。

<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"); 
   //最后执行或被其他方法阻止
</script> 

在上面显示的 notifyAll() 方法中,通知通过发送短信和发送电子邮件进行。因此,notifyAll 方法的调用者必须传递两个函数作为参数。每个函数承担一项职责,例如发送短信和发送电子邮件。

成功执行上述代码后将显示以下输出。

starting notification process 
Sms send .. 
Email send .. 
End of script 

在上面提到的代码中,函数调用是同步的。这意味着 UI 线程将等待完成整个通知过程。同步调用变为阻塞调用。现在让我们了解非阻塞或异步调用。

了解 AsyncCallback

考虑上述示例。

要启用脚本,请执行对 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"); //首先执行或者没有被其他人阻止
</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;
// 将此交给某人

实现Promise的第一步是创建一个将使用Promise的方法。假设在这个例子中,getSum()方法是异步的,即其操作不应阻止其他方法的执行。一旦此操作完成,它将稍后通知调用者。

以下示例(步骤 1)声明了一个 Promise 对象"var promise"。Promise 构造函数首先调用函数以成功完成工作,然后调用另一个函数以防发生错误。

Promise通过使用 resolve 回调并传入结果(即 n1+n2)来返回计算结果

步骤 1 − resolve(n1 + n2);

如果 getSum() 遇到错误或意外情况,它将调用 Promise 中的拒绝回调方法,并将错误信息传递给调用者。

步骤 2 − accept(Error("Negatives not supports"));

方法实现在下面的代码中给出(步骤 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); 
   // 这将返回另一个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); 
      //这将返回另一个 Promise 
   },   
   function(error) {   
      console.log(error);   
   })
   .then(function(result) {   
      console.log(result);   
      returngetSum(30, 40); 
      //这将返回另一个 Promise 
   }, 
   function(error) {   
      console.log(error);   
   })   
   .then(function(result) {   
      console.log(result);   
   }, 
   function(error) {         
      console.log(error);   
   });   
   console.log("脚本结束");   
</script> 

成功执行上述代码后将显示以下输出。

程序首先显示"脚本结束",然后逐一显示调用 getSum() 方法的结果。

脚本结束
11
30
70

这表明 getSum() 是以异步方式或非阻塞方式调用的。Promise 提供了一种简洁明了的方式来处理回调。

ES6 - 模块

简介

考虑需要重用部分 JavaScript 代码的场景。ES6 通过 模块 的概念来帮助您。

模块组织一组相关的 JavaScript 代码。模块可以包含变量和函数。模块只不过是写在文件中的一段 JavaScript 代码。默认情况下,模块的变量和函数不可用。模块内的变量和函数应导出,以便可以从其他文件内访问它们。ES6 中的模块仅在严格模式下工作。这意味着模块中声明的变量或函数将无法全局访问。

导出模块

export 关键字可用于导出模块中的组件。模块中的导出可分为以下几类 −

  • 命名导出
  • 默认导出

命名导出

命名导出通过其名称来区分。模块中可以有多个命名导出。模块可以使用下面给出的语法导出选定的组件 −

语法 1

//使用多个导出关键字
export component1
export component2
...
...
export componentN

语法 2

或者,模块中的组件也可以使用单个导出关键字和 {} 绑定语法导出,如下所示 −

//使用单个导出关键字

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 文件并在实时服务器中运行它。请注意,我们应该在脚本标记中使用 attribute 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 文件并在实时服务器中运行它。请注意,我们应该在脚本标记中使用 attribute 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 对象的预定义类型。

Sr.No 错误对象和说明
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 {
    // 要运行的代码
    [break;]
} catch ( e ) {
    // 发生异常时运行的代码
    [break;]
}[ finally {
    // 无论是否发生异常,始终执行的代码
    //
}]

示例

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 ); 
}

Output

成功执行上述代码后将显示以下输出。

Error: Divide by zero error

注意 − 注意:您可以在一个函数中引发异常,然后可以使用 try...catch 块在同一函数或调用函数中捕获该异常。

onerror() 方法

onerror 事件处理程序是第一个促进 JavaScript 中错误处理的功能。每当页面上发生异常时,都会在窗口对象上触发错误事件。

示例

<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> 

Output

成功执行上述代码后将显示以下输出。

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 对象的一些常用方法是 −

Sr.No 方法和说明
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 代表全局匹配
   let result = str.match(regex);
   console.log(result)
</script>

上述代码的输出如下所示 −

["J", "J", "F", "W", "F"]

正则表达式搜索区分大小写。要关闭区分大小写,请使用 /i 修饰符。

示例

以下示例执行不区分大小写的全局匹配。该示例将 fun 替换为 enjoyable

<script>
   // /gi 全局匹配忽略大小写

   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

Number

ES6 中添加到 Number 对象 的一些常用方法是 −

Sr.No 方法和说明
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 对象 的一些流行方法是 −

Sr.No 方法 &描述
1 Math.sign()

函数返回数字的符号,表示数字是正数、负数还是零。

2 Math.trunc()

函数通过删除小数部分返回数字的整数部分。

ES6 中的数组方法

下表重点介绍了 ES6 中的不同数组方法以及带有说明。

Sr.No 方法 &描述
1 copyWithin()

将数组的一部分浅拷贝到同一数组中的另一个位置并返回,而不修改其长度。

2 entries()

方法返回一个新的 Array Iterator 对象,其中包含数组中每个索引的键/值对。

3 find()

方法返回数组中第一个满足所提供测试函数的元素的值。否则返回 undefined。

4 fill()

方法用静态值填充数组中从起始索引到结束索引的所有元素。它返回修改后的数组。

5 Array.of()

方法从可变数量的参数创建一个新的 Array 实例,无论参数的数量或类型如何。

6 Array.from()

方法从类似数组或可迭代对象创建浅拷贝。

Object

下表中列出了与 Object 函数相关的方法以及相应的描述。

Sr.No 方法 &描述
1 Object.is()

方法确定两个值是否为同一值

2 Object.setPrototypeOf()

方法将指定对象的原型设置为另一个对象或 null。

3 Object.assign()

方法用于将所有可枚举的自身属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

ES6 - Reflect API

ES6 引入了围绕元编程的新功能,涉及检查或修改程序的结构,或更改语言本身的工作方式。

以下是元编程的三种形式 −

  • 自省 − 自省意味着程序收集有关自身的信息。用于自省的 JavaScript 运算符的一些示例是 typeof、instanceof 等。

  • 自我修改 − 自我修改是指在运行时修改程序的结构。它涉及在运行时访问或创建新属性。换句话说,自我修改是某些代码修改自身的时候。

  • 调解 − 是指代码修改编程语言的默认行为。调解涉及在运行时修改编程语言的语义或向程序添加新构造。

ES6 引入了支持元编程的 Reflect 应用程序编程接口 (Reflect API) 和代理 API。

使用 Reflect API 进行元编程

ES6 中的 Reflect API 允许我们在运行时检查或修改程序的类、对象、属性和方法。 Reflect API 提供全局 Reflect 对象,该对象具有可用于自省的静态方法。这些方法用于发现有关代码的低级信息。Reflect API 可用于构建在运行时检查和自省程序的自动化测试框架。

下面给出了 Reflect 对象的一些常用方法 −

Sr.No 方法 &描述
1 Reflect.apply()

使用 args 参数指定的参数调用目标函数

2 Reflect.construct()

相当于调用类的新目标(...args)对象

3 Reflect.get()

返回属性值的函数。

4 Reflect.set()

为属性赋值的函数。如果更新成功,则返回布尔值,该值为 true。

5 Reflect.has()

in 运算符作为函数。返回一个布尔值,指示是否存在自有或继承的属性。

ES6 - 代理 API

ES6 使用代理实现元编程的代理形式。与 ReflectAPI 类似,代理 API 是在 ES6 中实现元编程的另一种方式。代理对象用于定义基本操作的自定义行为。代理对象代表真实对象执行一些操作。

下面给出了与 ES6 代理相关的各种术语

Sr.No 方法和说明
1

处理程序

包含陷阱的占位符对象

2

陷阱

提供属性访问的方法。这类似于操作系统中的陷阱概念

1

目标

代理虚拟化的对象。它通常用作代理的存储后端。

语法

以下语法适用于代理 API,其中,target 可以是任何类型的对象,如数组、函数或其他代理,而 handler 是属性为函数的对象。这定义了代理的行为。

const proxy = new Proxy(target,handler)

处理程序方法

处理程序对象包含代理的陷阱。所有陷阱都是可选的。如果未定义陷阱,则默认行为是将操作转发到目标。一些常见的处理程序方法如下 −

Sr.No 方法 &描述
1 handler.apply()

函数调用的陷阱。

2 handler.construct()

new 运算符的陷阱。

3 handler.get()

A获取属性值的陷阱。

4 handler.set()

设置属性值的陷阱。

5 handler.has()

in 运算符的 TA 陷阱。

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> 

Output

成功执行上述代码后将显示以下输出。

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 属性以将其定位在屏幕上的任何位置。以下是相同的语法。

// 设置与屏幕左边缘的距离。
object.style.left = 像素或点的距离;
或
// 设置与屏幕顶部边缘的距离。
object.style.top = 像素或点的距离;

手动动画

让我们使用 DOM 对象属性和 JavaScript 函数实现一个简单的动画,如下所示。以下列表包含不同的 DOM 方法。

  • 我们使用 JavaScript 函数 getElementById() 获取 DOM 对象,然后将其分配给全局变量 imgObj

  • 我们定义了一个初始化函数 init() 来初始化 imgObj,并在其中设置了其位置和左侧属性。

  • 我们在窗口加载时调用初始化函数。

  • 我们调用 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 导航器对象包含一个名为 plugins 的子对象。此对象是一个数组,每个安装在浏览器上的插件都有一个条目。只有 Netscape、Firefox 和 Mozilla 支持 navigator.plugins 对象。

示例

以下示例显示如何列出浏览器中安装的所有插件。

<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>

Output

成功执行上述代码后将显示以下输出。

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

查找和修复错误的过程称为调试,是开发过程的正常部分。本章介绍可帮助您完成调试任务的工具和技术。

IE 中的错误消息

追踪错误的最基本方法是打开浏览器中的错误信息。默认情况下,当页面发生错误时,Internet Explorer 会在状态栏中显示一个错误图标。

错误图标

双击此图标将转到一个对话框,其中显示有关已发生特定错误的信息。

由于此图标很容易被忽略,因此 Internet Explorer 为您提供了在发生错误时自动显示错误对话框的选项。

要启用此选项,请选择工具 → Internet 选项 →高级选项卡,最后选中"显示有关每个脚本错误的通知"框选项,如以下屏幕截图所示。

Internet 选项

Firefox 或 Mozilla 中的错误消息

其他浏览器(如 Firefox、Netscape 和 Mozilla)会将错误消息发送到一个称为 JavaScript 控制台错误控制台 的特殊窗口。要查看控制台,请选择 工具 →错误控制台或 Web 开发

不幸的是,由于这些浏览器在发生错误时没有提供任何视觉指示,因此您必须保持控制台打开并在脚本执行时观察错误。

错误控制台

错误通知

控制台上或 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 一起使用的步进命令。

Sr.No 步进命令 &描述
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://code.visualstudio.com/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.html" alt = "Perl Tutorial" 
            target = "_self" 
            onMouseOver = "showTutorial('perl')" 
            onMouseOut = "showTutorial('')"/>
         <area shape = "rect"   
            coords = "22,83,126,125"  
            href = "/html/index.html" alt = "HTML Tutorial" target = "_self"   
            onMouseOver = "showTutorial('html')"         
            onMouseOut = "showTutorial('')"/>  
         <area shape = "circle"  coords = "73,168,32"  
            href = "/php/index.html" alt = "PHP Tutorial" target = "_self"   
            onMouseOver = "showTutorial('php')"       
            onMouseOut = "showTutorial('')"/> 
      </map> 
   </body>
   
</html>

成功执行上述代码后将显示以下输出。您可以通过将鼠标光标放在图像对象上来感受地图概念。

image map

ES6 - 浏览器

了解不同浏览器之间的差异非常重要,以便以预期的方式处理每个浏览器。因此,了解您的网页在哪种浏览器中运行非常重要。要获取有关您的网页当前在哪种浏览器中运行的信息,请使用内置导航器对象。

导航器属性

您可以在网页中使用多个与导航器相关的属性。以下是名称及其说明的列表。

Sr.No 属性 &描述
1

appCodeName

此属性是一个字符串,包含浏览器的代码名称,对于 Netscape 为 Netscape,对于 Internet Explorer 为 Microsoft Internet Explorer。

2

appVersion

此属性是一个字符串,包含浏览器的版本以及其他有用信息,例如其语言和兼容性。

3

language

此属性包含两个字母的缩写浏览器使用的语言。仅限 Netscape。

4

mimTypes[]

此属性是一个数组,包含客户端支持的所有 MIME 类型。仅限 Netscape。

5

platform[]

此属性是一个字符串,包含浏览器编译的平台。"Win32"适用于 32 位 Windows 操作系统。

6

plugins[]

此属性是一个数组,包含已安装在客户端上的所有插件。仅限 Netscape。

7

userAgent[]

此属性是一个字符串,包含浏览器的代码名称和版本。此值将发送到原始服务器以识别客户端。

Navigator 方法

有几种特定于 Navigator 的方法。以下是它们的名称和说明的列表。

Sr.No 方法和描述
1

javaEnabled()

此方法确定客户端中是否启用了 JavaScript。如果启用了 JavaScript,此方法返回 true;否则,返回 false。

2

plugings.refresh

此方法使新安装的插件可用,并使用所有新插件名称填充插件数组。仅限 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 的浏览器");
            // 在此处保留您的 opera 特定 URL。
            } else if (gecko) {
            document.write("基于 Mozilla 的浏览器");
            // 在此处保留您的 gecko 特定 URL。
            } else if (ie) {
            document.write("基于 IE 的浏览器");
            // 在此处保留您的 IE 特定 URL。
            } else if (netscape) {
            document.write("基于 Netscape 的浏览器");
            // 在此处保留您的 Netscape 特定 URL。
            } else {
            document.write("未知浏览器");
            }
            // 您可以将版本与上述任何条件一起包含。
            document.write("<br /> 浏览器版本信息:" + version );
            //
         --> 
      </script> 
   </body> 
   
</html>

成功执行上述代码后将显示以下输出。

Mozilla based browser  
Browser version info : 5.0 

(Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML,类似 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

数组包含

ES7 中引入的 Array.includes() 方法有助于检查数组中是否有元素。在 ES7 之前,Array 类的 indexof() 方法可用于验证数组中是否存在值。如果找到数据,indexof() 将返回数组中第一次出现的元素的索引,否则如果数据不存在则返回 -1。

Array.includes() 方法接受一个参数,检查作为参数传递的值是否存在于数组中。如果找到该值,则此方法返回 true,否则如果该值不存在,则返回 false。使用 Array.includes() 方法的语法如下所示 −

语法

Array.includes(value)

Array.includes(value,start_index)

第二种语法检查指定索引中的值是否存在。

示例

以下示例声明一个数组标记并使用 Array.includes() 方法来验证数组中是否存在某个值。

<script>
    let marks = [50,60,70,80]
    //检查数组中是否包含 50
    if(marks.includes(50)){
    console.log('在数组中找到元素')
    }else{
    console.log('找不到元素')
    }
    
    //检查是否从索引 1 找到 50
    if(marks.includes(50,1)){ //从索引 1 搜索
    console.log('在数组中找到元素')
    }else{
    console.log('找不到元素')
    }
    
    //检查数组中是否为非数字 (NaN)
    console.log([NaN].includes(NaN))
    
    //创建一个对象数组
    let user1 = {name:'kannan'},
    user2 = {name:'varun'},
    user3={name:'prijin'}
    let users = [user1,user2]
    
    //检查对象是否可用数组
    console.log(用户.includes(用户1))
    console.log(用户.includes(用户3))
    </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>

   //用 0 填充字符串
   let product_cost = '1699'.padStart(7,0)
   console.log(product_cost)
   console.log(product_cost.length)

   //用空格填充字符串
   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>

    //用 x 填充字符串
    let product_cost = '1699'.padEnd(7,'x')
    console.log(product_cost)
    console.log(product_cost.length)
    
    //用空格填充字符串
    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:缺少形式参数
(,)=>{}; //SyntaxError:预期表达式,结果为 ','
test(,) //SyntaxError:预期表达式,结果为 ','
  • 尾随逗号不能与剩余参数一起使用。

function test(...arg1,){} // SyntaxError:剩余参数后的参数
(...arg1,)=>{} // SyntaxError:预期右括号,结果为 ','

示例

以下示例声明了一个在参数列表中带有尾随逗号的函数。

<script>

   function sumOfMarks(marks,){ // 忽略尾随逗号
      let sum=0;
      marks.forEach(function(e){
         sum+=e;
      })
      return sum;
   }

   console.log(sumOfMarks([10,20,30]))
   console.log(sumOfMarks([1,2,3],))// 忽略尾随逗号
</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 中 Promises 的语法糖。await 关键字与Promise一起使用。此关键字可用于暂停函数的执行,直到Promise得到解决。如果Promise得到解决,await 关键字将返回Promise的值,如果Promise被拒绝,它将抛出错误。await 函数只能在标记为 async 的函数内使用。使用 async 关键字声明的函数始终返回Promise。

语法

带有 await 的 async 函数的语法如下 −

async function function_name(){
    let result_of_functionCall = await longRunningMethod();
}
//调用异步函数

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) {
            //做一些复杂耗时的工作
            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 loop

异步可迭代对象无法使用传统的 for..of loop 语法进行迭代,因为它们返回的是Promise。ES9 引入了 for await of loop 来支持异步迭代

使用 for await of loop 的语法如下,其中,

  • 每次迭代时,都会将不同属性的值分配给 variable,并且可以使用 const、let 或 var 声明变量。

  • iterable −需要迭代其可迭代属性的对象。
for await (variable of iterable) {
    语句
}

示例

以下示例展示了如何使用 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

Rest/Spread 属性

ES9 支持将 Rest 和 Spread 运算符与对象一起使用。

示例:对象和 Rest 运算符

以下示例显示了将 rest 运算符与对象一起使用。student 的 age 属性值被复制到 age 变量中,而其余属性的值则使用 rest 语法 `...` 复制到另一个变量中。

<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的 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 序列解析为未定义,并且不会引发错误。这在下面的示例中显示 −

<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"}

正则表达式功能

在正则表达式中,点运算符或句点用于匹配单个字符。. 点运算符 会跳过换行符,如 , ,如下例所示−

console.log(/Tutorials.Point/.test('Tutorials_Point')); //true
console.log(/Tutorials.Point/.test('Tutorials
Point')); //false
console.log(/Tutorials.Point/.test('Tutorials
Point')); //false

正则表达式模式表示为 / regular_expression /。 test() 方法采用字符串参数并搜索正则表达式模式。在上面的示例中,test() 方法 搜索以 Tutorials 开头,后跟任意单个字符并以 Point 结尾的模式。如果我们在 Tutorials 和 Point 之间的输入字符串中使用 ,则 test() 方法将返回 false。

true
false
false

ES9 引入了一个新标志 - DotAllFlag (\s),可与正则表达式一起使用来匹配行终止符和表情符号。以下示例显示了这一点 −

console.log(/Tutorials.Point/s.test('Tutorials
Point'));
console.log(/Tutorials.Point/s.test('Tutorials
Point'));

上述代码的输出将如下所示 −

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