ES6的语法

JavaScript/前端
37
0
0
2024-07-03
标签   TypeScript

ES6的笔记

## let声明变量

基本用法:类似var ,但是变量只在代码块内有效 var 和 let 比较

{
	let x=10;
	var y=15
}
	console.log(y)//15
	console.log(x)//报错
let不存在变量提升
暂时性死区
es6明确规定,如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了密闭空间。凡是在声明之前就使用这些变量就会报错
简单来说暂时性死区就是在let的本作用域中 在let之前引用了let的变量
	let不允许重复声明斜体样式
	允许在块级作用域内声明函数
	函数声明类似于var ,即会提升到全局作用域或函数作用域的头部,同时函数声明还会提升到所在的块级作用域的头部
	避免在块级作用域内声明函数优先使用函数表达式
	let fn=function(){}
	//块级作用域必须有大括号
	const
	const声明的变量为常量,只读,不能更改
	const声明变量是立即赋值
	const作用域玉let相同,只在声明的块级作用域有效
	不存在变量提升
	不能重复声明
	const保证的是值和引用地址不得更改
	const FOO=Object.freeze({a:1,b:2})
	冻结对象本身不能添加属性,不能修改属性的值类型
	冻结数组本身不能添加元素,不能修改元素的值类型
//Object.keys(obj)返回一个数组,由obj的所有属性或者obj的所有索引
//深拷贝:
	function freezeAll(obj){
			var ora=Array.isArray(obj)?[]:{};
			Object.freeze(obj);
			//Object.keys(obj)返回一个数组,由obj的所有属性或者obj的所有索引
			Object.keys(obj).forEach(function(item){
				if(typeof obj[item]=="object"){
					ora[item]=freezeAll(obj[item])
				}else{
					ora[item]=obj[item]
				}
			});
			return ora;
			
		}
		var obj=[1,[2,3,[4,5,[6,7]]]]
		var res=freezeAll(obj);
//冻结
const AX=freezeAll(obj)
function freezeAll(obj){
	Object.freeze(obj);
	//	Object.keys(obj)返回一个数组,由obj的所有属性或者obj的所有索引
	Object.keys(obj).forEach(function(item){
		if(typeof obj[item]=="object"){
			obj[item]=freezeAll(obj[item])
		}
	});
	return obj;
	
}
let a=1,b=2,c=3;
不注册变量成window的属性
没有重复定义

数组的解构赋值

按一定模式从数组或对象中提取值为变量赋值叫做解构
模式匹配,等号左右两边模式相同,不能解构赋值undefined
部分匹配,左边变量少于右边数组
右边不是数组
表达式惰性求值,需要赋值的时候执行表达式
对象的解构赋值
let{a:a,b:b,c:c}={a:1,b:2,c:3}--模式和变量 
对象的解构赋值的内部机制,是先找到同名属性,然后再赋值给对应的变量
等号右边数字和布尔值结构先转为对象

字符串

es6用反引号(ESC下)包围变量用${变量}拼接
	字符串的方法:str.includes("s") 有没有 返回truefalse
	str.startsWith("s")是不是在开头
	str.endsWith("s")是不是在结尾
	str.includes("s",num) 
	str.startsWith("s",num)从索引最后前num是否以s开头
	str.endsWith("s",num)从索引最后前num是否以s解束
	str.repeat(n)重复次数,生成新字符串n不是数字会被转成数字,n<=-1报错;-1<n<0,n=NAN解果都为0
	str.padStart(n,"xyz")从前面补全字符串,生成新字符串
	str.padEnd(n,"y")从后面补全字符串
	n:补全之后的长度,y要补充的字符串,重复出现
	n=str长度:返回str
	重复次数过多超过n,截取后面的多余字符
	str.trim()//去除空白返回新字符串
	str.trimStart()去除前面空白和str.trimLeft()一样
	str.trimEnd()去除后面空格和str.trimRight()一样
	空白含:空格 tab键空格 全角空格 半角空格
	str.replaceAll("a","m")替换全部
	Number.isFinite()只对数值有效,其他类型一律false isFinite()
	Number.isNAN()只对数值有效,其他类型一律false isNAN();
	Number.parseInt()==parseInt();
	Number.parseFloat()==parseFloat();
	Number.isInteger();判断是否为整数,非数值返回false
	Number.isSafeInteger()判断是否是安全整数(-253次方)~(253次方)
	Number.MAX_SELF_INTEGER
	BigInt-大整数
	在数字后面加n(标志)
	typeofBigInt()
	BigInt(x)x为小数报错,x为NAN报错
	Boolean String Number可以将大整数转换
	运算与Number一致,除以运算舍弃小数10n/3n=3n;
	可用于比较1n<2 true
	""+35n="35"
	运算(1n*10n)

