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声明变量
- let是块级作用域,只作用于当前块的作用域内
- 一个变量名称只能定义一次,不允许重复声明
- 必须先定义在使用, 使用必须在定义之后
- 不与顶层变量挂钩
let myage = 100
console.log(window.myage)//无法访问到
1.2.2、const声明常量
- 定义后不能改变,并且使用comst必须赋值
- 不能重复定义
- const是块级作用域,只作用于当前块的作用域内
- 必须先定义在使用, 使用必须在定义之后
- 不与顶层变量挂钩
- 改变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、字符串扩展
- 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
- 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、数值扩展
- 二进制和八进制表示法
let count1 = 100
let count2 = 0x100
let count3 = 0o100
let count4 = 0b100
- 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。
- 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
- 极小常量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
- 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
- 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、数组扩展
- 扩展运算符
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]
- Array.from
将类数组对象转换为真正数组
function test(){
console. log(Array.from(arguments))
}
test(1,2,3)
let oli = document. queryselectorA11("li")
console.log(Array.from(oli))
- Array.of
将一组值转化为数组,即新建数组
let arr1 = Array(3)
console. 1og(arr1)// [,,]
let arr2 = Array.of(3)
console.log(arr2)//[3]
- 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更新的
- fill方法
快速填充
let arr = new Array(3).fill("shangsan")//内容会被填充为shangsan
console.log(arr)
let arr1= [1,2,3]
console.log(arr1.fill("asd",1,2))//快速替换第一个参数是要添加的元素,第二个参数是开始的位置,第二个元素是结束的位置
- 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、对象扩展
- 对象简写
let name = "moduleA"
let obj ={
name ,//name:name
test1(){
},
test2(){
}
}
- 对象属性
let name = "a"
let obj = {
[name]:"asd"
}
//此时[name]=a
let name = "moduleA"
let obj ={
name,
[name+"test"](){
},
[name+"test"](){
}
}
//此时改变name的值就能改变对象中的属性值
- 扩展运算符
...
(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值
- 快速合并对象
Object.assign
let obj1 = {
name = "asd"
}
let obj2 ={
name ="wsx"
}
let obj3 ={
age : 100
}
console.log=(Object.assign(obj1,obj2,obj3))//实际上是以第一个对象为基准,把后面两个对象给加进去,所以会导致第一个对象发生变形
- 判断两个值是否相同
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、常规属性值
- 参数默认值
function ajax(url,method="get",async="true"){
console.log(url,method,async)
}
ajax("/aaa")
- rest参数 剩余参数
function test(...data){
console.log(data)
}
test(1,2,3,4,5,6)
- name 属性
- 拿到函数的名字
function test(...data){
console.log(data)
}
test(1,2,3,4,5,6)
console.log (test,name)//值为test
1.9.2、箭头函数
- 写法简洁
//常规
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)。
- 使用Symbol作为对象属性名
let name = symbo1()
let age = symbo1()
var obj={
[name] : "kerwin",
[age] : 100
}
console.log(obj[name])//teichui
- Symbol()函数可以接受一个字符串作为参数,表示对Symbol实例的描述。这主要是为了在控制显示,比较容易区分
let name = symbo1("name")
let age = symbo1("age")
var obj={
[name] : "kerwin",
[age] : 100
}
console.log(obj)
- Symbol不能进行运算
- 隐式转换为布尔类型
var s1 = symbol()
if(si){
console.log("aaa")
}
- 整体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的作用有三个:
- 为各种数据结构,提供一个统一的、简便的访问接口;
- 使得数据结构的成员能够按某种次序排列;
- 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结构
它类似于数组,但成员的值都是唯一的,没有重复的值
- 初始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)
}
- set实例属性和方法
Set.prototype.size
获取set的成员总数Set.prototype.add
可以添加到set中(可以链式增加)Set.prototype.has
可以判断是否存在某个值在set中Set.prototype.delete
可以删除set中的某个值Set.prototype.clear
可以清除set中的值
- 遍历
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结构
类似于对象,也是键值对的集合,但是"键"的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
- 初识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)
- 实例的属性和方法
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方法获取对象类型时,需要先用一个变量定义这个函数,再获取这个变量
- 遍历
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是对应的。
- 代替Object的一些方法
let obj = {
}
Reflect.defineProperty(obj,"name",{
value:"asdasf",
writable:false,//定义这个属性是否可改
enumerable:false//定义这个属性是否可删除
})
console.log(obj)
- 修改某些Object方法的返回结果
Reflect.defineProperty(obj,"name",{
value:"asdasf",
writable:false,//定义这个属性是否可改
enumerable:false//定义这个属性是否可删除
})
//老写法
object.defineProperty(obj,"name",{
value:"asdasdsdasd"
})
//执行会打断
//新写法
Reflect.defineProperty(obj,"name",{
value:"asdasdsdasd"
})
//这样写不会被打断
- 命令式变为函数行为
let obj = {
name = "asdsads"
}
//老写法
console.log("name"in obj)//true
//新写法
console.log(Reflect.has(obj,"name"))//true
//老写法
delete obj.name
//新写法
Reflect.deleteProperty(obj,"name")
- 配合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 实例具有三种状态。
- 异步操作未完成(pending)
- 异步操作成功(fulfilled)
- 异步操作失败(rejected)
这三种的状态的变化途径只有两种。
- 从“未完成”到“成功”
- 从“未完成”到“失败”
一旦状态发生变化,就凝固了,不会再有新的状态变化。这也是 Promise这个名字的由来,它的英语意思是"承诺",一旦承诺成效,就不得再改变了。这也意味着,Promise实例的状态变化只可能发生一次。
因此,Promise的最终结果只有两种。
- 异步操作成功,Promise 实例传回一个值(value),状态变为fulfilled。
- 异步操作失败,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函数内部的每一个状态。
- 基本语法
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语法
- 异步加载
- js文件引入位置在body标签之前
- 加deger,async,可以是js文件异步加载
- 其中async执行比较靠后,deger比较靠前
使用模块化语言处理
- 在所引入js文件的
script
标签上加上type="module"
- 私密不漏
希望方法里面的嵌套的某些方法不被看见
- 在script标签中加上
type="module"
- 在需要引入的js文件中加上
exprot default 导出函数名
(如果想到处多个函数,可以用一个对象的方式将两个函数包起来 ) - 在script标签中加上
import 导出函数名(可以随机写一个) from '文件的相对路径'
- 重名不怕
- 与上述方法一样引出js文件就不怕几个文件中有相同名字的函数
- 依赖不乱
- 在哪里用函数就在哪里导入函数,可以避免未定义而提前用
第二种导出方案
- 在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"