ES6基础

ES6的特点

模块化

初始化项目 : npm init 选项可全部回车
初始化后,会生成package.json文件,里面存放了第三方包
快速初始化项目 : npm i -y   表示全部的选项都是yes

package.json文件

devDependencies

在产品阶段使用的包

Dependencies

在开发阶段使用的包

安装第三方包的工具,包管理工具/机制

npm
国外的包管理工具 服务器部署在外网 下载速度会比较慢,但包比较全,
不会加载缓存,直接重新下载依赖
cnpm
国内的包管理工具,服务器部署在国内 下载速度比较快
不会加载缓存,直接重新下载依赖
安装
 npm config set registry https://registry.npmmirror.com/
 npm install -g cnpm --registry=https://registry.npmmirror.com
 // 项目中配置映射修改规则
npm.taobao.org => npmmirror.com
registry.npm.taobao.org => registry.npmmirror.com
yarn
会先加载缓存查看是否存在,不存在再继续下载。
安装
npm install -g yarn --registry=https://registry.npmmirror.com
yarn -v 查看版本号
全局安装与局部安装
npm install -g 包名
npm install --save 包名

模块化规范

模块化的导出

列表导出
格式:
	ES6:   export { 导出的第一个变量,导出的第二个变量 }
	ES5:  exports { 导出的第一个变量名: 变量值,导出的第二个变量名: 变量值 }
重命名导出
格式:
	export { 导入的变量名 as 要重名为的名字}
默认导出
格式:
	export default {
		导出的名字:导出的值
}

模块化的导入

列表导入
ES6:
	格式:
		import {导出的变量名,导出的第二个变量名} from '导入文件的路径'
	直接使用 导出的变量名,就直接可以使用我们导出的变量
ES5:
	格式:
		let 模块名 = require('模块路径')
		模块名.导出的变量名
重命名导入
格式:
	import {导出的变量名 as 重命名} from '导入文件的路径'
默认导入
格式 : import 自定义的名字 from ’导入的模块路径‘
全部引入
import  * as 自定义命名  from '路径'

CommonJs模块规范(是node的一个规范)

导出:
	module.exports = {变量,变量}
	或
	module.exports.变量 = xxx;
导入:
	let mokuai = require('路径');
	mokuai.变量;
	导入第三方包:
		let lodash = require('包名') // 注意,首先保证该包已npm下载
或 
	let {变量,变量}= require('路径');
特点:
运行时,导出的是一个值的赋值,即是浅拷贝,与es6的不同,es6输出的是一个值得引用,即在导出后,再对模块里的数据进行修改,那么引入的值也会被修改。
例:
	导出模块
	export let name = ’zhangsan‘;
	setTimeout = (()=> name = 'lisi',2000);
	导入模块
	import name from ’/path‘,//name 两秒后变成lisi 
commentjs在运行时才会加载模块,ES6在编译时就会加载我们的模块

ES6 与 CommonJs 的区别

1. commonJS 导出的值为浅拷贝 , ES6为深拷贝,即值得引用
2. commonJS在运行时加载模块,ES6在编译时加载模块

第三方包

babel-cli 转码工具

当某些浏览器不支持高版本的es语法时或低版本的node不支持时,需要转码
安装
指令 
	npm install -g babel-cli // 全局安装
	局部安装 cnpm install --save-dev babel-cli babel-preset-latest
		--save为局部开发环境安装  
		-dev为上线环境安装  
		babel-preset-latest 预设
测试安装 : babel --version
使用

注意使用前需要局部安装 :
cnpm install --save-dev babel-cli babel-preset-latest
在文件夹根目录下创建文件 .babelrc
设置文件
{
“presets”: [“latest”]
}
最后在控制台 : babel xxx.js 即可成功转换该js文件

