ES6笔记

一、走进ES6

1.1初识ES6

ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

  • 1997年:ECMAScript 1.0
  • 1998年:ECMAScript 2.0
  • 1999年:ECMAScript 3.0
  • 2006年: ECMAScript 4.0 未通过
  • 2009年: ECMAScript 5.o
  • 2015年: ECMAScript 6.0·至今,版本号改用年号的形式。

1.2、let声明变量与const声明常量

1.2.1、let声明变量

  1. let是块级作用域,只作用于当前块的作用域内
  2. 一个变量名称只能定义一次,不允许重复声明
  3. 必须先定义在使用, 使用必须在定义之后
  4. 不与顶层变量挂钩
	let myage = 100
	console.log(window.myage)//无法访问到

1.2.2、const声明常量

  1. 定义后不能改变,并且使用comst必须赋值
  2. 不能重复定义
  3. const是块级作用域,只作用于当前块的作用域内
  4. 必须先定义在使用, 使用必须在定义之后
  5. 不与顶层变量挂钩
  • 改变const命名的值的方式
    • 如果命名的是对象数据类型,则可以直接改变对象内部的值
    • 如果对对象数据类型使用了fresze则不法直接改变对象内部的值(只能冻住一级属性)

1.3、解构赋值

  • 快速的从对象和数组中获取里面的成员
  • 例:
var arr = ["asd","132","12sd"]

let [x,y,z]

console.log(x,y,z)
  • 交换:
var a = 10
var b = 20
var [b,a] = [a,b]
  • 多维数组取值:
var arr = [1,2,[3,4,[5]]]

//想获取5,需要arr[2][2][0]
var [a,b,[c,d,[e]]] = arr

//直接取e即可

对象

  • 赋值对象(对号入座)
var obj = {
	name = "zhangsan"
	age = 100
	location:"henaN"
	data:{
		list:["aaa","bbb","ccc"]
	}
}

let {name , age, location:mylocation,data:{list:[x,y,z]}} = obj
//取对象里的值
console.log = (name,age,mylocation,x)
  • location是一个关键字需要用location:mylocation的方法来替代,同样如果在对象外部用let定义了和key值相同的变量也用这种方法消除
  • 也可以通过函数的方式获取对象的值
function getData(){
	let res = {
		code:200,
		data:{
			list:["aaa","bbb","ccc"]
		}
	}
	test(res)
}

function test({code,data}){
	console.log(code,data)
}
getData()

字符串解构

let myname = "asdasf"
let [x,y,z] = myname
console.log(x,y,z)//取出字符串前三个字母

let{length} = myname
console.log(length)

1.4、模板字符串

使用``将需要加的标签与内容写进去即可

//map案例的改编
var arr =["aaa","vvv","ooo","aaas"]
var arr2 =arr.map(function(item){
	return `<li>${item}</li>`
})
documnet.write(arr2.join(""))
//也可以给数组中指定的元素加上class属性

var arr =["aaa","vvv","ooo","aaas"]
var arr2 =arr.map(function(item,index){
	return `<li${index===0?'class':''}>
		<b>${item}</b>
	</li>`
})

//在es6中可以通过使用``来使字符串可以换行
var myhtml = `
<li>2</li>
<li>1</li>
`
var name = "zhangsan"
var str = `my name is ${name}`
//通过在${}里面添加变量可以添加字符串,使其连在一起
//${}内部的区域相当于js的区域

var arr=[1,2,3,4]
var arr2=arr.map(function(item){
	return item*item//返回值返回到原数组中
	//此式子为计算原数组平方
})

1.5、字符串扩展

  1. includes函数
    判断字符串中是否存在指定字符
let myname = "kerwin"
console.log(myname.includes("e")) //true
console.log(myname.startswith("k")) //true
console.log(myname.endswith("n")) //true

函数里可以有两个参数

  • 第二个参数表示从第几个字母开始查阅
  • endswith是从第二个参数往前的字符串的最后一个字母
