一、ECMAScript

1、ECMA

ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为 Ecma 国际。

2、ECMAScript

ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言。

3、什么是 ECMA-262

Ecma 国际制定了许多标准,而 ECMA-262 只是其中的一个

4、ECMA-262 历史

ECMA-262(ECMAScript)历史版本:点我查看

第 1 版1997 年制定了语言的基本语法
第 2 版1998 年较小改动
第 3 版1999 年引入正则、异常处理、格式化输出等。IE 开始支持
第 4 版2007 年过于激进,未发布
第 5 版2009 年引入严格模式、JSON,扩展对象、数组、原型、字符串、日期方法
6 2015 模块化、面向对象语法、Promise、箭头函数、let、const、数组解构赋值等等
第 7 版2016 年幂运算符、数组扩展、Async/await 关键字
第 8 版2017 年Async/await、字符串扩展
第 9 版2018 年对象解构赋值、正则扩展
第 10 版2019 年扩展对象、数组方法
ES.next动态指向下一个版本

5、ECMAScript 和 JavaScript 的关系

一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系?

要讲清楚这个问题,需要回顾历史。1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。

因此,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 Jscript 和 ActionScript)

二、基本语法

ES6 相对之前的版本语法更严格,新增了面向对象的很多特性以及一些高级特性。本部分只学习项目开发中涉及到 ES6 的最少必要知识,方便项目开发中对代码的理解。

1、let 声明变量

创建文件夹 02-ES6-demo,创建 01-let.js

let比起var的提升(区别):

  1. 变量不能重复声明
  2. 存在块儿级作用域(但是两者都具备函数级别的作用域)
  3. 不存在变量提升
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//声明变量
let a
let b, c, d
let e = 100
let f = 521,
g = 'iloveyou',
h = []

//1. 变量不能重复声明
let name = 'Helen'
let name = '环' //报错:SyntaxError: Identifier 'name' has already been declared

//2. 存在块儿级作用域
// if else while for
{
let star = 5
}
console.log(star) //报错:star is not defined

//var和let都具备函数级别的作用域
function test1() {
var f1 = '函数test1的变量'
console.log(f1)
}
test1()
console.log(f1) // f1 is not defined

//3. 不存在变量提升
console.log(song) //报错:Cannot access 'song' before initialization
let song = '依然爱你'

2、const 声明常量

创建 02-const.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//声明常量
const SCHOOL = '尚硅谷'
console.log(SCHOOL)

//1. 一定要赋初始值
const A//报错:SyntaxError: Missing initializer in const declaration

//2. 一般常量使用大写(潜规则,可以小写)
const a = 100

//3. 常量的值不能修改
SCHOOL = 'ATGUIGU'//报错:TypeError: Assignment to constant variable.

console.log(PLAYER)//报错:ReferenceError: PLAYER is not defined

//4. 对于数组和对象的元素修改, 不算做对常量的修改, 不会报错
const TEAM = ['康师傅','海狗人参丸','雷神','阳哥']
TEAM.push('环') //常量地址不变,添加内容不会报错,(添加内容,数组地址不会变)
TEAM = 100 //报错:TypeError: Assignment to constant variable.

3、解构赋值

创建 03-解构赋值.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,
//这被称为解构赋值。
//1. 数组的解构
const F4 = ['小沈阳', '刘能', '赵四', '宋小宝']
let [xiao, liu, zhao, song] = F4
console.log(xiao)
console.log(liu)
console.log(zhao)
console.log(song)

//2. 对象的解构
const zbs = {
username: '赵本山',
age: '不详',
xiaopin: function () {
console.log('演小品')
},
}

let { username, age, xiaopin } = zbs

console.log(username)
console.log(age)
console.log(xiaopin)
xiaopin()

//3. 根据名字自动解构
// 需要几个属性写几个
// let {username} = zbs

4、模板字符串

创建 04-模板字符串.js

模板字符串相当于加强版的字符串,用反引号 `

除了作为普通字符串,还可以用来定义多行字符串,还可以在字符串中加入变量和表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ES6 引入新的声明字符串的方式 『``』 '' ""
//1. 声明
let str = `我也是一个字符串哦!`
console.log(str, typeof str)

//2. 内容中可以直接出现换行符
let list = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>魏翔</li>
<li>艾伦</li>
</ul>`
console.log(list)

//3. 变量拼接
let lovest = '贾玲'
let out = `我喜欢${lovest}`
console.log(out)

5、声明对象简写

创建 05-声明对象简写.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let username1 = 'Tom'
let age1 = 2
let sing1 = function () {
console.log('I love Jerry')
}