将转码后的文件输出给另一个文件
babel xxx.js --out-file 要输出的文件名.js
将当前文件夹全部的js文件 转码到另一个文件夹里面
babel 当前要转换的文件夹名 --out-dir 要转换到的另一个文件夹名字

箭头函数

没有this指向,this指向的是声明箭头函数时外部的作用域

案例

1.

let name = 'zhangsan'
sayName=()=>{
	console.log(this.name); //undefined
}

注意!! 该this指向的是一个外部作用域,以上案例即当前模块module,如果moudule为一个空对象,那么就是undefined。默认情况下,指向的 module.exports,注意默认情况下 exports与module.exports指向的是同一个对象。

实参数组 rest

用rest来保存形式参数,当没有形式参数来接受实际参数时,那么传过来的实际参数都被保存在rest里面,如:
let test = (a,...b)=>{}
test(1,2,3,4)    
以上rest里面的保存的是...b ,a将不会被保存

普通函数与箭头函数的区别

1.this 指向的问题
2. 普通函数是用arguments保存实际参数,箭头函数rest参数保存的实际参数
3.

es7新增属性

指数函数

格式 :输出几次幂
	2**3 :输出2的三次幂

includes

includes(NaN)   能查找NaN  

变量

ES5 var

特点 变量提升 可以重复声明,不具有块级作用域

let

特点: 不会变量提升,不可以重复声明,有块级作用域

const 常量声明

特点:不会变量提升,不可以重复声明,有块级作用域,
且是一个常量,在声明的时候就要被赋值,否则会报错。 不被更改值

解构

等号两侧的模式完全相同时才能完成解构

数组解构

完全解构

只有左右侧的数据类型相同,且模式完全相同时才能完成解构
例:
let [a,b,c,d,e] = [1,2,3,5]   // 不是完全解构,因为元素的个数不一样
let [a,b,c,d] = [1,2,[3,4],5] // 则a=1,b=2,c=[3,4],d=5

不完全解构

不符合完全解构时,就是不完全解构

默认值解构

当右侧匹配严格模式为undefinded时 默认值才会生效,默认值则是在左边的默认等于值
例:
let [a=test()] = [], //a = test();
let [a=test()] = [1] //a=1;

集合解构 拓展运算符 …

即是三点运算符
let [a,...b] = [1,2,3,4,5] //a = 1,b =[2,3,4,5]

对象解构

属性名与变量名一致

注意!!要求属性名与变量名要一致
let {name,age} = {name:'zhangsan',age:12}

重命名解构

格式
let {name:a,age:b} = {name:'zhangsan',age:1] // name重命名为a,age重命名为b

嵌套解构

例:
	let obj = {p:['hello',{y:'word'}]};
	let {p:[a,{y:b}]} = obj // a=hello,b = word

字符串解构

利用数组来进行字符串解构

let [...arr] = 'hello' // arr = ['h','e','l','l','o']

利用对象解构字符串

拓展运算符 …

在拓展运算符中,用在左侧是聚合,用在右侧是展开
例:
	let arr=[1,2,3]
	let [...a] = arr; //a = [1,2,3];
	let obj = {name:'zhangsan',age:12};
	let obj1 = {gender:'man'};
	let temp = [...obj,...obj1]; // temp={name:'zhangsan',age:12,gender:'man'};

函数参数

函数的长度只与其形参的个数有关,形参的个数是多少,长度就是多少,当函数的形参中有一个默认赋值,那么后面的所有形参的都默认为为参数,伪参数不计入长度
例:
function test(a,b,c){}
test.length === 3
test(a,b=2,c,d) ;
test.length===1

API

对象新增静态方法

is 比较两个数是否相等,返回true或者false

格式:
	Object.is(+0,-0) //false
	Object.is(NaN,NaN); //ture

assign

复制(两个参数),是半深拷贝
格式:
	Object.assign(要复制成的目标对象,被复制的对象)
	Object.assign(obj,obj1) // 把obj1的内容复制给obj, 并返回obj
	注意,深拷贝的实现是被拷贝的对象中没有引用数据类型。如果没有引用数据类型实现的就是深拷贝,否则是浅拷贝。
