目录
class类
- constructor():构造函数,
new命令
生成实例时自动调用 - extends:继承父类
- super:新建父类的
this
- static:定义静态属性方法
- get:取值函数,拦截属性的取值行为
- set:存值函数,拦截属性的存值行为
私有属性方法
const name = Symbol("name");
const print = Symbol("print");
class Person {
constructor(age) {
this[name] = "Bruce";
this.age = age;
}
[print]() {
console.log(`${this[name]} is ${this.age} years old`);
}
}
继承混合类
function CopyProperties(target, source) {
for (const key of Reflect.ownKeys(source)) {
if (key !== "constructor" && key !== "prototype" && key !== "name") {
const desc = Object.getOwnPropertyDescriptor(source, key);
Object.defineProperty(target, key, desc);
}
}
}
function MixClass(...mixins) {
class Mix {
constructor() {
for (const mixin of mixins) {
CopyProperties(this, new mixin());
}
}
}
for (const mixin of mixins) {
CopyProperties(Mix, mixin);
CopyProperties(Mix.prototype, mixin.prototype);
}
return Mix;
}
class Student extends MixClass(Person, Kid) {}
Module
- export:规定模块对外接口
- 默认导出:
export default Person
(导入时可指定模块任意名称,无需知晓内部真实名称) - 单独导出:
export const name = "Bruce"
- 按需导出:
export { age, name, sex }
- 改名导出:
export { name as newName }
- 默认导出:
- import:导入模块内部功能
- 默认导入:
import Person from "person"
- 整体导入:
import * as Person from "person"
- 按需导入:
import { age, name, sex } from "person"
- 改名导入:
import { name as newName } from "person"
- 自执导入:
import "person"
- 复合导入:
import Person, { name } from "person"
- 默认导入:
模块方案
- CommonJS:用于服务器(动态化依赖)
- AMD:用于浏览器(动态化依赖)
- CMD:用于浏览器(动态化依赖)
- UMD:用于浏览器和服务器(动态化依赖)
- ESM:用于浏览器和服务器(静态化依赖)
加载实现
- 传统加载:通过
<script>
进行同步或异步加载脚本- 同步加载:
<script src=""></script>
- Defer异步加载:
<script src="" defer></script>
(顺序加载,渲染完再执行) - Async异步加载:
<script src="" async></script>
(乱序加载,下载完就执行)
- 同步加载:
- 模块加载:
<script type="module" src=""></script>
(默认是Defer异步加载)
promise
- 定义:包含异步操作结果的对象
- 状态
- 进行中:
pending
- 已成功:
resolved
- 已失败:
rejected
- 进行中:
- 特点
- 对象的状态不受外界影响
- 一旦状态改变就不会再变,任何时候都可得到这个结果
- 声明:
new Promise((resolve, reject) => {})
- 出参
- resolve:将状态从
未完成
变为成功
,在异步操作成功时调用,并将异步操作的结果作为参数传递出去 - reject:将状态从
未完成
变为失败
,在异步操作失败时调用,并将异步操作的错误作为参数传递出去
- resolve:将状态从
- 方法
- then():分别指定
resolved状态
和rejected状态
的回调函数- 第一参数:状态变为
resolved
时调用 - 第二参数:状态变为
rejected
时调用(可选)
- 第一参数:状态变为
- catch():指定发生错误时的回调函数
-
let p = new Promise(function(resolve, reject) { // 封装异步操作,传入成功时执行的resolve函数和失败执行的reject函数 $.ajax({ url: "https://xxx", success(data) { resolve("success", data); // 成功的话执行resolve函数,并传入一个状态和对应的数据,在后面then的时候调用 }, error(data) { reject("error", data); // 失败执行reject函数,在后面catch的时候调用 } }); }); // 在这里进行异步操作的回调处理 p.then(function(status, data) { // 成功时的回调函数,相当于此时执行resolve方法 console.log(status, ":", data); }).catch(function(status, data) { // 失败时的回调函数,相当于此时执行reject方法 console.log(status, ":", data); });
- Promise.all():将多个实例包装成一个新实例,返回全部实例状态变更后的结果数组(齐变更再返回)
- 入参:具有
Iterator接口
的数据结构 - 成功:只有全部实例状态变成
fulfilled
,最终状态才会变成fulfilled
- 失败:其中一个实例状态变成
rejected
,最终状态就会变成rejected
- 入参:具有
-
new Promise.all([ // 传入一个包含多个异步操作的数组 $.ajax({ url: "https://xxx", dataType: "json"}), $.ajax({ url: "https://yyy", dataType: "json"}), $.ajax({ url: "https://zzz", dataType: "json"}), ]).then( // 通过then方法调用后续操作,分别传入一个成功和失败的处理方法 ([data1, data2, data3]) => { // 返回的数组分别是data1,data2,data3,通过结构方式接受 console.log(data1, data2, data3); }, res => { console.log("失败"); })
- Promise.race():将多个实例包装成一个新实例,返回全部实例状态优先变更后的结果(先变更先返回)
- 入参:具有
Iterator接口
的数据结构 - 成功失败:哪个实例率先改变状态就返回哪个实例的状态
- 入参:具有
-
Promise.race([ $.ajax({ url: "https://xxx", dataType: "json"}), $.ajax({ url: "https://yyy", dataType: "json"}), $.ajax({ url: "https://zzz", dataType: "json"}), ]).then( (data) => { // 只对第一个完成的操作进行回调 console.log(data); }, res => { console.log("失败"); })
- Promise.resolve():将对象转为Promise对象(等价于
new Promise(resolve => resolve())
)- Promise实例:原封不动地返回入参
- Thenable对象:将此对象转为Promise对象并返回(Thenable为包含
then()
的对象,执行then()
相当于执行此对象的then()
) - 不具有then()的对象:将此对象转为Promise对象并返回,状态为
resolved
- 不带参数:返回Promise对象,状态为
resolved
- Promise.reject():将对象转为状态为
rejected
的Promise对象(等价于new Promise((resolve, reject) => reject())
)
- then():分别指定
Async
- 声明
- 具名函数:
async function Func() {}
- 函数表达式:
const func = async function() {}
- 箭头函数:
const func = async() => {}
- 对象方法:
const obj = { async func() {} }
- 类方法:
class Cla { async Func() {} }
- 具名函数:
- await命令:等待当前Promise对象状态变更完毕
- 正常情况:后面是Promise对象则返回其结果,否则返回对应的值
- 后随
Thenable对象
:将其等同于Promise对象返回其结果
-
async function aaa() { console.log(0); let x = await $.ajax({ url: "https://xxx", dataType: "json" }, function(data) { console.log(data); }) // x接收异步操作返回的数据 // 由于这里使用了await等待,所以在该步会等待异步操作执行 // 如果异步操作失败成功则执行后续步骤,否则不会进行后面的操作 console.log(1); let y = await $.ajax({ url: "https://yyy", dataType: "json" }, function(data) { console.log(data); }) console.log(2); let z = await $.ajax({ url: "https://zzz", dataType: "json" }, function(data) { console.log(data); }) console.log(3); }
- 错误处理:将
await命令Promise对象
放到try-catch
中(可放多个) -
async function aaa() { console.log(0); try{ let x = await $.ajax({ url: "https://xxx", dataType: "json" }, function(data) { console.log(data); }) console.log(x); } catch(e) { // 捕捉失败的请求 console.log(e); } }
重点难点
Async函数
返回Promise对象
,可使用then()
添加回调函数-
function ajax() { // 封装成Promise对象 return new Promise((resolve, reject) => $.ajax({ url: "https://xxx", dataType: "json", success(data) { // then里调用 resolve(data); }, error(e) { // 失败时catch捕捉 reject(e); } }) ); } async function aaa() { console.log(0); let x = await ajax().then(data => data).catch(e => false); // 异步成功则只执行then,返回data,失败则捕捉并返回false console.log(x); }
- 内部
return返回值
会成为后续then()
的出参 - 内部抛出错误会导致返回的Promise对象变为
rejected状态
,被catch()
接收到 - 返回的Promise对象必须等到内部所有
await命令Promise对象
执行完才会发生状态改变,除非遇到return语句
或抛出错误
- 任何一个
await命令Promise对象
变为rejected状态
,整个Async函数
都会中断执行 - 希望即使前一个异步操作失败也不要中断后面的异步操作
- 将
await命令Promise对象
放到try-catch
中 await命令Promise对象
跟一个catch()
- 将
await命令Promise对象
可能变为rejected状态
,最好把其放到try-catch
中- 多个
await命令Promise对象
若不存在继发关系,最好让它们同时触发 await命令
只能用在Async函数
之中,否则会报错- 数组使用
forEach()
执行async/await
会失效,可使用for-of
和Promise.all()
代替 - 可保留运行堆栈,函数上下文随着
Async函数
的执行而存在,执行完成就消失
箭头函数
1.没有自己的this
,导致内部的this
就是外层代码块的this
2.
因为没有this
,因此不能用作构造函数
a = {
name: "aaa",
fn: function() {
console.log(this, this.name + "bbb")
// 使用function定义的this会绑定到当前对象,因此输出为当前对象a和"aaabbb"
},
fn1: () => {
console.log(this, this.name + "bbb")
// 箭头函数使得this绑定在window对象,因此输出为window对象和"bbb"
}
}
a.fn()
a.fn1()
let和const
const:声明常量,必须立即赋值
let:声明变量
特点:
- 不允许重复声明
- 未定义就使用会报错:
const命令
和let命令
不存在变量提升 - 暂时性死区:在代码块内使用
const命令
和let命令
声明变量之前,该变量都不可用
字符串方法
includes:判断字符串是否存在于其中
"abc".includes('a')
// true
"abc".includes('d')
// false
startsWith:判断字符串是否以其开头,endsWith:结尾
"abc".startsWith('a')
// true
"abc".startsWith('b')
// false
repeat:将字符串复制成原来的几倍
"abc".repeat(3)
// "abcabcabc"
数组方法
for of:遍历数组
a = [1,2,3,4,5]
a.forEach((item, index) => {console.log(item, index)})
// 循环输出:1 0、2 1、...
forEach:遍历数组(使用throw中断循环)
var arr = ['a','b','c','d'];
for(var item of arr){
console.log(item);
}
//输出a,b,c,d
map:对数组数据进行统一操作
a = [1,2,3,4,5]
a.map(function(item){return item>=3})
// 统一操作判断每个数据是否大于等于3,[false, false, true, true, true]
// 由于上面的函数符合一个参数,且只有一条return语句,因此可以简写如下:
// 简写后:a.map(item=>item>=3)
// 这里容易看混掉的是第一个=>是代表箭头函数,第二个=>代表大于等于运算符
a.map(function(item, index){return [item, index]})
// [[1,0],[2,1],[3,2],[4,3],[5,4]]
reduce:对整个数组进行循环某运算,其下有三个参数为:tmp
/item
/index
,分别代表上一次操作返回的结果(第一次默认为数组的第一个数)、下一个传入的值(即数据的下一个数)、循环的索引
a = [1,2,3,4,5]
a.reduce(function(tmp, item, index) {
console.log(tmp, item);
return tmp + item;
// 返回结果为当前数和下一个数的求和
})
// 最后的结果为15
filter:根据条件过滤数据
a = [1,2,3,4,5]
a.filter(item => item%2==0)
// 返回所有偶数,结果为[2, 4]
some:循环判断数组中是否存在满足条件的数据,只要有一个满足就返回true
a = [1,2,3,4,5]
a.some(item=>item>=3)
// 有大于等于3的数,返回true
every:循环判断数组中是否全部满足条件,是则返回true
a = [1,2,3,4,5]
a.every(item=>item>=3)
// 有不大于等于3的数,返回false
对象方法
for in:遍历对象数组的键值
var obj={
name:'abc',
age:13
}
for(var key in arr){
console.log(key+': '+arr[key]);
}
//name: abc
age: 13
Object.keys():将对象的所有键以数组形式输出
o = {a:1, b:2, c:3}
Object.keys(o)
// ["a", "b", "c"]
Object.values():将对象的所有值以数组形式输出
o = {a:1, b:2, c:3}
Object.values(o)
// [1, 2, 3]
Object.entries():将对象的所有键和值以数组形式输出,数组中的子元素是长为2的数字,分别为键和值
o = {a:1, b:2, c:3}
Object.entries(o)
// [Array(2), Array(2), Array(2)]
Object.entries(o)[0]
// ["a", 1]
Object.assign():合并对象(浅拷贝),返回原对象
Object.is():对比两值是否相等
...操作符
1.将数组展开传入
function test(a, b, c) {
console.log(a + b + c);
}
test(...[1, 2, 3])
// 将数组展开成1, 2, 3赋值给a, b, c
2.数组拼接
a = [1,2,3]
b = [4,5,6]
[...a, ...b]
// [1, 2, 3, 4, 5, 6]
3.对象拼接
a = {name: 111, pwd: 222}
{...a, b:1}
// 通过对象{b: 1}存放...a,结果为:{name: 111, pwd: 222, b: 1}
Set
成员值都是唯一且没有重复的值
- 去重字符串:
[...new Set(str)].join("")
- 去重数组:
[...new Set(arr)]
或Array.from(new Set(arr))
- 集合数组
- 声明:
const a = new Set(arr1)
、const b = new Set(arr2)
- 并集:
new Set([...a, ...b])
- 交集:
new Set([...a].filter(v => b.has(v)))
- 差集:
new Set([...a].filter(v => !b.has(v)))
- 声明:
- 映射集合
- 声明:
let set = new Set(arr)
- 映射:
set = new Set([...set].map(v => v * 2))
或set = new Set(Array.from(set, v => v * 2))
- 声明:
参考:掘金