指数

a**b=Math.pow()
a的b次方
a**b**c===a**(b**c)
Math
Math.trunc()去除小数点,保留整数
            非数值转化成数值,转化不了NAN
Math.sign() 正1 负-1 0-0 -0--0 NAN
Math.imul(a,b);a*b

数组Array 扩展运算符…

Math.max(...[123])
let arr=[1,2];var copy=[...arr];
let arr1=[1,2],arr2=[3,4,5]
let arr=[...arr1,...arr2]
const[first,...rest]=[1,2,3,4,5];
let BtnArr=[...document.querySelectorAll(".btn")]
Array.from(),将类数组转化成真正的数组
只要是部署了Iterator接口的数据结构,Array.from都能将其转为数组;
第二个参数回调函数,对数组元素进行处理,将处理之后的值放入返回数组
Array.from(arguments,function(arg){
	teturn arg*arg
})
与 ...(扩展运算符)的区别:都是能转化具有Iterator接口的数据为数组
{length:2},...不能转化
Array.from转换对象为[undefined,undefined],...转换对象报错
Map
arr.map(function(value,index,arr){
})
返回新数组,可以对每一项进行修改可以直接通过value改值,forEach不行,只读不写  想要更改要用第三个参数arr[index]进行改值(value = arr【index】*1)
生成1-100
var res=Array.from({length:100}).map(function(v,i){
	return v=i+1;
});
或
var res=Array(100).fill(0).map(function(v,i){
	return v=i+1;
})
arr.fill(x)填充数组,已有的元素会被覆盖
arr.fill(x,start,end)//起始位置,结束位置(不含)只有开始填充到最后
x是引用类型,填的是指向
Array.of();序列转化成数组
Array.of(1,2,3)==[1,2,3];
[].slice.call(arguments)模拟实现Array.of()

序列变数组Array.of()
类数组变数组Array.from()
数组转序列...(扩展运算符)
Array.copyWithin(目标索引,开始索引,结束索引)
从开始索引到结束索引,复制数组元素,从目标索引开始放在目标索引 负数为倒数
[1,2,3,4,5].copyWithin(0,3) 4,5,3,4,5
arr.find(function(){})返回第一个符合条件的结果,没有则返回undefined
arr.findIndex(function(){})返回第一个符合条件的索引,没有则返回-1
indexOf()不能查找NAN    (arr.includes)能查找NAN
arr.keys();获取键
arr.values()获取值
arr.entries()获取键值对
返回数组,遍历器对象,可通过for..of遍历
for(let [k,v] of arr.keys()){ //keys() 数组中的每一项
	console.log(k,v)//索引和内容
}

let arr=[1,2,3,4,5];
for(let i of arr){
	console.log(i) 直接取值
}

for(let i of arr.keys()){
	console.log(i)取索引
}
arr.includes(tag,index) arr中是否包含tag
index,开始索引,默认0,负数从后往前数 负大于长度0
arr.flat(n);拉平数组
用infinity做参数,无论多少维数组都能拉平为一层
arr.flatMap(function(v,i){
	对每个元素进行处理(map),在拉平,最后返回一个新数组
})
flatMap只能拉平一层

empty,[,,,]
empty:什么都没有,不是undefined,不是null
forEach,some,every,reduce,filter跳过空元素
map跳过但保留元素显示为(empty)
join,toString将空元素视为undefinedundefinednull视为空
Array.from(),...将空视为undefined          将类似数组的对象转化为真的数组
copyWith拷贝空元素
fill将空视为正常
for...of将空视为undefined
keys,values,entries,find,findIndex将空视为undefined

object