let myname = "kerwin"
console.log(myname.includes("e"2)) //false
console.log(myname.startswith("e",1)) //true
console.log(myname.endswith("s",4)) //true
  1. repeat函数
    repeat()方法返回一个新字符串,表示将原字符串重复n次。
  • 参数只能传数字
let myname = "kerwin"
console.log(myname.repeat(3))//kerwinkerwinkerwin
console.log(myname.repeat(0))//"""
console.log(myname.repeat(3.5))//kerwinkerwinkerwin
console.log(myname.repeat("3"))//kerwinkerwinkerwin

1.6、数值扩展

  1. 二进制和八进制表示法
let count1 = 100
let count2 = 0x100
let count3 = 0o100
let count4 = 0b100
  1. isFinite与isNaN方法
  • 减少全局性方法,使得语言逐步模块化
let num1 = Number.isFinite(100)//true
let num2 = Number.isFinite(100/0) //false
let num3 = Number.isFinite(Infinity) // fa1se
let num4 = Number.isFinite("100") //fa1se
let num1 = Number.isNaN(100)// false
let num2 = Number.isNaN(NaN] //true
let num3 = Number.isNaN ("kerwin") //false
let num4 = Number.isNaN("100")// false

它们与传统的全局方法isFinite()和isNaN()的区别在于,传统方法先调用Number()将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,Number.isFinite()对于非数值一律返回false, Number.isNaN()只有对于NaN才返回true,非NaN一律返回false。

  1. islnteger方法
    用来判断─个数值是否为整数。
let num1 = Number.isInteger(100) // true
let num2 = Number.isInteger(100.0)//true
let num3 = Number.isInteger("kerwin") //false
let num4 = Number.isInteger("100"") // fa1se
  1. 极小常量Number.EPSILON.
    它表示1与大于1的最小浮点数之间的差。2.220446049250313e-16
function isEqua1(a,b){
	return Math.abs(a-b)<Number.EPSILON
	}
	console.log(isEqua1(O.1+0.2,0.3)) //true
	console.log(0.1+0.2===0.3)//false
  1. Math.trunc
    将小数部分抹掉,返回一个整数
console.log(Math,trunc(1.2))//1
console.log(Math,trunc(1.8))//1
console.log(Math,trunc(-1.8))//-1
console.log(Math,trunc(-1.2))//-1
  1. Math.sign
    Math.sign方法用来判断一个数到底是正数,负数,还是零。对于非数值,会先将其转换为数值
Math.sign(-100)//-1
Math.sign(100)//+1
Math.sign(0)//+0
Math.sign(-0)//-0
Math.sign("zhangsan")//NaN

1.7、数组扩展

  1. 扩展运算符
let arr1 = [1,2,3]
let arr2 = [4,5,6]
console.log([...arr1,...arr2])

let mayarr = [1,2,3,4,5,6]
let [a,b,...c] = myarr 
console.log(a,b,c)//此时c表示[3,4,5,6]
  1. Array.from
    将类数组对象转换为真正数组
function test(){
	console. log(Array.from(arguments))
	}
	test(1,2,3)
	let oli = document. queryselectorA11("li")
	console.log(Array.from(oli))
  1. Array.of
    将一组值转化为数组,即新建数组
let arr1 = Array(3)
console. 1og(arr1)// [,,]
let arr2 = Array.of(3)
console.log(arr2)//[3]
  1. find方法
    1)该方法主要应用于查找第一个符合条件的数组元素
    2)它的参数是一个回调函数。在回调函数中可以写你要查找元素的条件,当条件成立为true时,返回该元素。如果没有符合条件的元素,返回值为undefined
let arr = [11,12,13,14,15]
let res1 = arr.find(function(item){
		return item>13
		})
let res2 = arr.findIndex(function(item){
		return item>13
})
console.log(res1) //14
console.log(res2)//3

let res1 = arr.findLast(function(item){
		return item>13
		})
console.log(res1)//15

findLast findLastIndex() 从数组的后面开始查找ES2022更新的

  1. fill方法
    快速填充
let arr = new Array(3).fill("shangsan")//内容会被填充为shangsan
console.log(arr)

