Articles19
Tags0
Categories0

Es6语法

es6语法

1.解构赋值

数组:

let a,b,c,cc,rest;
[a,b]=[1,2]
//a:1,b:2
[a,b,...rest]=[1,2,3,4,5,6]
//a:1,b:2,rest:[3,4,5,6]
[a,b,c=3]=[1,2]
//a:1,b:2,c:3
[a,b,cc]=[1,2]
//a:1,b:2,cc:undefind
let aa=1;
let bb=2;
[aa.bb]=[bb,aa]
//aa:2,bb:1
function f(){
return [1,2]
}
let fa,fb;
[fa, fb]=f();
//fa:1.fb:2

对象:

let a,b;
({a,b}={a:1,b:2})
//a:1,b:2
let o={p:42,q:true};
let{p,q}=o
//p:42,q:true
let {aa=10,bb=5}={aa:3}
//aa:3,bb:5
let metaData={
title:'abc',
test:[{
title:'test',
desc:'description'
}]
}
let {title:estitle,test:[{title:cntitle}]}=metaData
//estitle:abc
//cntitle:test

2.正则表达式

//es5的正则表达式
let regex=new RegExp('xyz','i')
//或
let regex=new RegExp(/xyz/i)
//es6:
let regex3=new RegExp(/xyz/ig,'i')
//regex3.flags:i
//flags:获取正则表达式的修饰符

关于正则表达式的修饰符

i:不区分大小写

g:全局匹配,第二次匹配是从上一次匹配的结果之后开始寻找,可以忽略中间的任何字符直至找到符合的

s:默认的圆点 . 是匹配除换行符 \n 之外的任何单字符,加上s之后, . 中包含换行符

y(es6):全局匹配,第二次匹配是从上一次匹配的结果之后开始寻找,不可以忽略中间的任何字符,必须是下一个也符合才可以被匹配,否则返回null

//g与y的区别的例子
let s="bbb_bb_b"
let a1=/b+/g
let a2=/b+/y
console.log('one',a1.exec(s),a2.exec(s));
//one ['bbb',index:0,input:'bbb_bb_b']  ['bbb',index:0,input:'bbb_bb_b']
console.log('two',a1.exec(s),a2.exec(s));
//two ['bb',index:4,input:'bbb_bb_b'] null
console.log(a1.sticky,a2.sticky)
//false true
//sticky:此属性用来检测正则表达式是否使用y修饰符。

u:unicode编码

console.log('u-1',/^\uD83D/.test('\uD83D\uDC2A'))
/true,'\uD83D\uDC2A'视为两个字符
console.log('u-2',/^\uD83D/u.test('\uD83D\uDC2A'))
//false,'\uD83D\uDC2A'视为一个字符
console.log(/\u{61}/.test('a'))  //false
console.log(/\u{61}/u.test('a'))  //true a的unicode编码是61

.:匹配任意字符,但超过两个字节就没法识别(以及换行符,回车符,行/段分隔符)

console.log('\u{20887}') //𠢇
console.log('u',/^.$/.test('𠢇')) //false
console.log('u-2',/^.$/u.test('𠢇')) //true 加u可以判断有大于两个自己的字符
console.log('test',/𠢇{2}/.test('𠢇𠢇')) //false
console.log('test-2',/𠢇{2}/u.test('𠢇𠢇')) //true

字符串的处理

charCodeAt:取两个字节,codePointAt:取四个字节

console.log('a','\u0061') // a,a
console.log('s','\u20887')
//a7,因为超出了一个字符,当成两个字符:2088和7
console.log('\u{20887}') //𠢇
let s="𠢇"
console.log('length',s.length)
//length 2
console.log('0',s.charAt(0))//取字符,打印出来是乱码
console.log('1',s.charAt(1)) //打印出来是乱码
console.log('at0',s.charCodeAt(0)) //取码值 55362
console.log('at0',s.charCodeAt(1)) //取码值 56455
let s1="𠢇a";
console.log('code0',s1.codePointAt(0))
//取第一个字符’𠢇‘的编码
//code0 133255
console.log('code1',s1.codePointAt(0).toString(16))
//以16进制的形式取第一个字符’𠢇‘的编码
//code1 20887
console.log('code2',s1.codePointAt(1)) 
//若没有4个字节,就取后面两个字节
//code2 56445,’𠢇’的后两个字节
console.log('code3',s1.codePointAt(2)) 
//97 a的编码