属性简洁表示法
	{a:a,b:b}=={a,b},
	方法简洁表示法
	{a:a,b:b,say:function(){}}==={a,b,say(){}}
	对象方法做构造函数方法不能简写
	let obj={
		fn(){
		this.x=100
		}
	}
	属性名表达式
	obj.a=10 标志符
	obj["b"]=20方括号
	let obj={
		a:1,
		b:2
	}
	不要用对象做表达式
	
	可枚举,enumerable
	对象的每个属性都有个可描述对象,Object.getOwnPropertyDescriptor(obj,xy)
	Object.getOwnPropertyDescriptors(obj)方法,返回指定对象的所有自身属性(非继承的属性)的描述对象
	enumerable为false,则不可被for in遍历 自身的和继承的
	for..in循环:只遍历对象自身的和继承的可枚举属性
	Object.keys():返回数组,包含对象自身所有可枚举属性的键名
	JSON.stringify():只串行化对象自身的可枚举属性
	Object.assign():忽略enumerable为false的属性,只拷贝对象自身的可枚举属性
	Object.assign({},obj,变量1,变量2)合并对象,浅拷贝,返回新数组
	Object.assign(obj,变量1,变量2)合并对象,浅拷贝
	arr.concat()浅拷贝
	Object.defineProperty 扩展属性
	
	for..in循环:只遍历对象自身的和继承的可枚举属性
	Object.keys(obj):返回数组,包含对象自身所有可枚举属性;
	Object.getOwnPropertyNames(objs)数组,包含自身所有属性和自身不可枚举属性的键名(非继承属性)
	Object.getOwnPropertySymbols(obj)数组,包含对象自身所有的Symbol属性的键名
	Reflect.ownKeys(obj);返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是Symbol或字符串,也不管是否可枚举
	
	首先遍历所有数值键,按照数值升序排列
	其次遍历所有字符串键,按照加入时间升序排列
	最后遍历所有的symbol键,按照加入时间升序排列

数据劫持

let obj={}
	Object.defineProperty(obj,"a",{
		value:200,默认为undefined
		enumerable:true,默认为true
		writable:true,默认为false
		configurable:true;默认为false
	})
	
	let obj={}
	Object.defineProperty(obj,"a",{
		get:function(){
			return this.value;
		},
		set:function(v){
			this.value=v;
		},
		value:200,默认为undefined
		enumerable:true,默认为
		configurable:true;默认为
	})
	
	Object.defineProperty(Array,"shuffle",{
		value(arr){
			return arr.sort(function(){
				return 0.5-Math.random()
			})
		}
	})
	
	Object.defineProperty(Array,"shuffle",{
		value:function(arr){
			return arr.sort(function(){
				return 0.5-Math.random()
			})
		}
	})
	console.log(Array.shuffle(arr))
super:指向当前对象的原型对象,只能在对象方法里使用
obj.__proto__读取或设置obj的原型方法 Object.prototype
let obj=Object.create(xy)生成obj的原型对象为xy
Object.setPrototypeOf(obj,mn)设置对象的原型对象
Object.getPrototypeOf(obj)获取对象的原型对象
扩展运算符...的解构赋值
将对象可遍历但没分配的属性拷贝过来
let{a,b...c}={a:1,b:2,m:3,n:4};
a=1,b=2,c={m:3,n:4}
...只能用在最后一个参数
...后面不是对象强制转换成对象
...后面是字符串时,转成类数组
扩展运算符的拷贝
let x={a:1,b:2}
let obj={...x}等价于let obj=Object.assign({},x)//合并对象
只拿到了自身属性,获取自身和原型属性可用:
let obj={
	__proto__:Object.getPropertyOf(x),
	...x
}
let obj=Object.assign(Object.create(Object.getPrototypeOf(x)),x)
扩展运算符...合并
let x={a:1,b:2};
let y={a:3,d:4};
let obj={...x,...y}等价于let obj=Object.assign({},x,y);

链判断运算符?.
链式调用时判断,如果是nullundefined直接返回undefined
a?.b       属性调用
m?.[1]	索引调用
xiaoming.say?.()	方法调用
短路
delete
报错
括号

null判断??
类似||,设定默认值
如果是nullundefined才生效
let title=a?.b?.title??"Null判断"
与&&或||一起用,必须括号
??和| |效果类似,但是 区别在于??仅代表前面的表达式是null 或者undefined才会执行后面的表达式 。而| |则代表前面的表达式是null或者undefined或者false 或者0才会执行后面的。
Object.keys  返回键
Object.values 返回值
Object.entriess 返回键值对

参数默认值

es6之前设置参数默认值 a=a||100
es6的null判断运算符 a=a??100
es6函数参数默认值 function say(a=100){}默认值严格等于(===)undefined
函数里不能再次用letconst声明参数的同名变量
参数名不能重复
默认值不影响arguments
解构赋值做默认值
function abc({a,b=10}){
	console.log(a,b)
}
abc()报错不能解构
abc({}undefined,10)