let arr1= [1,2,3]
console.log(arr1.fill("asd",1,2))//快速替换第一个参数是要添加的元素,第二个参数是开始的位置,第二个元素是结束的位置
  1. flat() flatMap()方法
    扁平化处理
let arr = [1,2,3,[4,5,6]]
let arr1 = arr.flat()

let arr = [
	{
		name:"1",
		list:["a","b","c"]
	}
	{
		name:"2",
		list:["s","d","f"]
	}
]
let res = arr.flatMap(function(item){
	return item.list
})
console.log(res)

1.8、对象扩展

  1. 对象简写
let name = "moduleA"
let obj ={
	name ,//name:name
	test1(){
	
	},
	test2(){
	
	}
}
  1. 对象属性
let name = "a"
let obj = {
	[name]:"asd"
}
//此时[name]=a

let name = "moduleA"
let obj ={
	name,
	[name+"test"](){
},
	[name+"test"](){

}
}
//此时改变name的值就能改变对象中的属性值
  1. 扩展运算符

...(ES2018支持)

let obj1 = {
	name = "asd"
}
let obj2 ={
	...obj1
}
obj2.name = "zxc"//此时不改变obj1的值只改变obj2的name值


let obj1 = {
	name = "asd"
}
let obj3 ={
	age : 100
}
console.log({...obj1,...obj3})
//此时合并obj1和obj3,同key值会导致后面的覆盖前面的key值
  1. 快速合并对象
    Object.assign

let obj1 = {
	name = "asd"
}
let obj2 ={
	name ="wsx"
}
let obj3 ={
	age : 100
}
console.log=(Object.assign(obj1,obj2,obj3))//实际上是以第一个对象为基准,把后面两个对象给加进去,所以会导致第一个对象发生变形
  1. 判断两个值是否相同
    Object.is
  • 原有的=====无法判断NaN类型的
Object.is(5,5)//true
Object.is(0,5)//false
Object.is({},{})//false
Object.is(NaN,NaN)//true
Object.is(parseInt("asdsad"),NaN)//可以判断传入的数据是否合法

Object.is(+0,-0)//false

1.9、函数扩展

1.9.1、常规属性值

  1. 参数默认值
function ajax(url,method="get",async="true"){
	console.log(url,method,async)
}
ajax("/aaa")
  1. rest参数 剩余参数
function test(...data){
	console.log(data)
}
test(1,2,3,4,5,6)
  1. name 属性
  • 拿到函数的名字
function test(...data){
	console.log(data)
}
test(1,2,3,4,5,6)

console.log (test,name)//值为test

1.9.2、箭头函数

  1. 写法简洁
//常规
 let test = function(){
}
//箭头函数
let test=()=>{
}
  • 可以省略{ }(只有返回值时可以省略return,只有一句代码时)
let arr =["aaa","bbb","ccc"]
let newarr = arr.map((item)=>`<li>${item}</li>`)
//此时可以将数组的值依次用函数表达出来
  • 当返回一句语句,并且是对象时,需要在大括号外面加一个括号
let test2 = ()=>({
	name:"asda",
	age:100
})
  • 可以省略括号(只能是只有一个形参时可以省略)
let arr =["aaa","bbb","ccc"]
let newarr = arr.map(item=>`<li>${item}</li>`)
  • 没有arguments(arguments是相当于没有形参时,但传入了参数,此时可以以数组的方式查看参数),无法new
let test3 = ()=>{
	console.log(arguments)
}
test3(1,2,3)//报错
new test3()//报错
  • 箭头函数没有this,箭头函数中的this会指向父级作用域

1.10、Symbol

ES6引入了一种新的原始数据类型symbol,表示独一无二的值。它属于JavaScript 语言的原生数据类型之一,其他数据类型是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number) 、对象(Object)。

  1. 使用Symbol作为对象属性名
let name = symbo1()
let age = symbo1()
var obj={
	[name] : "kerwin",
	[age] : 100
}
console.log(obj[name])//teichui
  1. Symbol()函数可以接受一个字符串作为参数,表示对Symbol实例的描述。这主要是为了在控制显示,比较容易区分