es5不能处理大于2个字节的字符,会乱码,但es6可以输出

console.log(String.fromCharCode('0x20bb7'));
//乱码
console.log(String.fromCodePoint('0x20bb7'));
//输出正常

es5和es6的遍历

let str='\u{20bb7}abc'
//es5的遍历
for(let i=0;i<str.length;i++){
console.log('es5',str[i])
//前2个乱码,后面正常输出
}
//es6的遍历,正常处理大于2个字节的字符
for(let code of str){
console.log('es6',code)
}
//打印结果:
//es6 𠮷
// es6 a
// es6 b
// es6 c

判断是否有某个字符:

let str='string'
console.log('includes',str.includes('r')) //true
console.log('start',str.startsWith('str')) //true
console.log('start',str.endsWith('ing')) //true

重复:

console.log(str.repeat(2))
//repeat(重复次数)

模板字符串:把数据和结果拼成带模板的字符串

let m=`i am ${name},${info}`

es7的草案,需要打补丁才能使用

npm i babel-polyfill --save-dev
import 'babel-polyfill'
console.log('1',padStart(2,'0'))
//向前补充长度,就是‘1’得有两个字节,如果没有,就用‘0'补充
//01
console.log('1',padEnd(2,'0'))
//向后补充长度
//10

标签模板:过滤信息,只留下模板,防止攻击,可以用于处理多语言转化

let user={
name:'list',
info:'hello'
}
console.log(abc`i am ${user.name},${user.info}`)
// i am ,,,listhello
function abc(s,v1,v2){
console.log(s,v1,v2)
return s+v1+v2
}
// ["i am ", ",", "", raw: Array(3)] "list" "hello"

String.raw:把斜杆进行转义,即在斜杆之前再加斜杆