function abc({a,b=10}={}){
	console.log(a,b)
}
abc()undefined,10
abc({}undefined,10)
有默认值的参数不是最后一个参数,调用时不可省略
省略中间参数(5,null,10)
function abc(a,b=5,c){
	console.log(a,b,c)5 5 10
}
abc(5,undefined,10)

**长度**
length计算方式:第一个默认值参数(不含)之前的参数个数
var a=100;
function abc(a,b=function(){console.log(a=10)}){
	a=25;
	b();
	console.log(a)10 10
}
abc(50)

rest
参数用...abc形式表示剩余参数,abc为数组
代替了arguments
rest不算入长度
rest必须放最后

严格模式

函数体内不能设置严格模式"use strict"
解决方案:全局设置,立即执行函数设置

箭头函数

let fn=x=>x    相当于:let fn=function(x){
	return x;
}
参数说明:1个参数可不加括号,无参数或多个函数要加括号
函数体说明:如果要return,无大括号可不写return
           单行执行代码可省略{}
		   返回对象形式,必须放()里
		   
特点:无arguments对象,用rest代替
	 this是创建时,不是调用时,箭头函数里没有this,this指向外层代码块不能做构造函数
	 
箭头函数使用要注意什么
(1)函数体内的this指向不固定window,和父级作用域一致

(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

(3)不存在arguments对象,用rest代替该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
(5) 没有prototype(原型)

(6) this指向不能被改变

set

支持forEach遍历
类似数组,每个值都是唯一的{1,2,3,5}
let s=new Set(数组、字符串、NodeListHTMLCollection、argument等)
s.size 成员数
s.add(x)添加成员,存在则不添加,返回实例本身
s.delete(x)删除成员,返回truefalse
s.clear()清楚所有成员
s.has(n);是否有n
set 用for of遍历
let s =new Set([1,2,3,4,5,6]);
for(k of s.leys()){
	console.log(k)
}

数组去重

let s=new Set(1,2,2,3,4,3,4,5,2,1)
console.log([...new Set(s)])
let x=new Set(1,3,2,4,5]),y=new Set([2,4,3,6,7]);
交集(公共部分)a,并集(合并,不重复)b,差集(没有对方的)c;
let a=[...x].filter(v=>[...y].includes(v));
let b=new Set([...x,...y]);
let c=[...x].filter(v=>![...y].includes(v));
weakSet
成员是对象或数组
没有size
不可遍历
add,has,delete
弱引用
let ws=new WeakSet([[1,2],[3,4]])

WeakSet和Set区别:

1WeakSet解构和Set类似,都是不重复值的集合。
2WeakSet的成员只能是对象,而不能是其他类型的值
3WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用。也就是说,如果其他对象都不再引用该对象,那么垃圾垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象是否还存在于WeakSet之中。(WeakSet里面的引用都不计入垃圾回收机制,适合临时存放一组对象,以及存放跟对象绑定的信息。只要这些对象在外部消失,它在WeakSet里面引用的就会自动消失。)

  WeakSet不能遍历,因为成员都是弱引用,随时可以能消失,遍历机制无法保证成员存在。
  WeakSet的一个用处是储存DOM节点,而不担心这些节点从文档移除时会引发内存泄露。

Map

存键值对的对象或数组{"yes"=>true,"no"=>false}	
size,
.set(key,value);key是任意值返回实例
.get(key)
has(键)
delete、clear
map对象本身就是map.entries()
weakMap 类似Map属性必须是对象(引用类型)
let wm=new weakMap([[{a:1},100,{b:2},200]])
Map
Map转json
属性都是字符串
转成对象,JSON.stringify(obj),JSON.parse(str)
属性不全是字符串
转成数组,JSON.stringify([...map]),JSON.parse(str)
JSONMap
键名都是字符串
对象转Map
整个JSON是数组,且每个元素又是数组
new Map(JSON)

Proxy Reflect

Proxy是在访问之前做一层拦截,对访问进行处理
let proxy=new Proxy("拦截目标",{拦截行为})
拦截目标:函数,数组,对象
拦截行为-get
get(target,prop,proxy){
	return 处理值
}

拦截属性读取

target:拦截目标
prop:属性
proxy:代理器对象 获取:proxy.getReceiver
configurable:false并且writable:false,报错
let obj={a:1,b:2}
let proxy=new Proxy(obj,{
	get(t,p){
		if(p in t){ 检测t里有没有p属性
			return t[p]
		}else{
			return `没有${p}属性`
		}
	}
})
获取对象属性,如果属性不存在,则打印 属性xx不存在
检测属性是否存在:if(prop in targer)
                if(Reflect.has(targer,prop))
