ECMAScript6
语法标准: 开发者 执行者(nodejs / 浏览器)
- hello world
- 安装nodejs
- 查看版本
node --version
- 第一个程序
- nodejs交互界面
- 编写代码,执行 node hello.js 二、 注释
三、 变量声明
弱类型
var 奇葩(其他语言)
1. 重复声明
var a;
var a;
2. 变量的提升
console.log(d);
var d;
3. 没有局部作用域
function foo(){
var result = 0;
for(var i=0;i<=100;i++){
result += i;
}
console.log(result)
console.log(i);
}
let
1. 不可重复声明
2. 不存在变量提升
3. 具有局部作用域
const
常量,只能赋值一次的变量,其他与let保持相同特性
let a = 3;
a++; // 4
const b = 3;
b++; //error
const obj = {age:1}
obj.age++; // age 2
四、 解构
使用模式匹配方式从一个对象、数组中快速获取值的方式
let obj = {
name:"terry",
age:12,
gender:"male",
telephone:"18812344321",
email:"licy@briup.com"
}
let a = obj.name;
let b = obj.age;
let c = obj.gender;
1. 对象解构
let {
name:name,
age:age
} = {
name:"terry",
age:12,
gender:"male",
telephone:"18812344321",
email:"licy@briup.com"
}
let {name,age,gender} = {name:"terry",age:12}
let {name,age,gender='男'} = {name:"terry",age:12}
let {toString} = 2;
let {push} = [1,2,3]
// 自动装箱 let n = new Number(2)
let n = 2;
toString.call(n) '2'
n.toString(); '2'
2. 数组解构
let [a,b,c] = ['terry','tom','jacky']
let [a,b,c,d] = ['terry','tom','jacky']
let [a,b,c,d='vicky'] = ['terry','tom','jacky']
五、 字符串拓展 String
1. 可迭代的对象
2. API拓展 lodash
1) 静态方法(声明在构造函数)
2) 实例(成员)方法(声明在原型对象中)
Number扩展
Number.isNaN
Number.isInfinite
Number.parsetInt
Number.parsetFloat
Number.isInteger
对象 Object
1. 对象简写
let name = "terry"
let obj = {name}
function foo(){}
let obj = {
name:"terry",
foo,
sayName(){
}
}
let url = "/article/deleteById"
let id = 1;
$.get(url,{id})
2. 扩展运算符
let {name,...other} = {name:"",a:"",b:""}
let p1 = { page: 2, pageSize: 10 }
let p2 = { title: '新冠'}
Object.assgin(p1,p2)
let param = {
page: 2,
pageSize: 10 ,
title: '新冠'
}
param = {
...param,
page:3
}
param = Object.assgin({},param)
监控param的改变?
param 参数
3. API
Object.is()
Object.assign()
Object.keys(obj) 键的数组
Object.values(obj) 值的数组
Object.entries(obj); 键值对组成的数组的数组
Object.setPrototypeOf(obj,prototype)
Object.getPrototypeOf(obj)
让类数组可以调用所有的数组方法?
六、 原型
每个函数都有一个原型对象与之对应,函数中有个指针
prototype指向这个原型,原型中有个指针constructor指向函数
一个函数的特性与其调用方式有关,如果通过new来调用,这个函数可以理解为构造函数;如果通过()、apply、call来调用,这个函数可以理解为普通函数
function Student(name,age){
this.name = name;
this.age = age;
}
new Number() 创建数值的实例对象
Number() 将其他数据类型转换为Number
let arr = new Array()
arr instanceof Object
七、数组 Array
静态
Array.from()
将类数组对象、set转换为数组
Array.of()
将参数放置到数组内并且返回
非静态
Array.prototype.keys
Array.prototype.values
Array.prototype.entries
Array.prototype.includes()
Array.prototype.flat(Infinity)
这三个方法返回值为迭代器对象
迭代器对象的调用:
1. for-of
2. iterator.next()
3. 拓展运算符
八、函数拓展
1) 默认值
2) rest参数
扩展运算符的逆运算
let arr = [1,2,3]
let n = [9,8,7,...arr]
let [a,...b] = [1,2,3,4,5]
function foo(a,...b){
console.log(a);
console.log(b);
}
九、 Promise 对异步操作进行封装。 状态:待定、成功、失败
1) 构造函数
let p = new Promise((resolve,reject)=>{
})
2) 静态方法
Promise.xxx
3) 实例方法
Promise.prototype.xxx
ajax
GET /carousel/findAll HTTP/1.1
Authorization:XXWEREAWFEWAFAEW
十、 Symbol
函数,无法使用new来调用,每次执行都可以产生式一个唯一的值(基本数据类型),这个值用来作为属性名。
let s1 = Symbol()
let s2 = "name"
let obj = {
[s1]:"terry", // 神秘的唯一值:"terry"
[s2]:"tom" , // name:"terry"
s3:"jacky" // s3 :"jacky"
}
obj[s1]
obj.name
obj.s3
1. Symbol() 函数
用来产生唯一值
2. Symbol(flag)
flag字符串,表示标识
3. Symbol.for(flag)
4. Object.getOwnPropertySymbols()
可以获取某个对象中所有的symbol属性名
5. 系统内置Symbol
1) Symbol.hasInstance
所有的构造函数都内置这么个方法,当instanceof的时候会调用
let obj = {
[ Symbol.hasInstance]:function(o){
return false
}
}
let o = {}
{} instanceof obj;
2) Symbol.iterator
当迭代对象的时候会被调用 for-of
for(let o of arr){}
十一、 集合
是对数组和对象的拓展
1. Set
不可以存放相同的值,不可以通过索引来访问。Set是一种特殊的map
let arr = [1,2,3,4,5,1,2,3]
let arr = ['terry','larry']
1) 构造函数
new Set()
2) 原型
Set.prototype.size
Set.prototype.add()
Set.prototype.delete()
Set.prototype.clear()
Set.prototype.keys()
Set.prototype.values()
Set.prototype.entries()
Set.prototype.forEach()
2. Map
键值对,键可以为任意数据类型;
Map可以提供额外的api
购物车(家政)
goods
id name price
fbm = {1 北京方便面 2}
kqs = {2 怡宝矿泉水 2.5}
let shopcar = new Map();
shopcar.set(1,1)
shopcar.set(2,3)
如何将一个对象转换为map?
1) 构造函数
let map = new Map([[],[]])
2) 原型方法
十二、 代理
1. 对象 setter/getter
let obj = {} // 目标对象
let proxy = new Proxy(obj, { // 代理
set(target,key,val){
target[key] = val;
},
get(target,key){
return target[key]
}
})
proxy.name = 'terry' // 面向代理使用
2. 函数 apply
let foo = function(msg){console.log(msg);}
let proxy = new Proxy(foo, {
apply(target,that,args){
target.apply(that,args)
}
})
3. 构造函数 constructor
let Person = function(name){this.name = name}
let proxy = new Proxy(Person,{
constructor(target,args){
return new target(...args)
}
})
十三、 反射
与代理一一对应,为代理提供操作方法:操作set/操作get/操作apply/操作contructor
let proxy = new Proxy(obj, { // 代理
set(target,key,val){
Reflect.set(target,key,val)
},
get(target,key){
return Reflect.get(target,key)
}
})
...
十四、 Promise
1. axios
异步操作的解决方案,常用于封装ajax
axios就是基于Promise对Ajax的封装
0) 特点
XMLHttpRequests(浏览器) 、http(nodejs)
默认将data(post)转换为json
params(get)
支持Promise
1) nodejs中应用(http)
安装cnpm
$ npm install cnpm -g --registry=https://registry.npm.taobao.org
$ npm init
$ cnpm install axios --save
2) 实例化
axios
配置属性
{
method
url
params
data
}
3) 全局配置
4) 拦截器
5) 快捷方法
2. 原生ajax的封装
function loadArticles(){
// 待定
return new Promise((resolve,reject)=>{
let xhr = new XMLHttpRequest()
xhr.open()
xhr.setRequestHeader()
xhr.send()
xhr.onreadystatechange = function(){
if(this.readyState === 4){
if(this.status === 200){
// 待定-> 成功 (执行then中的回调)
resolve(this.response);
} else {
// 待定 -> 失败(执行catch中的回调)
reject(this.response);
}
}
}
})
}
loadArticles().then().catch().finally()
3. 成员方法
then/catch/finally 返回值都是一个承诺对象
Promise.prototype.then(successHandler[,errorHandler])
Promise.prototype.catch(errorHandler)
等价于
Promise.prototype.then(null,errorHandler)
Promise.prototype.finally(handler)
4. 静态方法
Promise.all([p1,p2,...])
该方法返回值为promise,当p1,p2,...全部执行完毕并且状态resolved的时候,promise的then才会被调用,该then的回调函数的参数是p1,p2,...的运行结果
案例:当查询完所有的班级,渠道后在调用查询学生的接口;查询学生的时候默认查询第一个班级
Promise.all(p1,p2).then((result)=>{
let defaultClazz = result[0].data.data[0]
loadStudent();
})
Promise.race(iterable)
返回值为promise,返回率先改变状态的promise结果
Promise.allSettled(iterable)
返回值为promise,与all不同,当所有的承诺对象状态被确认的时候会执行promise的then,then的参数为结果
Promise.resolve(val)
直接返回一个承诺对象,并且状态为成功
new Promise(resolve => {
resolve(val);
})
Promise.reject(error)
直接返回一个承诺对象,并且状态为失败
new Promise((resolve,reject) => {
reject(error);
})
iterable 可迭代的对象,常见的是数组或set...,可迭代对象中的元素是promise实例
十五、 迭代器
0. 执行过程
next() 调用 -> 指针
1. ES6可迭代的对象
数组、字符串、set、map
实例对象可以直接访问Symbol.iterator,构造函数实现了Symbol.iterator接口
// 标准
inteface Iterator {
[Symbol.iterator]():void;
}
// 类 == 构造函数 Array String Set Map
class Array implements Iterator{
[Symbol.iterator]():void{
}
}
let arr = [1,2,3]
arr[Symbol.iterator]()
for(let a of arr){}
2. 触发迭代器执行的场景
...
for-of
new Set()/new Map()
Array.from()
Promise.all()
Promise.race()
十六、 generator函数
1. 迭代器函数本质上就是一个generator函数
手动实现一个类数组构造函数,并且该构造函数实现了Symbol.iterator接口
function* foo(){
yield 'terry';
yield 'larry';
yield 'tom';
}
2. next参数
next参数可以作为上⼀个yield表达式的返回值
let iterator = foo()
iterator.next(1)
十七、 异步函数
async function foo(){
await axios.get(url1)
await axios.get(url2)
}
foo()
十八、 面向对象
是ES5语法糖
1. 构造函数
function Animal(name,age){
this.name = name;
this.age = age;
}
let animal = new Animal('terry',12);
-------------------------------------
class Animal {
constructor(name,age){
this.name = name;
this.age = age;
}
}
let animal = new Animal('terry',12);
语法:
class 为关键字
Animal 为类名,类名首字母大写,采用驼峰命名
{} 为类体,其中可以包含:
构造函数、
成员属性、
成员方法、
静态方法、
静态属性、
静态代码块(node16才支持)
2. 实例对象
通过构造函数创建的对象
plain object 纯对象({},new Object())
3. 原型方法 - 成员方法/实例方法
class Animal {
name; // 成员自身中
sayName(){ // 原型
}
sayAge(){
}
}
4. 构造函数方法 - 静态方法
class Animal {
sayAge(){
}
static foo(){ // 类,通过类名直接调用
}
}
5. 继承
原型链继承:子构造函数的原型指向父构造函数的实例
借用构造函数:
` function Dog (name,age,gender){ Animal.call(this,name,age) this.gender = gender; } Dog.prototype = new Animal(); Dog.prototype.constructor = Dog; Dog.prototype.xxx 实例方法 Dog.xxx 构造函数方法 --------------------------- class Dog extends Animal{ constructor(name,age,gender){ super(name,age) this.gender = gender; } sayGender(){
}
}
十九、 模块化
任何一个js文件或者是目录都可以认为是一个模块,如果目录作为一个模块,那么,目录中应该出现package.json
$ npm init -y
$ npm install qs --save
连接互联网,获取qs库?中央仓库 ,下载当前目录的node_modules
--save 本地安装并且将其安装信息写入到package.json中 dependencies
CommonJS 模块化 社区提供的 1. 模块的暴露 模块内部的变量其他模块是无法访问,如果想要其他模块进行访问,需要进行接口的暴露 module.exports
module是一个对象,每个模块都拥有这个对象,exports属性是用于将当前目录信息传递到其他模块,其默认值是一个空对象
module.exports.xxx
或者
module.exports = {}
2. 模块引用
require(模块)
1. 当模块为自定义模块的时候,参数为文件路径
require('./a.js')
2. 当模块为内置模块的时候,参数为模块名称
require('http')
3. 当模块为第三方模块的时候,参数为模块名称,但是需要先进行模块的安装
$ cnpm install axios --save
require('axios');
模块引入本质的就是获取被引入模块中的module.exports属性。
ES6 模块化 官方提供的 如果想要让nodejs支持es6模块化:node版本v14+ , package.json添加一个配置项 type:"module"
模块暴露:
export 声明
多次使用,使用哪个变量暴露,就要使用哪个变量获取
export default
尽可使用一次,可以使用任意变量名来获取
一个模块中可以既使用export又使用export default
模块导入
import aa from './a.js