console.log(String.raw`Hi\n${1+2}`)
//Hi\n3
console.log(Hi\n${1+2}`)
//Hi
//3

3.数值扩展

二进制以0b开头(b可以大小写),八进制 0o(o可以大小写)

console.log(0b101011) //43
console.log(0o767) //503

Number.isFinite :是否有尽

console.log('NaN',Number.isFinite(NaN))//false

isInteger:判断是否是整数

console.log('25.0',Number.isInteger(25.0)) //true

es6的数在-2的53次方到2的53次方之间

console.log(Number.MAX_SAFE_INTEGER)
//常量,表示数的上限,下限:MIN_SAFE_INTEGER
//判断是否在-2的53次方到2的53次方之间
Number.isSafeInteger(数字)

Math.trunc():判断带小数的数字的整数部分并返回

console.log(Math.trunc(4.1)) //4
console.log(Math.trunc(4.9)) //4

Math.sign():判断是否是正数,负数,0

console.log('-5',Math.sign(-5)) //-1
console.log('0',Math.sign(0)) //0
console.log('5',Math.sign(5)) //1
console.log('50',Math.sign('50')) //1
//把字符转化为数字
console.log('foo',Math.sign('foo')) //NaN
//字符串:NAN

Math.cbrt():立方根的计算

Math.cbrt(-1) //-1
Math.cbrt(8) //2

其他还有三角函数和对数的用法

4.数组扩展

let arr=Array.of(3,4,7,8,11)
console.log('arr',arr) // [3,4,7,8,11]
let empty=Array.of()
console.log('empty',empty) // []

把伪数组或集合转化为数组

<p>葫芦娃</p>
<p>哪吒</p>
<p>十万个冷笑话</p>
let p=document.querySelectorAll('p')
//p标签的集合
let pArr=Array.from(p)
//集合变成数组
pArr.forEach(function(item){
console.log(item.textContent);
//拿到item的文本
//打印结果:
//葫芦娃 哪吒 十万个冷笑话
})
console.log(Array.from([1,3,5],function(item){
return item+2
}))
//[3, 5, 7]

数组内容替换

console.log('fill-7',[1,'a',undefined].fill(7))
//[7,7,7],数组全部替换成7
console.log('fill-7',['a','b','c'].fill(7,1,3))
//表示替换成7,起始位置是1,结束位置是3
//['a',7,7]

返回所有的下标或值的集合

for(let index of ['1','c','ks'].keys()){
console.log('ky',indexs)
}
//ky 0
//ky 1
//ky 2
for(let value of ['1','c','ks'].values()){
//取对应的值
console.log('value:',value)
}
//value:1
//value:c
//value:ks
//以上方法存在兼容性问题
for(let[indx,value] of ['1','c','ks'].entries()){
//不存在兼容性问题
console.log('value:',index,value)
}
//value:0 1
//value:1 c
//value:2 ks

将当前数组内部指定位置的成员复制到指定位置上

console.log([1,2,3,4,5].copyWithin(0,3,4))
// [4, 2, 3, 4, 5]
//第一个参数:从哪个位置开始替换
//第二个参数:从哪个位置读取数据
//第三个参数:从哪个位置截至
//这个代码的意思是:从下标0开始,到下标4之前截至,即[1,2,3,4]
//替换成下标3的值即4,替换值只有一个,结果是将下标0替换成下标3

查找一个元素是不是在一个数组中

console.log([1,2,3,4,5,6].find(function(item){
return item>3
}))
//4,只会找第一个满足条件的成员
console.log([1,2,3,4,5,6].findIndex(function(item){
return item>3
}))
//3,返回第一个满足条件的成员的下标
//解决NAN的状况
console.log('number',[1,2,NAN].includes(1));
//true
console.log('number',[1,2,NAN].includes(NAN));
//true

5.函数扩展

函数默认值



function test(x,y='so'){
console.log(x,y)
}
test('ok')
//ok so
//有默认值的变量后面不能有没有默认值的变量
//如test(x,y='so',c)会报错
let a='test'
function test2(a,b=a){
console.log(a,b)
}
test2('kid')
//kid kid
test2()
//undefind undefind
function test3(c,b=a){
console.log(c,b)
}
test('kid')
//kid test

将所有参数转化为数组

function test3(...args){

for(let v of arg){

console.log(v)

}

test3(1,2,3,4,'a')

将数组转化成离散的值

console.log(...[1,2,4])
//1 2 4
console.log(a,...[1,2,4])
//a 1 2 4

尾调用:函数的最后一句话是不是函数

function tail(x){
console.log('tail',x)
}
function fx(x){
return tail(x)
}
fx(1)//1

6.对象扩展

表示法

let o=1;
let k=2;
let a='b';
let es6={
o,
k,
[a]: 'c',//属性表达式,等价与:b:'c'
hello(){
console.log('hi')
}//对象中的方法
}

拷贝

console.log('字符串',Object.is('abc','abc'))//等价与'abc'==='abc',true
console.log('字符串',Object.is([],[]))//数组是引用,值相等,但地址不同,false
console.log(Object.assign({a:'a'},{b:'b'}))
//{a:'a',b:'b'}
//第一级属性深拷贝,以后级别属性浅拷贝 ,将后面参数的属性复制到第一个
//只有自身对象的属性,不可枚举的属性
//遍历输出
for(let [key,value] of Object.entries({k:1,u:9})){
console.log(key,value)
}

补充:深浅拷贝

浅拷贝:将原对象或原数组的引用直接赋给对象,新数组/对象只是原对象的一个引用

深拷贝:创建一个新的对象和数组,将原对象的各项属性的值(数组的所有元素)拷贝过来,是值不是引用

深拷贝的方法:

(1)slice:从已有的数组中截取一部分元素片段组成的新数组,不改变原来的数组!

(2)concat() 方法用于连接两个或多个数组。( 该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。)

https://blog.csdn.net/qq_39207948/article/details/81067482

针对Object.assign的例子:

//例子1:
let s={name:{asd:'123'}}
let d=Object.assign({},s)
d.name.asd='123456'
console.log(d,s)
//{name:{asd: "123456789"}}
//{name:{asd: "123456789"}}



//例子2
let o={name:{asd:'123'}}
let p=Object.assign({},s)
p.name = '123456789'
console.log(p, o)
//{name: "123456789"}
//{name: {asd: "123"}}

7.Symbol

提供独一无二的值

//声明
let a1=Symbol()
//若想要2个Symbol里面的值相等
let a2=Symbol.for('a2')
let a3=Symbol.for('a2')
console.log(a2===a3)//true

取值:

let a1=Symbol.for('abc')
let obj={
[a1]: '123',
'abc':345,
'c':456
}
//采用Symbol的对象属性是无法通过Object.entries等常规方法取得他的值的
//取值
Object.getOwnPropertySymbols(obj).forEach(function(item){
console.log(obj[item])
})
//123
//getOwnPropertySymbols(obj):返回的是一个数组

Reflect.ownKeys(obj):返回的结果包含了symbol的key值作为属性和非symbol的属性的数组

8.数据结构

set:array,集合中的元素是不能重复的

map:object,key可以是任何形式的值

set

定义:

let list=new Set();
list.add(5)
list.add(7)
console.log(list) // Set(2) {5, 7}
console.log(list.size)  //长度  2
let arr=[1,2,3,4,5]
let list2=new Set(arr)
//长度:5
//元素必须是唯一的
ist.add(7)
console.log('list',list)//Set(2) {5, 7}
//相同的不会报错,只会不添加
//用于去重

去重(不会做数据类型的转化):

let arr=[1,2,3,1,2]
let list2=new Set(arr)
console.log(list2)

方法:

let arr=['add','delete','clear','has']
let list=new Set(arr)
console.log('has',list.has('add'))//true
list.delete('add')
list.clear()
for(let key of list.keys()){
console.log('keys',key)
//add delete clear has
}
for(let key of list.values())){
console.log('keys',key)
//add delete clear has
}
for(let key of list)){
console.log('keys',key)
//add delete clear has
}
for(let [key,value] of list.entries())){
console.log('keys',key,value)
}
//add add
//delete delete
//clear clear
//has has
list.forEach(function(item){
console.log(item)})

WeakSet

与Set的区别:支持的数据类型不一样,WeakSet元素只能是对象,是弱引用,不会检测是不是被垃圾回收站引用了

/没有clear的方法

没有size

不能遍历

let weakList=new WeakSet();
let arg={
weakSet.add(arg)
}

Map

{

let map=new Map();
let arr=['123']
//添加元素
map.set(arr,456)
console.log(map,map.get(arr))
//Map(1) {Array(1)=>456}
//key:['123']
//value:456
//456
let map=new Map([['a',123],['b',456]])
//a=>123
//b=>456
//长度:map.size
//删除:map.delete('a')
//清除:map.clear()

}

WeakMap

let weakmap=new WeakMap()

Map、set与Array的对比

let map=new Map();
let set=new Set();
let array=[];

//增

map.set('t',1)
set.add({t:1});
array.push({t:1}

//查

let map_exist=map.has('t')//true
let set_exist=set.has({t:1})//false,若要为true,值则必须被引用过
let array_exist=array.find(item=>item.t)//返回当前对象

//改

map.set('t',2)
set.forEach(item=>item.t?item.t=2:'')
array.forEach(item=>item.t?item.t=2:'')

//删

map.delete('t')
set.forEach(item=>item.t?set.delete(item):'')
let index=array.findIndex(item=>item.t)
array.splice(index,1)

)

Map、set与Object的对比

//先定义item,使得值有被引用
let item={t:1}
let map=new Map();
let set=new Set()
let obj={};

//增

map.set('t',1)
set.add(item)
obj['t']=1

//查

let map_exist=map.has('t')//true
console.log(set.has(item))
console.log('t' in obj)

//返回当前对象

//改

map.set('t',2)
item.t=2//因为set存的是引用
obj['t']=2
array.forEach(item=>item.t?item.t=2:'')

//删

map.delete('t')
set.delete(item)
delete obj['t']

}

9.Proxy和Reflect

proxy:代理,用户与最真实的对象

reflect:反射

proxy

let obj={
time:'2017-01',
name:'net',
_r:123
}
//作为一个原始的对象来存储最真实的数据
let monitor=new Proxy(obj,{
//代理的方法
//拦截对象属性的读取
get(target,key){
return target[key].replace('2017','2018')
//把所有2017替换成2018
}
set(target.key,value){
//只允许修改name的属性
if(key==='name'){
return target[key]=value
}else{
return target[key]
}
}
//拦截key in object操作

has(target,key){
//自暴露name属性,其他的不暴露
if(key==='name'){
return target[key]
}else{
return false
}
}
//拦截delete
deleteProperty(target,key){
//只允许删除下划线开头的
if(key.indexOf('_')>-1){
delete target(key);
return true
}else{
return target[key]
}
}
//拦截Object.getOwnOropertySymbols,Object.getOwnOropertyNames
OwnKeys(target){
//保护time属性
return Objet.keys(target).filter(item=>item!='time')
}
})
//monitor是映射这个对象,用户访问的是monitor,最终将用户的操作通过Proxy传给原对象obj
console.log(monitor.time) //2018-01
monitor.time='2010';
console.log(monitor.time) //2018-01
monitor.name='zhumeng';
console.log(monitor.name) //zhumeng
console.log('name' in monitor)//true
console.log('time' in monitor)//false
console.log(delete monitor.time)//2018-01
//console.log(delete monitor._r)//true
console.log(Object.keys(monitor))//['name',_r]//time属性被保护起来了

Reflect

let obj={
time:'2017-01',
name:'net',
_r:123
}
console.log(Reflect.get(obj,'time'))
Reflect.set(obj,'name','zhumeng')
Reflect.has(obj,'name')

应用—校验模块

function vaildator(target,vaildator){
return new Proxy(target,{
_vaildator:vaildator,
set(target,key,value,proxy){
if(target.hasOwnProperty(key)){
let va=this._validator[key]
if(!!va(value)){
return Reflect.set(target,key,value,propx)
}else{
throw Error(`不能设置${key}到${value}`)
}
}else{
throw Error(`${key}不存在`)
}
}
}
)
}

//过滤条件

const  personValidators={
name(val){
return typeof val==='string'
}
age(val){
return typeof val==='number'&&val>18
}
}
class Person{
constructor(name,age){
this.name=name;
this.age=age
return validator(this,personValidators)
}
}
const person=new Person('lilei',30)
console.info(person)
person.name=48//报错,不能设置${key}到${value}
}

10.类

class Person{//定义了一个名字为Person的类
    constructor(name,age=9){//constructor是一个构造方法,用来接收参数,age=9:子类重写name属性值
        this.name = name;//this代表的是实例对象
        this.age=age;
    }
    super(props)//supe使得子组件可以修改从父组件继承的参数(props),子类向父类修改 super一定放第一行
    say(){//这是一个类的方法,注意千万不要加上function
        return "我的名字叫" + this.name+"今年"+this.age+"岁了";
    }
}
var obj=new Person("laotie",88);
console.log(obj.say());//我的名字叫laotie今年88岁了
//1.在类中声明方法的时候,千万不要给该方法加上function关键字
//2.方法之间不要用逗号分隔,否则会报错
console.log(typeof Person);//function
console.log(Person===Person.prototype.constructor);//true

实际上类的所有方法都定义在类的prototype属性上。代码证明下:

Person.prototype.say=function(){//定义与类中相同名字的方法。成功实现了覆盖!
    return "我是来证明的,你叫" + this.name+"今年"+this.age+"岁了";
}
var obj=new Person("laotie",88);
console.log(obj.say());//我是来证明的,你叫laotie今年88岁了

还可以通过Object.assign()方法来为对象动态添加方法

Object.assign(Person.protype,{
getName:function(){
 return this.name;
},
 getAge:function(){
        return this.age;
    }
})
var obj=new Person('laotie',88)
console.log(obj.getName());//laotie
console.log(obj.getAge());//88

类的静态方法:

class Parent{
construct(name='xiamu'){
this.name=name
}
// 静态方法:通过类去调用,而不是实例
static tel(){
console.log('tell')
}
}
Parent.tell()
Parent.type='test'//定义静态属性
console.log('静态属性',Parent.type) // 静态属性 test
let v_parent = new Parent();
    console.log(v_parent); // {name: "xiaxaioxian"}  没有tell方法和type属性

11.Promise

原生异步:

let ajax=function(callback){
console.log(执行)
setTimeout(function(){
callback&&callback.call()
},1000)
};
ajax(function(){
console.log('timeout1')
})
//先输出执行再输出timeout1

promise的基本调用:

let ajax=function(){
console.log('执行2');
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve()
},1000)
})
}

ajax().then(
//resolve
function(){
console.log('promise','timeout2')
},function(){
//reject
return 'error'
}
)
//ajax返回一个promise实例,then表示执行下一步
//执行2 promise timeout2
let ajax=function(){
console.log('执行3');
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve()
},1000)
})
}
ajax()
.then(function(){
//再返回一个promise函数。继续下一步
return new Promise(
function(resolve,reject){
setTimeout(function(){
resolve()
},2000)
}
)
}).then(function(){
console.log('timeout3')
})
//执行3     promise timeout2 timeout 3

捕获异常:

let ajax=function(num){
console.log('执行4')
return new Promise(function(resolve,reject){
if(num>5){
resolve()}
else{
throw new Error('出错了')
}
})
}
ajax(6).then(function(){
console.log('log',6)
}).catch(function(err){
console.log('catch',err)
})
//log 6 
ajax(3).then(function(){
console.log('log',6)
}).catch(function(err){
console.log('catch',err)
})
//catch Error

Promise.all:把多个Promise实例当成一个Promise实例,当所有Promise实例都完成后整个promise才算完成,才调用then

应用场景例子:所有图加载完后再显示在页面上

function loadImg(src){
return new Promise((resolve,reject)=>{
let img=doucument.createElement('img');
img.src=src;
img.onload=function(){
resolve(img)
}
img.onerror=function(err){
reject(err);
}
})}
//添加到页面
function showImgs(imgs){
imgs.forEach(function(img){
document.body.appendChild(img);
})
}

Promise.all({
loadImg('http://.......png'),//加载当前图片
loadImg('http://.......png'),
loadImg('http://.......png'),
}).then(showImgs)

Promise.race:多个实例中有一个率先改变,则这个Promise改变,其他的不再响应

应用场景例子:仅有1个图显示在页面上,谁先加载完谁先显示

function loadImg(src){
return new Promise((resolve,reject)=>{
let img=doucument.createElement('img');
img.src=src;
img.onload=function(){
resolve(img)
}
img.onerror=function(err){
reject(err);
}
})}

function showImgs(img){
let p=documnet.createElement('p');
p.appendChild(img)
document.body.appendChild(p)
}

Promise.race({
loadImg('http://.......png'),//加载当前图片
loadImg('http://.......png'),
loadImg('http://.......png'),
}).then(showImgs)

12.Iterator和for…of

//数组内部的Iterator的接口已经定义好了
let arr=['hello','world']
//调用Iterator接口
let map=arr[Symbol.iterator]();
//返回一个对象
console.log(map.next())
console.log(map.next())
console.log(map.next())
//object{value:'hello',done:false}
//object{value:'world',done:false}
//object{value:undefind,done:true}
//done:有下一步状态为false,没有为true

object 自定义使用Iterator接口

let obj={
start:[1,3,2],
end:[7,9,8],
[Symbol.iterator](){
let sele=this;
let index=0;
let arr=self.start.concat(self.end);
let len=arr.length;
return{
next(){
//写遍历的过程
if(index<len){
return{
value:arr[index++],
done:false
}
}else{
return{
value:arr[index++],
done:true
}
}
}
}
}
}
for(let key of obj){
console.log(key)
}
//先遍历start再遍历end
//132798

13.Generator

异步编程的总解决方案

let tell=function* (){
yield 'a';
yield 'b';
return 'c'
};
let k=tell();
console.log(k.next())
console.log(k.next())
console.log(k.next())
console.log(k.next())
//object{value:'a',done:false}
//object{value:'b',done:false}
//object{value:'c',done:false}
//object{value:undefind,done:true}
//调用next,执行一个yield
 let obj={};
  obj[Symbol.iterator]=function* (){
    yield 1;
    yield 2;
    yield 3;
  }
 for(let value of obj){
    console.log('value',value);
  }
// value 1
// value 2
// value 3

循环调用

 let state=function* (){
    while(1){
      yield 'A';
      yield 'B';
      yield 'C';
    }
  }
  let status=state();
  console.log(status.next());
  console.log(status.next());
  console.log(status.next());
  console.log(status.next());
  console.log(status.next());
  //ABCAB

语法糖async写法

 let state=async function (){
    while(1){
      await 'A';
      await 'B';
      await 'C';
    }
  }
  let status=state();
  console.log(status.next());
  console.log(status.next());
  console.log(status.next());
  console.log(status.next());
  console.log(status.next());

14.Decorators

装饰器:是个修改类行为的函数

//只读装饰器定义
let readonly=function(target,name,descriptor){
    descriptor.writable=false;
    return descriptor
  };
class Test{
   @readonly
   time(){
     return '2017-03-11'
   }
 }

let test=new Test();

  // test.time=function(){
  //   console.log('reset time');
  // };
  //无法写,报错,因为装饰器的作用

console.log(test.time());
let typename=function(target,name,descriptor){
    target.myname='hello';
  }

  @typename
  class Test{

  }

  console.log('类修饰符',Test.myname);//hello

第三方库修饰器的js库:core-decorators; npm install core-decorators

15.模块化

//导出一个变量
export let myName="laowang";
//导出多个变量
export {
    myName,
    myAge,
    myfn
}
//引入的时候用{}包裹,名字须相同
import {myfn,myAge,myName} from "./test.js";
//若不想暴露模块当中的变量名字,可以通过as来进行操作:
export {
    myName as name,
    myAge as age,
    myfn as fn
}
import {fn,age,name} from "./test.js";
//如果想要全部引入
import * as info from'...'
//通过*来批量接收,as 来指定接收的名字
console.log(info.fn());//我是laowang!今年90岁了
console.log(info.age);//90
console.log(info.name);//laowang
//一个模块只能有一个默认导出,对于默认导出,导入的名称可以和导出的名称不一致。
export default function(){
    return "默认导出一个方法"
}
import myFn from "./test.js";//注意这里默认导出不需要用{}。
console.log(myFn());//默认导出一个方法
//可以将所有需要导出的变量放入一个对象中,然后通过default export进行导出
export default {
    myFn(){
        return "默认导出一个方法"
    },
    myName:"laowang"
}
import myObj from "./test.js";
console.log(myObj.myFn(),myObj.myName);//默认导出一个方法 laowang
//重命名export和import
/******************************test1.js**********************/
export let myName="我来自test1.js";
/******************************test2.js**********************/
export let myName="我来自test2.js";
/******************************index.js**********************/
import {myName as name1} from "./test1.js";
import {myName as name2} from "./test2.js";
console.log(name1);//我来自test1.js
console.log(name2);//我来自test1.js
Author:shuo
Link:http://yoursite.com/2019/10/14/20191012-es6语法/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可