let name = symbo1("name")
let age = symbo1("age")
var obj={
	[name] : "kerwin",
	[age] : 100
	}
	console.log(obj)
  1. Symbol不能进行运算
  2. 隐式转换为布尔类型
var s1 = symbol()
if(si){
	console.log("aaa")
}
  1. 整体Symbol()
let keys = {
	name:Symbol(),
	age:Symbol(),
	location:Symbol(),
	test:Symbol()
}
let obj = {
	[key.name]:"asd"
	[key.age]:100
	[key.location]:"zxc"
	[key.test](){
		console.log("test")
	}
}

console.log(obj[Symbol()])

也可以给Symbol加上参数,不过表达出的依旧是其本身

let keys = {
	name:Symbol(name),
	age:Symbol(age),
	location:Symbol(location),
	test:Symbol(test)
}
let obj = {
	[key.name]:"asd"
	[key.age]:100
	[key.location]:"zxc"
	[key.test](){
		console.log("test")
	}
}

console.log(obj[Symbol()])
  • for in 无法遍历出Symbol定义的对象
  • 可以通过Object.getOwnProperSymbols()来使Symbol定义的对象
let keys = {
	name:Symbol(name),
	age:Symbol(age),
	location:Symbol(location),
	test:Symbol(test)
}
let obj = {
	[key.name]:"asd"
	[key.age]:100
	[key.location]:"zxc"
	[key.test](){
		console.log("test")
	}
console.log(Object.getOwnProperSymbols(obj))
  • Reflect.ownKeys()可以获取对象的所有内容
let keys = {
	name:Symbol(name),
	age:Symbol(age),
	location:Symbol(location),
	test:Symbol(test)
}
let obj = {
	[key.name]:"asd"
	[key.age]:100
	[key.location]:"zxc"
	[key.test](){
		console.log("test")
	}
Reflect.ownKeys(obj).forEach(item=>{
	console.log(item,obj[item])
})

Symbol可以作为常量

const VIDEO = Symbol()
const AUDIO = Symbol()
const IMAGE = Symbol()

function play(type){
	switch(type){
		case VIDEO:
		console.log("视频播放")
		case AUDIO:
		console.log("音频播放")
		case IMAGE:
		console.log("图片播放")
		}
	}
	play(IMAGE)

1.10、Iterator迭代器

Iterator的作用有三个:

  1. 为各种数据结构,提供一个统一的、简便的访问接口;
  2. 使得数据结构的成员能够按某种次序排列;
  3. ES6创造了一种新的遍历命令for…of循环,Iterator接口主要供for…of循环
let arr = ["aaa","bbb","ccc"]

for (let i of arr){
	console.log(i)
}
//通过for...of可以获取数组中的所有项
console.log(arr)

let iter = arr[Symbol.iterator]()
//返回得到的就是遍历器对象
console.log(iter)

console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
//会依次表达出数组的值

  • Iterator的遍历过程:
    • 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象
    • 每次调用指针对象的next方法,指针就依次指向相应的值
    • 不断调用指针对象的next方法,直到它指向数据结构的结束位置

ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是"可遍历的”(iterable)。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。执行这个函数,就会返回一个遍历器。

原生默认具备lterator接口的数据结构如下:

  • Array
  • Set
  • Map
  • String
  • arguments对象(伪数组)
  • NodeList对象(伪数组)

对象不支持遍历,对象没有Iterator接口

对象使不具备线性关系的

如何使对象遍历

let obj ={
	0:"asd",
	1:"xczc",
	2:"scasc",
	length:3,//迭代器只能加给线性的有顺序的的对象
	[Symbol.iterator]:Array.prototype[Symbol.iterator]
}
for(let i of obj){
	console.log(obj)
}


let obj2 = {
	code:200,
	name:"obj2"
	list:["aaa","bbb","ccc"],
	[Symbol.iterator](){
		let index = 0
		return{
			next:()=>{
				return {value:this.list[index++],
				done:index>=(this.list.length+1)?true:false}
			}
		}
	}
}

let iter = obj2[Symbol.iterator]()

console.log(iter)

console.log(iter.next())
console.log(iter.next())
console.log(iter.next())

1.11、set结构

它类似于数组,但成员的值都是唯一的,没有重复的值

  1. 初始Set
let s1 = new Set([1,2,3,2,3])
	console.log(s1)
	arr1 = [...s1]//可以转为数组
	arr2 = Array.from(s1)
	
let s2 = new Set()
	s2.add(1)
	s2.add(2)
	s2.add(3)
	console.log(s2)
for(let i of s1){
	console.log(i)
}
  1. set实例属性和方法
  • Set.prototype.size获取set的成员总数
  • Set.prototype.add可以添加到set中(可以链式增加)
  • Set.prototype.has可以判断是否存在某个值在set中
  • Set.prototype.delete可以删除set中的某个值
  • Set.prototype.clear可以清除set中的值
  1. 遍历
  • Set.prototype.keys()返回键名的遍历器
  • Set.prototype. values()返回键值的遍历器
  • Set.prototype.entries()返回键值对的遍历器
  • Set.prototype.forEach()遍历每个成员
    • set中键名键值相同
let list = [1,2,2,"kerwin","kerwin",[1,2],[3,4],[1,2],{name:"kerwin"},{age:100},{name:"kerwin"}]

function uni(arr){
	let res = new set()
	return arr.filter((item)=>{
		//判断has trun false 
		//没有 return true 
		let id = JSON.stringify(item)
		if(res.has(id)){
			return false
		}else{
			res.add(id)
			return true
		}
	})
}

console.log(uni(list))

1.12、Map结构

类似于对象,也是键值对的集合,但是"键"的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

  1. 初识Map
let ml = new Map
m1.set("name" , "kerwin")
m1.set({a: 1},"大连")
	
console.1og(m1)

let m2= new Map([
	["name" , "kerwin"],
	[{a: 1}"大连"]
	])
console.log(m2)
  1. 实例的属性和方法
    size:返回Map结构的成员总数。
    Map. prototype.set(key,value):添加key对应得value,返回Map结构本身。
    Map. prototype.get(key):获取key对应的value
    Map. prototype.delete(key):删除某个键(键名+键值)
    Map. prototype.has(key):某个键是否在当前Map对象之中。
    Map. prototype.clear(key):清空Map对象
    • 用get方法获取对象类型时,需要先用一个变量定义这个函数,再获取这个变量
  2. 遍历
    Map.keys:遍历Map对象的键名
    Map.value:遍历Map对象的键值
    Map.entries遍历Map对象的键名+键值
  • 以上的方法需要使用for ...of的方法

Map.foreach:某个键是否在当前Map对象之中。

  • 该方法使用函数的方法

1.13、Proxy代理

Proxy如其名,它的作用是在对象和和对象的属性值之间设置一个代理,获取该对象的值或者设置该对象的值,以及实例化等等多种操作,都会被拦截住,经过这一层我们可以统一处理,我们可以认为它就是"代理器”

拦截获取对象的值

  • 此方法只能拦截一个对象的值
let obj = {}
//参数中第一个是要被拦截的对象,第二个是要被修改的属性,第三个是get和set的方法
Object.defineProperty(obj,"data",{
	get(){
		console.log("get")
	}
	set(){
		console.log("set")
		//设置dom
	}
})
	console.log(obj)
//一次可以拦截多个值
let obj = {}
let proxy = new Proxy(obj,{
		get(target,key){
			console.log("get",target[key])
			return target[key]//get必须有返回值
	}
		set(target,key,value){
			console.log("set",target,key,value)
			if(key==="data"){
				box.innerHTML = value
		}
		target[key] = value
	}
})
let s = new Set()

let proxy = new Proxy(s,{
	get (target,key){
		//判断如果是方法,修正this指向
		let value = target[key]
		if(value instanceof Function){
			//call apply bind
			return value.bind(target)
		}
		return value
	},
	set(){
		console.log("set")
	}
})

1.14、Reflect对象

Reflect可以用于获取目标对象的行为,它与Object类似,但是更易读,为操作对象提供了一种更优雅的方式。它的方法与Proxy是对应的。

  1. 代替Object的一些方法
let obj = {
}
Reflect.defineProperty(obj,"name",{
	value:"asdasf",
	writable:false,//定义这个属性是否可改
	enumerable:false//定义这个属性是否可删除
})
console.log(obj)
  1. 修改某些Object方法的返回结果
Reflect.defineProperty(obj,"name",{
	value:"asdasf",
	writable:false,//定义这个属性是否可改
	enumerable:false//定义这个属性是否可删除
})

//老写法
object.defineProperty(obj,"name",{
	value:"asdasdsdasd"
})
//执行会打断

//新写法
Reflect.defineProperty(obj,"name",{
	value:"asdasdsdasd"
})
//这样写不会被打断
  1. 命令式变为函数行为
let obj = {
	name = "asdsads"
}
//老写法
console.log("name"in obj)//true
//新写法
console.log(Reflect.has(obj,"name"))//true

//老写法
delete obj.name
//新写法
Reflect.deleteProperty(obj,"name")
  1. 配合Proxy
let s = new Set()

let proxy = new Proxy(s,{
	get (target,key){
		//判断如果是方法,修正this指向
		let value =Reflect.get(target,key)
		if(value instanceof Function){
			//call apply bind
			return value.bind(target)
		}
		return value
	},
	set(target,key,value){
		Reflect.set(...arguments)
	}
})

1.15、Promise

Promise是异步编程的一种解决方案,比传统的解决方案回调函数,更合理和更强大。ES56将其写进了语言标准,统一了用法,原生提供了Promise对象。

  • 指定回调函数方式更灵活易懂。
  • 解决异步回调地狱的问题。
let pro = new Promise(function(resolve,reject){
	//执行器函数
	setTimeout(()=>{
		resolve()//执行“有了”
		reject()//执行“没了”
	},1000)
})
//第一种
pro.then(()=>{
	//如果true则执行这个
	console.log("有了")
},()=>{
	//如果false则执行这个
	console.log("没了")
})

//第二种
pro.then(()=>{
	//如果true则执行这个
	console.log("有了")
}).catch(()=>{
	//如果false则执行这个
	console.log("没了")
})

1.15.1、回调地狱

  • 当一个回调函数嵌套一个回调函数的时候
  • 就会出现一个嵌套结构
  • 当嵌套的多了就会出现回调地狱的情况
  • 比如我们发送三个ajax请求
    • 第一个正常发送
    • 第二个请求需要第一个请求的结果中的某一个值作为参数
    • 第三个请求需要第二个请求的结果中的某一个值作为参数

1.15.2、Promise对象的状态

Promise对象通过自身的状态,来控制异步操作。Promise 实例具有三种状态。

  1. 异步操作未完成(pending)
  2. 异步操作成功(fulfilled)
  3. 异步操作失败(rejected)

这三种的状态的变化途径只有两种。

  1. 从“未完成”到“成功”
  2. 从“未完成”到“失败”

一旦状态发生变化,就凝固了,不会再有新的状态变化。这也是 Promise这个名字的由来,它的英语意思是"承诺",一旦承诺成效,就不得再改变了。这也意味着,Promise实例的状态变化只可能发生一次。
因此,Promise的最终结果只有两种。

  1. 异步操作成功,Promise 实例传回一个值(value),状态变为fulfilled。
  2. 异步操作失败,Promise 实例抛出一个错误(error),状态变为rejected。
let pro = new Promise(function(resolve,reject){
	//执行器函数
	setTimeout(()=>{
		resolve(1000)//执行“有了”
		reject()//执行“没了”
	},1000)
})
pro.then((res)=>{
	//如果true则执行这个
	console.log("有了")
	//如果return 非promise类型则自动转换为pending-fulfilled,则return什么则第二个then表达什么
	//如果return promise类型,根据这个新类型的promise对象的结果,决定pending-fulfilled pending-rejected
}).then((res)=>{
	//如果true则执行这个
	console.log("有了")
}).catch(()=>{
	//如果false则执行这个
	console.log("没了")
})

Promise.all

  • 接受一个数组,当每一个promise都有结果之后可以以数组的方式来表达
let pro1 = new Promise(function(resolve,reject){
	//执行器函数
	setTimeout(()=>{
		resolve(1000)
	},1000)
})
let pro2 = new Promise(function(resolve,reject){
	//执行器函数
	setTimeout(()=>{
		resolve(2000)
	},2000)
})
let pro3 = new Promise(function(resolve,reject){
	//执行器函数
	setTimeout(()=>{
		resolve(3000)
	},3000)
})

promise.all([pro1,pro2,pro3]).then(res=>{
	console.log(res)
}).catch(err=>{
	console.log(err)	
})

Promise.race

  • 只表达最快的那个promise对象
let pro1 = new Promise(function(resolve,reject){
	//执行器函数
	setTimeout(()=>{
		resolve(1000)
	},1000)
})
let pro2 = new Promise(function(resolve,reject){
	//执行器函数
	setTimeout(()=>{
		resolve(2000)
	},2000)
})
let pro3 = new Promise(function(resolve,reject){
	//执行器函数
	setTimeout(()=>{
		resolve(3000)
	},3000)
})

promise.race([pro1,pro2,pro3]).then(res=>{
	console.log(res)
}).catch(err=>{
	console.log(err)	
})

1.16、Generator函数

Generator函数是ES6提供的一种异步编程解决方案
Generator函数是一个状态机,封装了多个内部状态。
执行Generator函数会返回一个遍历器对象,也就是说,Generator函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历Generator函数内部的每一个状态。

  1. 基本语法
function *gen({
	console.log(1)
	yield;
	console.1og(2)
	yield;
	console.log(3)
}
let g = gen()
g.next()
g.next()
g.next()

产出

function *gen({
	console.log(1)
	yield "asd";//产出
	console.1og(2)
	yield "xzc";
	console.log(3)
}
let g = gen()
let res1 = g.next()
	console.log(res1)
let res2 = g.next()
	console.log(res2)
let res3 = g.next()
	console.log(res3)

for(let i of g){
	console.log(i)
}

next的用法

function *gen(){
let res1 = yield "aaa"//产出
console.log("gen内部",res1)
let res2 = yield "bbb"
console.log( "gen内部",res2)
}
let g = gen()
let res1 = g.next("传入-11111")//遇到yield会停止
	console.log(res1)
let res2 = g.next("传入-22222")
	console.log(res2)
let res3 = g.next("传入-33333")
console.log(res3)



//自动版本
function *gen(){
let res1 = yield "aaa"//产出
console.log("gen内部",res1)
let res2 = yield "bbb"
console.log( "gen内部",res2)
}
function AuutoRun(gen){
	let g =gen()
	function next(data){
		let res = g.next(data)
		if (res.done)return
		res.value.then(function(data){
			next(data)
		})
	}
}

1.17、Class语法

类的写法

class Person {
	constructor (name ,age){
		this. name = name;
		this.age = age;
	}//在constructor中放构造函数的实例化的属性
	say(){
		console.1og(this.name , this.age)
	}
}
let obj = new Person("kerwin",100)
console.log(obj)

get set拦截

class Person {
	constructor (name ,age){
		this. name = name;
		this.age = age;
	}
	get location(){
		console.log("get")

	}
	set location(data){
		console.log("set",data)
	}
}




class Person{
	constructor(name,age,id)
		this.name = name;
		this.age  =age;
		this.ele = document.querySelector(`#${id}`)
}
get html(){
	return this.ele.innerHTML
}
set html(data){
	this.ele.innerHTML = data.map(item=>`<li>${item}</li>`).join("")
}
let obj = new Person("asds",100,""list)

静态属性,静态方法

  • 在所需静态属性和方法前加上static
  • 无法通过class直接访问
  • 通过类名.属性的方式访问
class Person {
	static myname = "person类的名字"
	static mymethod = function(){
		console.log("mythod")
	}
	constructor(name,age){
		this.name = name
		this.age = age
	}
	age(){
		console.log(this.name,this.age)
	}
}

let obj = new Person("asdasd",100)
	console.log(Person. myname)
	Person.mymethod()

1.18、Class继承

  • 继承前面已经有过的代码
  • 父类的静态方法也能继承
class Person {
	static myname = "person类的名字"
	static mymethod = function(){
		console.log("mythod")
	}
	constructor(name,age){
		this.name = name
		this.age = age
	}
	age(){
		console.log(this.name,this.age)
	}
}


class Student extends Person{
	constructor(name,age,score){
		super(name,age)//调用被继承类的constructor
		this.score = score
	}
	//增加自己的方法
	say(){
		super.say()//会找到父类元素上的原型
		console.log(this.name,this.age,this.score)
	}
	getScore(){
		console.log(this.score)
	}
}
Let obj = new Student("kerwin" ,100,155)
<div class="box1">
	<h1></h1>
	<ul></ul>
</div>
<div class="box2">
	<h1></h1>
	<img>
	<ul></ul>
</div>
<script>
var data1 = {
	title:“体育",
	list:["体育-1""体育-2""体育-3"]
}
var data2 = {
	title:“综艺",
	img:"asdsadsad"
	list:["综艺-1""综艺-2""综艺-3"]
}

class CreatBox{
	constructor(select,data){
	this.ele = document.querySelector(seLect)
	this.title = data.title
	this.list = data.list
	this.render()
}
	render(){
		Let oh1 = this.ele.querySelector("h1")let oul
		this.ele.queryselector("ul")
		oh1.innerHTML -= this.title
		oul.innerHTML ·= this.list.map(item=>
		`<li>$(item}</li>`
		).join("")	
	}
}
new CreatBox(".box1",data1)

cLass CreateImgBox extends CreatBox{
	constructor(seLect,data){
		super(select,data)
		this.imgUrl = data.url
		this.render()
	}
	render(){
		super.render()
		let oimg = this.ele.queryselector( "img")
		oimg.src= this.imgUrl
	}
}

new CreateImgBox(".box2",data2)

</script>

1.19、Module语法

  1. 异步加载
  • js文件引入位置在body标签之前
  • 加deger,async,可以是js文件异步加载
    • 其中async执行比较靠后,deger比较靠前

使用模块化语言处理

  • 在所引入js文件的script标签上加上type="module"
  1. 私密不漏

希望方法里面的嵌套的某些方法不被看见

  • 在script标签中加上type="module"
  • 在需要引入的js文件中加上exprot default 导出函数名(如果想到处多个函数,可以用一个对象的方式将两个函数包起来 )
  • 在script标签中加上import 导出函数名(可以随机写一个) from '文件的相对路径'
  1. 重名不怕
  • 与上述方法一样引出js文件就不怕几个文件中有相同名字的函数
  1. 依赖不乱
  • 在哪里用函数就在哪里导入函数,可以避免未定义而提前用

第二种导出方案

  • 在js文件中加入export{函数名}也可以在没一个函数前面加export
  • 在script标签中加上import {函数名} from 'js文件相对路径'
  • 不同文件引入相同函数时,需要进行重命名即import {函数名 as 另一个名字} from 'js文件相对路径'
  • 如果js文件中需要引入很多函数可以以import *as 重新命名 from 'js文件相对路径'

1.20、NdoeJS中的模块化

JavaScript现在有两种模块。一种是ES6模块,简称ESM;另一种是Common]S模块,简称CJS。
Common]S模块是Node.js专用的,与ES6模块不兼容。语法上面,两者最明显的差异是,Common]S模块使用require()和module.exports,ES6模块使用import和export。

  • 将js扩展名改为mjs即可在NdoeJS中使用ES6规范
    写法1:
export default A1
import a1 from "./1.js"

写法2:

export {A1,A2}
import {A1,A2} from "./1.js"
import {A1 as a1,A2 as a2} from "./1.js"
import * as obj from "./1.js"

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值