学习笔记:ECMAScript教程(尚硅谷)
介绍
- 本文主要记录在学习尚硅谷的 ECMAScript 课程时的一些笔记
- 尚硅谷前端学科全套课程请点击这里进行下载,提取码:afyt
一、ECMA
二、ES6
1.let
变量不能重复声明
1 | let name = "wrysmile" |
块级作用域
- 在ES5中只有全局、函数、eval(严格模式下才有)作用域
- ES6新增块级作用域,let 声明的变量只能作用在块级作用域中
- if、else、while、for、花括号都属于块级作用域
不存在变量提升
不影响作用域链
!案例:遍历绑定事件时使用不使用this
在遍历绑定事件时
- 如果使用 var 声明,不使用 this 时会因为全局作用域中的变量导致事件找不到当前下标
- 如果使用 let 声明,因为其声明的变量只在其块级作用域中有效,所以事件可以找到当前下标
案例如下:
1 | <h1>点击切换颜色</h1> |
2.const
作用:用来声明一个常量
一定要赋初始值
一般常量使用大写
常量的值不能修改
块级作用域
对于数组和对象的元素修改,不算做常量的修改,不会报错
3.变量解构赋值
ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,称为解构赋值
数组的解构:
1 | const arr = ["小明","小张","小王","小李"]; |
对象的解构:
1 | const obj = { |
4.模板字符串
概念:ES6 中引入了新的声明字符串的方式
内容中可以直接出现换行符
1 | let str = `你好 |
支持变量拼接,只需要使用
${}
即可进行拼接
1 | let str1 = "陈奕迅"; |
5.简化对象写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
1 | let name = "Wrysmile"; |
6.箭头函数
ES6 中允许使用箭头来定义函数
特性:
- this 是静态的,this 始终指向函数声明时所在作用域下的 this 的值
- 不能作为构造函数来实例化对象
- 不能使用 arguments 变量
简写:
- 省略小括号:当形参有且只有一个的时候
- 省略花括号:当代码体只有一条语句的时候,此时代码体的 return 必须省略,因为语句的执行结果就是函数的返回值
适合:
- 与 this 无关的回调,如定时器,数组的方法回调
不适合:
- 与 this 有关的回调,如事件回调,对象的方法
案例
通过静态this来修改元素属性
1 | const ad = document.getElementById("ad"); |
从数组中返回偶数的元素
1 | const arr = [1,4,6,7,58,63,100]; |
7.函数参数的默认值
ES6 允许给函数参数赋值初始值
特性:
- 形参初始值,具有默认值的参数,一般位置要靠后
- 可以与解构赋值结合
与解构赋值结合可以省略一部分重复代码,如下:
1 | function connect(options){ |
8.rest 参数
ES6 可以使用 rest 参数来获取函数的实参,用来代替 arguments
语法:
...args
,即在标识符前加三个点
1 | function date(...args){ |
与 arguments 的区别:
- arguments 返回的是对象
- rest 参数返回的是数组
9.扩展运算符
...
能将数组转换为逗号分割的参数序列,如下:
1 | const tfboys = ["易烊千玺", "王源", "王俊凯"]; |
两个函数执行结果对比如下:
应用:
- 数组的合并
- 数组的克隆
- 伪数组转为真正的数组
应用案例如下:
1 | // 数组的合并 |
10.Symbol
ES6 中引入了一种新的原始数据类型
Symbol
,表示独一无二的值它是 JS 的第七种数据类型,也是一种类似于字符串的数据类型
特点:
- Symbol 的值是唯一的,用来解决命名冲突的问题
- Symbol 的值不能与其他数据进行运算
- Symbol 定义的对象属性不能使用
for...in
循环遍历,但是可以使用Reflect.ownKeys
来获取对象的所有键名
(1).基础使用
普通创建 Symbol:
1 | let s = Symbol(); |
使用
Symbol.for()
来创建 Symbol:(可以通过描述字符串来找到唯一的Symbol值)
1 | let s1 = Symbol.for("s1"); |
使用描述字符串来标识一个 Symbol:
1 | let s2 = Symbol("s2"); |
(2).创建对象属性
当向某个对象中添加方法时,为了避免重名的问题,可以使用 Symbol 来唯一标识
1 | let game = { |
(3).Symbol 内置值
除了定义自己使用的 Symbol 值以外,ES 6还提供了11个内置的 Symbol 值,指向语言内部使用的方法
视频链接点这里的p17
11.迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署了 Iterator 接口就可以完成遍历操作
ES6 创造了一种新的遍历命令
for...of
循环,而迭代器主要供for...of
消费for...in
循环是获取到了属性名fro...of
循环是获取到了属性值
原生具备 Iterator 接口的数据,即可以使用
for...of
循环的有:Array、Arguments、Set、Map、String、TypedArray、NodeList工作原理:
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
- 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
- 每调用 next 方法返回一个包含 value 和 done 属性的对象
1 | const xiyou = ['唐僧','孙悟空','猪八戒','沙僧']; |
注意:需要自定义遍历数据的时候,要想到迭代器
1 | // 自定义迭代器 —— 遍历得出对象中数组的每个值 |
12.生成器
ES6 提供了一种异步编程的解决方案 —— 生成器函数
异步编程指纯回调函数,例如:Node中的fs模块、ajax、MongoDB等
创建生成器:在函数名前面加一个星号,返回的是迭代器对象,所以需要使用
next()
方法来执行其中的语句
1 | function * gen(){ |
代码分割:在该函数中可以使用
yield
来进行代码分割,执行next()
方法时就会按分割的区域顺序执行
1 | function * gen(){ |
函数传参:在
next()
方法中可以传入实参,该实参将作为上一次 yield 语句的返回值来进行展示
1 | function * gen2(arg){ |
案例:
1秒后输出111,2秒后输出222,3秒后输出333
1 | function one(){ |
模拟获取用户数据、订单数据、商品数据
1 | function getUser(){ |
13.Promise
ES6 引入的一种新的异步编程解决方案,是一个构造函数
作用:封装异步操作并可以获取其成功或失败的结果
1 | const p = new Promise(function (resolve, reject){ |
then()
方法:该方法的返回结构是 Promise 对象,对象状态由回调函数的执行结构来决定- 如果回调函数中返回的结构是非 Promise 类型的属性,返回状态为成功,返回值为对象的成功的值
- 如果回调函数中返回的结构是 Promise 类型的属性,返回状态是成功则成功,失败则失败
- 如果回调函数中返回的结构是抛出错误,返回状态为失败
- 所以,
then()
方法可以链式调用
catch()
方法:是then()
方法的语法糖,具体同上
案例:
使用 Promise 读取一个文件:
1 | const fs = require("fs"); |
使用 Promise 封装 AJAX:
1 | const p = new Promise((resolve, reject) => { |
使用 Promise 读取多个文件:
1 | // 普通读取多个文件 |
14.Set
ES6 提供了新的数据结构 —— Set(集合),类似于数组但成员的值都是唯一的,数据类型是对象
集合实现了 Iterator 接口,所以可以使用
扩展运算符
和for...of
来进行遍历声明一个 set,同时在传入值的时候还可以达到数组去重的效果
1 | const s1 = new Set(); |
集合的属性和方法:
s.size()
:返回集合的元素个数s.add()
:增加一个新元素,返回当前集合s.delete()
:删除一各元素,返回布尔值s.has()
:检测集合中是否包含某个元素,返回布尔值s.clear()
:清空当前集合
案例:
数组去重:
1 | const arr = [1, 2, 4, 6, 4, 1]; |
两数组的交集
1 | const arr1 = [1, 2, 4, 6, 4, 1]; |
两数组的并集
1 | const arr1 = [1, 2, 4, 6, 4, 1]; |
两数组的差值
1 | const arr1 = [1, 2, 4, 6, 4, 1]; |
15.Map
ES6 提供了 Map 数据结构,类似于对象,是键值对的集合,但键不限于字符串,各种类型的值(包括对象)都可以当做键
Map 也实现了 Iterator 接口,所以可以使用 扩展运算符
和 for...of
来进行遍历
声明一个 Map:
1 | const m = new Map(); |
Map 的属性和方法:
m.size()
:返回 Map 的元素个数m.set()
:增加一个新元素,返回当前 Mapm.get()
:返回键名对象的键值m.has()
:检测 Map 中是否包含某个元素,返回布尔值m.clear()
:清空集合,返回 undefined
16.Class
通过 class 关键字可以定义类,可以看做一个语法糖
(1).声明类
如下:
1 | class Phone{ |
(2).静态成员
通过
static
关键字设置的属性为静态属性,是不能被实例对象所引用的。就类似于Phone.name
设置的属性而不通过
static
关键字设置的属性是可以被实例对象所调用的。就类似于Phone.prototype.name
设置的属性
(3).继承
ES5 中的对象继承:
1 | // 父类 |
ES6 中的对象继承:
1 | // 父类 |
(4).重写
我们可以在子类中重写父类的同名方法,同时也可以使用
super.方法名()
来调用父类的方法:
1 | // 父类 |
(5).get与set
在 Class 中可以使用
get
来读取类中的方法,同时还可以读取到返回值
1 | class Phone{ |
在 Class 中给方法赋值时就会调用
set
中的函数
1 | class Phone{ |
17.数值扩展
Number.EPSILON
:JS 中表示的最小精度,其值接近于2.22*10(-16方)
进制数定义:
- 二进制:
0b1010
- 八进制:
0o777
- 十进制:
100
- 十六进制:
0xff
- 二进制:
Number.isFinite
:检测一个数值是否为有限数Number.isNaN
:检测一个数值是否为 NaNNumber.parseInt/Float
:将字符串转为整数/浮点数Number.isInteger
:判断一个数是否为整数Math.trunc
:将数字的小数部分抹掉Math.sign
:判断一个数到底为整数、负数还是零
18.对象方法扩展
Object.is
:判断两个值是否完全相等Object.assign(oldObject, newObject)
:对象的合并,当旧对象中有新对象中没有的时候,会进行合并,否则会直接覆盖Object.setPrototypeOf
:设置原型对象(不推荐使用)Object.getPrototypeOf
:获取原型对象(不推荐使用)
19.模块化
是指将一个大的程序文件拆成许多小的文件,然后进行组合
优势:
- 防止命名冲突
- 代码复用
- 高维护性
模块化规范产品:
- CommonJS:NodeJS、Browserify
- AMD:requireJS
- CMD:seaJS
(1).暴露与引入
暴露模块内容的方法:
- 在每一个需要暴露的变量或方法前面都加一个
export
- 也可以暴露一个对象,将需要暴露的变量或方法都放入对象中
- 也可以使用
export default xxx
来进行默认暴露的设置
- 在每一个需要暴露的变量或方法前面都加一个
通过
<script>
标签来引入模块的方法:- 通用的引入:
import * as xxx from "./test.js"
- 解构赋值的引入,以下三个分别对应暴露模块的三种形式:
import {school} from "./test.js"
import {school as guigu} from "./test.js"
import {default as a} from "./test.js"
- 简便形式的引入,只针对于默认暴露的方法:
import b from "./test.js"
- 通用的引入:
通过
<script>
标签的 src 属性来引入:- 在 src 中引入某个js文件
- 然后在该 js 文件中直接使用上面语句进行引入
(2).babel代码转换
通过使用 babel 可以将 ES6语法转换为 ES5语法,方便不同浏览器的使用,官网点击这里
使用方法:
- 使用
npm init --yes
进行初始化 - 使用
npm i babel-cli babel-preset-env browserify -D
命令来安装相关的开发依赖,会安装babel-cli(命令行工具)、babel-preset-env(预设包,进行转换)、browserify(打包工具)这三个工具 - 使用
npx babel 原始路径 -d 新路径
命令来进行转换 - 使用
npm browserify 新路径下的配置文件 -o 新路径配置文件
命令来进行打包 - 网页中只要引用最后打包好的文件即可
- 使用