合并对象(三个参数)
格式:
	Object.assign(合并成的目标对象,要合并的对象1,要合并的对象2)
	Object.assign(obj,obj1,obj2) //将obj1与obj2合并到obj ,并返回obj

获取原型对象的方法 .getPrototypeOf(obj)

设置原型对象方法 .setPrototype(obj,obj1)

Object.setPrototype(obj,obj1) //将obj的原型设置成obj1

keys 返回键组成的数组

默认对象是不能给for of 遍历的。
格式:Object.keys(obj),返回的是一个迭代器对象

values 返回的值组成的数组

返回的是一个迭代器对象

entries 返回键值对组成的数组

返回的是一个迭代器对象

fromEntries()用于把键值对还原成对象结构。

getPropertySymbols()获取symbol值

数组新增API

Array.prototype.find 返回第一个满足条件的元素或者undefined 参数回调函数

Array.prototype.find((item,index,arr)=>{}) find方法返回第一个满足条件的元素或者undefined 参数回调函数
let arr=[1,2,3,2,3];
 let result=arr.find((item)=>{
    return item>2
})
console.log(result) // 3

Array.prototype.findIndex() 返回第一个满足条件的元素的索引或者-1,参数是回调函数

例:
let arr=[1,2,3,2,3];
let result=arr.findIndex((item)=>{
    return item>2
})   // 返回的是2

Array.prototype.includes(); includes是否包含某个元素,返回true/false

Array.prototype.fill() 用来填充数组,修改原数组

.flat(展开的层级数) 用于数组嵌套数组时展开数组

例:
[1, 2, [3, 4]].flat();           // [ 1, 2, 3, 4 ]

.flatMap()

是 .map() 与 .flat()的组合 ,通过对map调整后的数据尝试展平操作。
例:
[1, 2, [3, 4]].flatMap(v => {
	if (typeof v === 'number') {
		 return v * 2
	 } else {
		 return v.map(v => v * 2)
 		}
})
// [2, 4, 6, 8]

String原型对象API

去除前后空格String.prototype.trimStart()/String.prototype.trimEnd()
格式:str.trimStart() //去除前空格
	str.trimEnd()  //去除后空格
头尾添加字符串String.prototype.padStart() / String.prototype.padEnd()
格式:str.padStart('要添加的字符串') //在头添加字符串
str.padEnd('要添加的字符串') //在尾添加字符串
Function.prototype.toString()
返回注释、空格和语法详细信息。
replaceAll 全部替换

类 class

注意在es6中没有原型的概念,类可以看成是构造函数的另一种写法,使用class关键字声明

类的声明

格式: constructor必须声明
	class Person {
		constructor(name) {
 	 		this.name = name
 		}
 		sayname(){}
 		static personAtrr = '静态属性'
 		static sayhi(){}  //静态方法
}
 constructor必须声明,里面写的是实例属性,如果没有显示声明,那么会初始化成一个空对象
 方法sayname() 类似于存在原型中,每个实例都可以调用。
 静态属性/方法,只能由类本身(例Person)的去调用,用static声明
 在类体里面的引用数据类型是实例私有的,基本数据类型是公有的。

类的使用

格式:
	let person =new Person('name')

继承

使用extends关键字进行继承

使用格式

class Animal{}
class dog extends Animal{
}

注意点

1.子类能调用父类的静态方法,
2.在继承中,先在子类的类体里面查找,再去父类的类体里面查找
3.子类能继承父类类体的所有方法
4.子类要继承父类的构造器的话,要提供constructor,且再里面使用super进行传递父类的constructor的参数,类似于借用父类的构造器
5.子类的对象通过__proto__指针指向父类的对象,子类的原型对象继承父类的原型对象

ES5与ES6的继承区别