// 传统
let person1 = {
username: username1,
age: age1,
sing: sing1,
}
console.log(person1)
person1.sing()

// ES6:变量和属性名合并为一个关键字,这样的书写更加简洁
let person2 = {
age1,
username1,
sing1,
}
console.log(person2)
person2.sing1()

6、定义方法简写

创建 06-定义方法简写.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 传统
let person1 = {
sayHi: function () {
console.log('Hi')
},
}
person1.sayHi()

// ES6
let person2 = {
sayHi() {
console.log('Hi')
},
}
person2.sayHi()

7、参数的默认值

注意:函数在 JavaScript 中也是一种数据类型,JavaScript 中没有方法的重载

创建 07-参数的默认值.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//ES6 允许给函数参数赋值初始值
// 优先使用传进去的值
//1. 形参初始值 具有默认值的参数
function add(a, b, c = 5) {
return a + b + c
}
let result = add(1, 2)
console.log(result) // 8------>1+2+默认值5=8

//2. 与解构赋值结合
function connect({ host = '127.0.0.1', username, password, port }) {
console.log(host) // atguigu.com
console.log(username) // root
console.log(password) // root
console.log(port) // 3306
}
connect({
host: 'atguigu.com',
username: 'root',
password: 'root',
port: 3306,
})

8、对象拓展运算符

创建 08-对象扩展运算符.js

扩展运算符(spread)也是三个点 ...

它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。

1
2
3
4
5
6
7
8
9
//展开对象(拷贝对象)
let person = { name: '路飞', age: 17 }
// let someone = person //引用赋值,即把当前对象person的内存地址传递给someone
// someone.name = '索隆' //使用引用赋值修改,会把person和someone的name值都修改掉

let someone = { ...person } //对拷拷贝
someone.name = '索隆'
console.log(person) // { name: '路飞', age: 17 }
console.log(someone) // { name: '索隆', age: 17 }

9、箭头函数

创建 09-箭头函数.js

箭头函数提供了一种更加简洁的函数书写方式。

基本语法是:参数 => 函数体箭头

函数多用于匿名函数的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//声明一个函数
let fn = function (a) {
return a + 100
}

//箭头函数,省略function
let fn = (a) => {
return a + 100
}

//简写:如果只有一句话,并且是reture语句,可以省略大括号
let fn = (a) => a + 100

//调用函数
let result = fn(1)
console.log(result) //101

10、Promise

Promise 是 ES6 引入的异步编程的新解决方案。

在很多时候,我们在进程中使用单一线程从头到尾地执行程序,这种简单模式会导致性能和用户体验另人难以接受。

比如程序向另外一台服务器发出请求,由于网络等外部原因,此种通信任务往往会耗费大量时间,进程如果在此期间仅仅只能等待网络或网络上其他机器的响应,将严重地降低了性能。程序不应该浪费等待的时间,而应该更加高效地利用,在等待的时间执行其他任务,回复到达后在继续执行第一个任务。

如果程序调用某个方法,等待其执行全部处理后才能继续执行,我们称其为同步的。相反,在处理完成之前就返回调用方法则是异步的。
我们在编程语言的流程中添加了异步控制的部分,这部分的编程可以称之为异步编程

一句简单的话来概括异步编程就是,程序无须按照代码顺序自上而下的执行

语法上 Promise 是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果

创建 10-Promise 基本语法.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 异步编程解决方案:文件的读取、ajax等等
// Promise对象有三个状态:初始化、成功、失败
// resolve:函数类型的参数,可以将Promise状态设置为成功
// reject:函数类型的参数,可以将Promise的状态设置为失败

// 以文件的读取为例
const fs = require('fs') //引入node.js中的本地文件扩展模块

// 实例化 Promise 对象:
const p = new Promise((resolve, reject) => {
// 调用readFile方法读取磁盘文件:异步操作
// 第一个参数:读取的文件路径
// 第二个参数:读取过程中对响应结果的处理(名字不重要,可以叫(e,d)或者其它)
fs.readFile('./hello.txt', (err, data) => {
// 当文件读取失败时,可以获取到err的值
// reject将Promise对象的状态设置为失败
// 如果Promise的状态变为失败,就调用catch
if (err) reject(err)

// 当文件读取成功时,可以获取到data的值
// resolve将Promise对象的状态设置为成功
// 如果Promise的状态变为成功状态,就调用then
resolve(data)
})
})

// 调用 promise 对象的方法
// then:当 Promise状态成功时执行
// catch:当 Promise状态失败时执行
p.then((response) => {
// 成功业务逻辑
console.log(response.toString())
}).catch((error) => {
// 失败业务逻辑
console.log('出错了')
console.error(error)
})