拦截行为set{
	set(arguments,value,proxy){
	target[prop]=value;
}
拦截赋值操作
value:要修改的值
configurable:false(无法删除)并且writable:false (无法修改)
拦截行为apply
apply(目标函数,this,目标参数实参列表){
	return Reflect.apply(...arguments)
	}
拦截函数时调用,apply,call,bind()
this:目标函数中的this
Reflect.apply(...arguments)===Reflect.apply(目标函数,this,目标函数的实参列表)
拦截行为 has
has(target,prop){
	teturn prop in target;
}
拦截in
Reflect.has(target,prop)
拦截行为defineProperty
defineProperty(target,prop,descriptor){
	return 
}
拦截Object.defineProperty,让属性不可写,不能添加新属性

deleteProperty
deletePrototypy(t,p){
	return t[p];
}
拦截delete,返回false为属性不可删除

拦截行为getOwnPropertyDescriptor
getOwnPropertyDescriptor(t,p){
	return;
}
拦截Object.getOwnPrototypeDescriptor,返回不能获取属性描述对象
	
拦截行为setPrototypeOf
setPrototypeOf(target,proto){
	return false;
}
	
拦截Object(或Reflect).setPrototypeOf()设置原型效果(__proto__),return false为不可设置

取消代理
Proxy.revocable(obj,handler)
返回一个可取消的proxy实例,{proxy,revoke(){}};

Symbol

原始数据类型,表示独一无二的值
let s=Symbol()没有new ,不是对象,类似字符串
let s=Symbol("js")参数只是个描述,用于不同Symbol之间的区分,获取这个参数的描述:s.description
Symbol可以转换字符串和布尔值
Symbol做对象属性
Symbol做对象属性不能用.访问
Symbol设置属性时要用[]
遍历对象Symbol属性
Object.getOwnPropertySymbols()获取所有Symbol的属性
Reflect.ownKeys()获取自身的属性(包含不可枚举的属性,包含Symbol)
Symbol.for(),Symbol.keyFor()
Symbol()!==Symbol()
Symbol.for()生成新的Symbol,可搜索,for登记
使用Symbol.for(参数)先检查有没有相同参数的Symbol,有则返回没有则创建新的Symbol
Symbol.for()===Symbol.for()
Symbol.keyFor(s)返回登记的Symbolkey(参数)只返回Symbol.for()创建的

Iterator

遍历器是一种接口,为不同数据提供一种统一的访问机制,任何部署了iterator接口的数据都可以用for..of遍历
执行过程
创建指针对象,指向数据的起始位置
第一次调用next时,指向第一个成员
第二次调用next时指向第二个成员
一直到数据结束位置
function abc(arr){
	var n=0;
	return {
		next(){
		return n<arr.length?{value:arr[n++],done:false}:{value:undefined,done:true};
		}
	}
}
let x=abc([2,4,5,8])
next返回成员信息
value 返回成员的值
done遍历是否结束
```javascript
Symbol.iterator属性
默认的interator接口部署在Symbol的iterator属性上,Symbol.iterator是遍历器的生成函数,执行这个函数就会返回一个遍历器
Symbol.iterator是表达式,返回Symbol对象的iterator属性(类型Symbol),所以要用[]设置或访问

原生数据具有iterator接口
数组,字符串,map,set,HTMLCollection,NodeList。类数组等
let str="javascript";
let iterator=str[Symbol.iterator]();
iterator.next()


普通对象设置iterator接口
obj[Symbol.iterator]=function(){}
[...obj]
let obj={a:1,b:2};
obj[Symbol.iterator]=function(){
	obj没有length,取obj的key
	let keys=Object.keys(obj);
	keys["a","b"]
	let index=0;
	return {
		next(){
			return index<keys.length?{value:[keys[index],obj[keys[index++]]],done:false}:{done:true}
			
		}
	}
}
for(let i of obj){
	console.log(i)
}

gennertor 异步同步化

ajax回调,异步用同步表示
回调地狱
	$(function(){
		$.ajax({url:"1.php",success:(data)=>{
			var n=data;
			console.log(n)
			$.ajax({url:`${n}.php`,success:(data1)=>{
				var n1=data1;
				console.log(n1)
				   $.ajax({url:`${n1}.php`,success:(data2)=>{
					console.log(data2)
				}})
			  }})
			}
		})
	})

解决回调地狱问题

generator:异步问题同步显示
function abc(){
	let a=ajax("1.txt");
	let b=ajax(a+".txt");
	let c=ajax(b+".txt");
	console.log(c)
}

function ajax(url,callback){
	let xhr.new XMLHttpRequest("get",url);
	xhr.send()
	xhr.onreadystatechange=function(){
		if(xhr.readyState==4){
			if(xhr.status==200){
				callback(xhr.responseText);
			}
		}
	}
	
}
function qs(url){
	ajax(url,function(dt){
		gt.next(dt)
	})
}

function* abc(){
	let a=yield qs(1.txt);
	document.getElementByClassName("res").innnerHTML+=a;
	let b=yield qs(b+".txt")
	document.getElementByClassName("res").innnerHTML+=b;
	let c=yield qs(c+".txt")
	document.getElementByClassName("res").innnerHTML+=c;
	console.log(c)
}
let gt=abc()

promise:
ajax("1.txt").then(()=>{return ajax("2.txt")}).then().then()

promise

异步编程解决方案
保存着未来才会结束的事件结果
特点:
1.状态不受外界影响,3个状态,pending进行,fulfilled已成功,rejected已失败,只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态
2.状态改变:pending->fulfilled,pending->rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved

promise基本用法
let promise=new Promise((resolve,reject)=>{
		if(异步操作成功){
			resolve(value);padding->resolve未完成到成功,异步操作成功调用,将值(value)做参数传递出去
		}else{
			reject(error);pending->rejected未完成到失败,将异步操作的错误传递出去
		}
	})
promise的then
promise对象的then方法分别指定resolved和rejected回调函数
promise.then(function(value){
	成功的操作
},function(error){
	失败的操作
})
promise的简单例子
setTimeout第三个参数:给第一个参数传参
function abc(ms){
		return new Promise((resolve,reject)=>{
			setTimeout(resolve,ms,"aaaa");
			setTimeout(reject,5000,"错误")
			throw new Error("错误")
		})
	}
	abc(1000).then((value)=>console.log(value),(txt)=>console.log(txt))
throw 抛出错误
throw new Error("错误")
try{尝试
		console.log(a)
	}catch(err){捕捉
		console.log(err)
	}
	finally{最终
	    console.log(end)
		
	}
promise立即执行
实例中直接调用resolve或rejected方法
function abc(){
		return new Promise((resolve,reject)=>{
			console.log(3);
			resolve()
		})
	}
	abc.then(function(){
		console.log(1)
	})
	console.log(2)
promise封装图片加载
function loadImage(url){
		return new Promise((resolve,reject)=>{
			var img=new Image();
			img.src=url;
			img.onload=function(){
				resolve(this);
			}
			
			img.onerror=function(){
				reject()
			}
		})
	}
	loadImage(url).then((img)=>{
		document.body.insertBefore(img,document.body.firstChild),
		()=>{
			console.log("加载失败")
		}
	})

promise封装getJson方法

function getJson(url){
		return new Promise((resolve,reject)=>{
			let xhr=new XMLHttpRequest();
			xhr.open("get",url);
			xhr.responseType="json";
			xhr.setRequestHeader("Accept","application/json");
			xhr.send();
			xhr.onreadystatechange=function(){
				if(xhr.readyState!=4){
					return;
				}else{
					if(xhr.status==200){
						resolve(xhr.reponse)
					}else{
						reject(xhr.statusText)
					}
				}
			}
			
		})
	}
	getJson(文件名.json).then((data)=>{console.log(data)},(txt)=>{console.log(txt)})

promise嵌套

一个resolve用另一个promise做参数
let a=new Promise((rv,rj)=>{
	setTimeout(()=>{rv()},5000)
}).then(()=>console.log(5000))

let b=new Promise((rv,rj)=>{
	setTimeout(()=>{rv(a)},1000)
}).then(()=>console.log(1000))

return
resolve,reject不中断后面语句执行,想要阻止用return resolve()

then
then有两个参数,接收promise的resolve和reject
then里的resolve返回结果,作为下一个then的resolve参数(链式调用)

Promise.prototype.catch
catch接收错误(promise错误,throwError,then错误)
catch接收前面所有的错误,不接收后面错误,无错误则跳过
不推荐reject,推荐catch
.then().catch(()=>{})
finally(()=>{})
通常放在最后面,finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作