ES5 : 
子类原型对象继承父类的原型对象
Dog.prototype.__proto__ = Animal.prototype
子类继承父类
	Dog.__proto__=Animal

symbol

是一个基本数据类型,表示一个独一无二的值,

作用

1.解决命名冲突
2.消除魔术字符串,即在多模块多次被重复使用相同的字符串
魔术字符串
消除魔术字符串,即在多模块多次被重复使用相同的字符串。
即在某一个模块中,这个字符串被修改之后,另外一个模块的对应字符串也要被修改才能正常使用,那么该字符串就是一个魔术字符串。
为解决这个问题可以使用symbol变量,为这个变量使用描述,即可便于以后的维护

使用格式

普通声明
let  sy1=Symbol('hello');  // hello为该变量的描述,即使描述是一样的,二者的值不相同
let  sy2=Symbol();
类似是key与value的关系
在对象里面使用
et obj={
name:"zhangsan",
age:12,
[sy1]:'myname',
[sy2]:'myage',
[Symbol('email')]:'kangjie@briup.com'
全局注册
当创建一个symbol变量时,使用该Symbol.for() 注册方法,可以使每次声明的变量时,就从全局注册表中查找该值,而不是重新创建一个值
使用格式
// 将symbol放到全局注册表中
let sy1=Symbol.for('hello');
// 从全局注册表中找到该key对应的value
let sy2=Symbol.for('hello');
keyFor() 检查给定的 key 是否已经在注册表中 ,
假如是,则会直接返回上次存储的那个。否则,它会再新建一个。
格式:
let sy1=Symbol.for('hello');
Symbol.keyFor(sy1) //hello

特点

1.forin循环访问不到我们的symbol值
2.获取symbol值要使用getPropertySymbols
3.当symbol值作为对象的属性名时,使用中括号 例:[sy3]:"myname"

迭代器 (Iterator)

迭代器是一种机制,一种接口,实现这种接口,就能使用for of 循环遍历
当数组调用keys() , values() , entries() 方法时,返回的是一个迭代器对象
当实现了迭代器接口后,才能使用for of循环进行遍历

for of遍历

与for in 的遍历不同的是,例字符串遍历中 for of 拿到的是一个对象值,而for in 是一个下标

实际原理

本质上调用迭代器对象的是next() 方法,把迭代器对象理解成一个指针,每调用一个next() 方法,得到的是一个解构的第一个成员,一直循环往复,直至所有解构的成员循环完毕
迭代器的 next() 指针
next指针存储着两个值 value盒done,value指向解构成员的值,done为false时表示不是最后一个成员,为true时表示时最后一个成员

keys ,values , entries 方法

当数组直接使用以上三种方法时,返回的是一个迭代器对象,把调用该方法返回值用来调用for of 才能实现真正的遍历。
例如 :第一次调用 .key.next() 得到的是一个下标成员

迭代器对象

实现某种迭代器接口的数据结构,只要实现了迭代器接口,那么就可以使用for of 方法
迭代器对象要遍历才能出我们想要的值

迭代器的作用

一是为各种数据结构,提供一个统一的、简便的访问接口;
二是使得数据结构的成员能够按某种次序排列;
三是ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费。

set 集合

类似一个数组,但成员的值是唯一的,没有重复的值。但引用数据类型可以重复,因为引用数据类型的地址不一样

set API

声明

var set = new Set()

添加成员 set.add(‘要添加的值’)

长度 set.size

删除 set.delete(‘要删除的值’)

注意,删除的时候引用数据类型要使用地址进行删除,否则无法删除引用数据类型
例:
temp = [1];
set.delete(temp)

遍历 set.forEach(),keys(),values(),entries()

清空全部set成员 set.clear()

作用

1.数组去重
2.存储值,因为成员是唯一的,不会重复的

map

类似一个对象,也是键值对的集合 ,但‘键’ 的范围不仅限于字符串,可以是各种类型的值 

表现形式

{‘name’=> 'lisi' , 'age'=>12 }

map API

删除 map.delete(‘键值’)

注意,删除的时候引用数据类型要使用地址进行删除,否则无法删除引用数据类型
	例:
	temp = [1];
	set.delete(temp)

map于obj的区别

MapObject
意外的键Map 默认情况不包含任何键。只包含显式插入的键。一个 Object 有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
键的类型一个 Map的键可以是任意值,包括函数、对象或任意基本类型。一个Object 的键必须是一个 String 或是Symbol。
键的顺序Map 中的 key 是有序的。因此,当迭代的时候,一个 Map 对象以插入的顺序返回键值。一个 Object 的键是无序的。注意:自ECMAScript 2015规范以来,对象确实保留了字符串和Symbol键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。
SizeMap 的键值对个数可以轻易地通过size 属性获取Object 的键值对个数只能手动计算
迭代Map 是 iterable 的,所以可以直接被迭代。迭代一个Object需要以某种方式获取它的键然后才能迭代。
性能在频繁增删键值对的场景下表现更好。在频繁添加和删除键值对的场景下未作出优化。

作用

1. 存储值,存储键值对形式的值,map比对象更合适,键可以是任意类型

async 异步函数

使用async声明的函数, 与await配合使用,await强制等待的,两种结合,
让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。
即:内部封装了generator函数,是一个语法糖,内部自带执行器,与await配合使用;异步编程,同步处理;

作用

一般用于请求的发送,

try catch 异常捕获

当请求错误时,仅报了promise错误,对于错误的类型并未做出声明,那么解决这个问题可以使用trycatch里面来写异步请求,
当请求失败的时候就会走catch,也可以使用throw('失败')来抛出异常
否则走try,最后无论成功与否都会执行finally函数

同步与异步

同步

同一时间内,只能做一件事情,
在单线程中,按照代码的解析顺序从上到下执行同步代码

异步

在进入到事件循环的时,主要处理一个宏任务,
但是处理宏任务时遇到微任务时,会优先执行微任务
微任务
promise async

generator函数

异步编程的解决方案,他会返回一个迭代器的对象,真正的执行就是调用next()指针,会执行yiled状态。
一个yiled状态就是一个yiled代码节点

特点

1. function 和函数名之间必须有*号
	例: function * test(){}
2. 内部使用yiled表达式,不使用return,最后一个可以使用return

yield

一个yiled状态就是一个yiled代码节点,即一个yield就是一个节点。
Generator函数内部使用的是yield,不使用return
例:
function * Generator(){
	// 内部使用的是yield表达式
	yield '1'; 
	yield '2'
	yield '3'
}
当调用Generator函数时,第一次调用即调用next()会返回 yield的第一个状态,即'1',第二次执行会得到 '2' ,

状态参数之间的传递

注意第一个状态的执行在代码里面就算使用了参数接收,也不会被那个参数所拿到,所以后续的状态如果需要使用上一状态的结果,就会拿不到。
即 
function * Generator(){
	// 内部使用的是yield表达式
	let res = yield '1';  //注意res是拿不到 1 的
	yield '2'
	yield '3'
}
所以我们要把第一个状态传递到第二个状态里,那么在第一个异步请求里面调用第二个状态
例子:
function *Generator(){
			let res=yield getData();
			console.log(res);
			 // 上一个状态声明变量 下一个状态使用 
			yield '结束了';
		}
		let res=Generator();
		res.next()
		async function getData(){
			let response=await axios.get('http://121.199.0.35:8888/index/article/findCategoryArticles');
			// 如果想要实现数据传递 需要发起第二段程序执行 
			// 拿上一个状态得返回值作为下一个状态得入口
			res.next(response.data)
		}

promise

是一个承诺对象,存放着将来才会执行的代码。不是一个同步代码,同步代码是立即执行的代码。
promise 是解决异步编程的方案。

作用

1.使用promise封装ajax,注意不是axios
2.异步操作,同步解决,避免了层层嵌套的回调函数,可以链式调用降低了操作难度

使用

声明promise对象

格式:
let promise = new Promise((resolve,reject)=>{
})
promise 参数
 new Promise(resolve,reject);二者是一个回调函数
 resolve: 成功的回调函数
 reject: 失败的回调函数

promise 的实例方法

格式:
promise.then((res){}).catch((err)=>{}).finally(()=>{})   --->链式调用,每次链式调用返回的都是一个promise实例,所以能链式调用

then

resolve 函数就由then提供,执行请求成功的回调函数,可以放两个参数。
例:
promise.then((res)=>{},(err)=>{})  -->第一个参数是请求成功的回调,第二个参数是请求失败的回调

catch

reject 方法由catch提供,执行失败的回调函数

finally

无论成功或者失败都会执行的回调函数,一般会应用于loading。

promise 的状态status

fulfilled

请求成功

rejected

请求失败

pedding

等待/进行中

promise封装ajax

function promise(method,url){
	return new Promise((resolve,reject)=>{
		let xhr = new XMLHttpRequest();
		xhr.open(method,url);
		xhr.send();
		xhr.onreadystatechange = function(){
			if(xhr.readyState===4){
				if(xhr.status===200){
					reslove(xhr.responseText)
				}else{
					reject(xhr.responseText)
				}
			}
		}
		
	})
}
// 使用
let p1 = promise('get','url');
p1.then(res =>{})

静态方法 Promise

Promise.all()

实例请求全部成功后返回一个承诺对象,
参数:
	Promise.all([存放多个promise实例对象])
	例:Promise.all([p1,p2])
返回值:
	返回一个promise实例 ,当全部实例请求成功后才能返回一个成功的状态码,里面存放了一个数组,数组里面存放了每个请求实例返回的对象

在这里插入图片描述

Promise.any()

返回一个承诺对象,实例全部失败则返回一个失败状态码,有成功的实例则返回一个成功的状态码,value存放一个请求成功的全部数据

Promise.race()

 赛跑返回先请求成功的实例,

Promise.allSettled()

把请求的实例对象 封装成 Arry[ {里面是一个实例请求} {} ],
把实例的请求都放在数组里面,不管是请求失败还是成功。

事件循环

同步代码>微任务>宏任务,
事件循环主要用于执行宏任务
一次事件循环,只能处理一次宏任务。执行完一个宏任务之后会进行一个轮询,检查是否有微任务,有微任务会把所有微任务执行完毕,之后执行宏任务。
同步代码为立即执行的代码,主要是从上到下的优先级,当同步任务遇到异步任务,异步任务不会立即执行,把异步任务放到任务队列中,继续向下执行同步任务
微任务
await后面的代码属于微任务,与promise.then同级别,
promise.then>promise.finally 二者都是微任务。但不在then或finally里面的任务是同步任务

宏任务

setTimeout setInterval ajax Dom事件

微任务

promise.then/finalli  async/await(注意,执行await时后面的代码会隐式在外层嵌套promise.then,变成微任务)
// 事件循环 
setTimeout(function () { // 宏任务
  console.log('1'); 
});
async function test(){
	console.log('5') // 同步代码,立即执行
	await async2(); // 微任务   ----》
	//相当于 new Promise(()=>{
	//	async2()
	//}).then(()=>{}).finally(()=>{ console.log('6')})
	console.log('6') // 微任务
}
new Promise(function (resolve) {
  console.log('2'); // 同步代码,立即执行
  resolve();
}).then(function () { // 微任务
  console.log('3'); 
}).finally(()=>{ // 微任务
	console.log('8');
})
function async2(){ 
	console.log('7'); // 同步代码
}
test()
console.log('4');

2 5 7 4 3 6 8 1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值