小伙伴大多数还在使用ES5来进行编写,使用ES5这无可厚非,因为ES5毕竟还是主流,速度也更快,但ES6引入的新特性是ES5无法比拟的,接下来分享一下我掌握的es6 也为自己做个总结
ES6搭建环境(与语法没什么关系 可忽略)
现在的Chrome浏览器已经支持ES6了,但是有些低版本的浏览器还是不支持ES6的语法,这就需要我们把ES6的语法自动的转变成ES5的语法。
webpack是有自动编译转换能力的,除了Webpack自动编译,我们还可以用Babel来完成
只用Babel做很简单的配置哈,想深入的可以观看阮一峰大大的日志
第一步配置 快速构建package.json
npm init -y
安装 babelnpm install -g babel-cli
安装之后 再次安装npm install --save-dev babel-preset-es2015 babel-cli
安装完成之后看看package.json 先 不要慌
"devDependencies": {"babel-cli":"^6.24.1","babel-preset-es2015":"^6.24.1"}
接着在根目录下 新建.babelrc
担心小伙伴懵逼 截个图
在文件中写入下方代码
{"presets":["es2015"],"plugins":[] }
新建src 目录 新建html 与 js ,再新建dist 目录 新建js
注意此时 我们在html中引入的是dist中的js 我们不动dist中的js 编辑src下的js
在src下的js中编辑 使用es6语法
leta=1;console.log(a);
然后我们在终端输入babel src/index.js -o dist/index.js
这句代码意思就是 把src下的index.js 转译到dist下的index.js中 此时我们查看dist下的index.js
此时es5语法的js已经自动生成 控制台也能看到1的输出
每次的编译都需要转换输入命令有点烦,可以配置一下package.json
"scripts": {"test":"echo \"Error: no test specified\" && exit 1","build":"babel src/index.js -o dist/index.js"},
修改好后,以后我们就可以使用 npm run build 来进行转换了。
没学过webpack的小伙伴可以尝试一下环境的安装
正式进入ES6 (想了解前后代码变化可以使用我上面的环境安装,编译之前记得npm run build )
ES6中新的声明方式
1.var:它是variable的简写,可以理解成变量的意思。
2.let:它在英文中是“让”的意思,也可以理解为一种声明的意思。
3.const:它在英文中也是常量的意思,在ES6也是用来声明常量的,常量你可以简单理解为不变的量。
var声明
var在ES6里是用来升级全局变量的,我们可以先作一个最简单的实例,用var声明一个变量a,然后用console.log进行输出。
vara="ES6";window.onload=function(){console.log(a); }
可以看到控制台输出了ES6,这证明var确实是全局的。如果你觉的这个不够直观说明var是全局声明,还可以用区块的方式进行调用测试,先看下面的代码。
vara=2; {vara=3; }console.log(a);
这时打印出来的值是多少那?对,应该是3,因为var是全局声明的。覆盖了上面的2
let局部声明
通过两个简单的例子,我们对var的全局声明有了一定了解。那跟var向对应的是let,它是局部变量声明。还是上面的例子,我们试着在区块里用let声明。
vara=2; {leta=3; }console.log(a);
这时候控制台打印出来的值就是2了。如果我们只在区块里声明,不再外部声明,我们打印a时就会报错,显示找不到变量。
{leta=3;}console.log(a);
有些小伙伴可能会以为输出undefined 其实是报错了 a并没有被声明
有些刚接触JavaScript的小伙伴会疑惑了,我感觉let还没有var好用,其实let是防止你的数据污染的,在大型项目中是非常有用处的。现在看一个循环的例子,我们来看一下let的好处。
用var声明的循环
for(leti=0;i<10;i++){console.log('循环体中:'+i); }console.log('循环体外:'+i);
你执行时会发现控制台报错了,找不到循环体外的i变量。通过两种声明的比较,可以明白let在防止程序数据污染上还是很有用处的。我们要努力去习惯用let声明,减少var声明去污染全局空间,在vue的使用中也要注意这点。
const声明常量
在程序开发中,有些变量是希望声明后在业务层就不再发生变化了,简单来说就是从声明开始,这个变量始终不变,就需要用const进行声明。
consta="ES6";vara='ES6';console.log(a);
在编译这段代码的过程中,你就会发现已经报错,无法编译了,原因就是我们const声明的变量是不可以改变的。const是很好理解的,我就不作过多的解释说明了。
ES6变量的解构赋值
简单的数组解构
以前,为变量赋值,我们只能直接指定值。比如下面的代码:
leta=0;letb=1;letc=2;
而现在我们可以用数组解构的方式来进行赋值。
let[a,b,c]=[1,2,3];
上面的代码表示,可以从数组中提取值,按照位置的对象关系对变量赋值。
数组模式和赋值模式统一
可以简单的理解为等号左边和等号右边的形式要统一,如果不统一解构将失败。
let[a,[b,c],d]=[1,[2,3],4];
如果等号两边形式不一样,很可能获得undefined或者直接报错。
解构的默认值
解构赋值是允许你使用默认值的,先看一个最简单的默认是的例子
let[foo =true] =[];console.log(foo);//控制台打印出true
上边的例子数组中只有一个值,可能你会多少有些疑惑,我们就来个多个值的数组,并给他一些默认值
let[a,b="ES6"]=['2016']console.log(a+b);//控制台显示“2016ES6” a对应2016 b对应空 但是默认值为ES6
现在我们对默认值有所了解,需要注意的是undefined和null的区别。
let[a,b="2016"]=['ES6',undefined];console.log(a+b);//控制台显示“ES62016”
undefined相当于什么都没有,b是默认值。
let[a,b="2016"]=['ES6',null];console.log(a+b);//控制台显示“ES6null”
null相当于有值,但值为null。所以b并没有取默认值,而是解构成了null。
对象的解构赋值 解构不仅可以用于数组,还可以用于对象。
let{foo,bar} = {foo:'ES6',bar:'2016'};console.log(foo+bar);//控制台打印出了“ES62016”
注意:对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
圆括号的使用
如果在解构之前就定义了变量,这时候你再解构会出现问题。下面是错误的代码,编译会报错。
letfoo;{foo} ={foo:'ES6'};console.log(foo);
要解决报错,使程序正常,我们这时候只要在解构的语句外边加一个圆括号就可以了。
letfoo; ({foo} ={foo:'ES6'});console.log(foo);//控制台输出ES6
字符串解构
字符串也可以解构,这是因为,此时字符串被转换成了一个类似数组的对象。
const[a,b,c,d,e,f]="STRING"; console.log(a); console.log(b); console.log(c); console.log(d); console.log(e); console.log(f);
ES6的扩展运算符和rest运算符
扩展运算符和rest运算符,它们都是…(三个点)。它们可以很好的为我们解决参数和对象数组未知情况下的编程,让我们的代码更健壮和简洁。
对象扩展运算符(…)
当编写一个方法时,我们允许它传入的参数是不确定的。这时候可以使用对象扩展运算符来作参数,看一个简单的列子:
functiones6(...arg){console.log(arg[0]);console.log(arg[1]);console.log(arg[2]);console.log(arg[3]); } es6(1,2,3);
这时我们看到控制台输出了 1,2,3,undefined,这说明是可以传入多个值,并且就算方法中引用多了也不会报错。
扩展运算符的用处
我们先用一个例子说明,我们声明两个数组arr1和arr2,然后我们把arr1赋值给arr2,然后我们改变arr2的值,你会发现arr1的值也改变了,因为我们这是对内存堆栈的引用,而不是真正的赋值。
letarr1=['www','baidu','com'];letarr2=arr1;console.log(arr2); arr2.push('ES6');console.log(arr1);
控制台输出:
["www", "baidu", "com"]
["www", "baidu", "com", "ES6"]
这是我们不想看到的,可以利用对象扩展运算符简单的解决这个问题,现在我们对代码进行改造。
letarr1=['www','baidu','com'];//let arr2=arr1;letarr2=[...arr1];console.log(arr2); arr2.push('ES6');console.log(arr2);console.log(arr1);
现在控制台预览时,你可以看到我们的arr1并没有改变,简单的扩展运算符就解决了这个问题。
rest运算符
如果你已经很好的掌握了对象扩展运算符,那么理解rest运算符并不困难,它们有很多相似之处,甚至很多时候你不用特意去区分。它也用…(三个点)来表示,我们先来看一个例子。
functiones6(first,...arg){console.log(arg.length); } es6(0,1,2,3,4,5,6,7);
这时候控制台打印出了7,说明我们arg里有7个数组元素,这就是rest运算符的最简单用法。
如何循环输出rest运算符
这里我们用for…of循环来进行打印出arg的值 (也可以使用for...in 两者没区别...吧 其实是有的 有兴趣可以自行百度一下)
functiones6(first,...arg){for(letvalofarg){console.log(val); } } es6(0,1,2,3,4,5,6,7);
for…of的循环可以避免我们开拓内存空间,增加代码运行效率,所以建议大家在以后的工作中使用for…of循环。有的小伙伴会说了,反正最后要转换成ES5,没有什么差别,但是至少从代码量上我们少打了一些单词,这就是开发效率的提高。
ES6的数字操作(用的比较少,了解一下)
二进制声明:
letbinary =0B010101;console.log(binary);
来看看es5的编译
"use strict";varbinary =21;console.log(binary);
当然命名二进制还是很少啦
八进制声明:
letb=0o666;console.log(b);
数字判断和转换
数字验证Number.isFinite( xx )
可以使用Number.isFinite( )来进行数字验证,只要是数字,不论是浮点型还是整形都会返回true,其他时候会返回false。
leta=11/4;console.log(Number.isFinite(a));//trueconsole.log(Number.isFinite('ES6'));//falseconsole.log(Number.isFinite(NaN));//falseconsole.log(Number.isFinite(undefined));//false
判断是否为整数Number.isInteger(xx)
leta=123.1;console.log(Number.isInteger(a));//false
整数转换Number.parseInt(xxx)和浮点型转换Number.parseFloat(xxx)
leta='9.18';console.log(Number.parseInt(a));console.log(Number.parseFloat(a));
整数取值范围操作
整数的操作是有一个取值范围的,它的取值范围就是2的53次方。我们先用程序来看一下这个数字是什么.
leta =Math.pow(2,53)-1; =>有些大神连下面的那串数字都记得住 完全瑟瑟发抖console.log(a);//9007199254740991
最大安全整数
consolec .log(Number.MAX_SAFE_INTEGER);
最小安全整数
console.log(Number.MIN_SAFE_INTEGER);
安全整数判断isSafeInteger( )
leta=Math.pow(2,53)-1;console.log(Number.isSafeInteger(a));//false
ES6中新增的数组知识(1)
JSON数组格式转换
JSON的数组格式就是为了前端快速的把JSON转换成数组的一种格式,我们先来看一下JSON的数组格式怎么写。
letjson = {'0':'www','1':'baidu','2':'com', length:3}
这就是一个标准的JSON数组格式,跟普通的JSON对比是在最后多了一个length属性。只要是这种特殊的json格式都可以轻松使用ES6的语法转变成数组。在ES6中绝大部分的Array操作都存在于Array对象里。我们就用Array.from(xxx)来进行转换。我们把上边的JSON代码转换成数组,并打印在控制台。
letjson = {'0':'www','1':'baidu','2':'com',length:3}letarr=Array.from(json);console.log(arr) =>["www","baidu","com"]
Array.of()方法
它负责把一堆文本或者变量转换成数组。在开发中我们经常拿到了一个类似数组的字符串,需要使用eval来进行转换,如果你一个老手程序员都知道eval的效率是很低的,它会拖慢我们的程序。这时候我们就可以使用Array.of方法。我们看下边的代码把一堆数字转换成数组并打印在控制台上
letarr =Array.of(3,4,5,6);console.log(arr);
当然它不仅可以转换数字,字符串也是可以转换的,看下边的代码:
letarr =Array.of('www','baidu','com');console.log(arr);
find( )实例方法
所谓的实例方法就是并不是以Array对象开始的,而是必须有一个已经存在的数组,然后使用的方法,这就是实例方法(不理解请看下边的代码,再和上边的代码进行比对,你会有所顿悟)。这里的find方法是从数组中查找。在find方法中我们需要传入一个匿名函数,函数需要传入三个参数
value:表示当前查找的值。
index:表示当前查找的数组索引。
arr:表示当前数组。
在函数中如果找到符合条件的数组元素就进行return,并停止查找。你可以拷贝下边的代码进行测试,就会知道find作用。
熟悉ES5新数组方法的小伙伴应该很清楚啊
letarr=[1,2,3,4,5,6,7,8,9];console.log(arr.find(function(value,index,arr){returnvalue >5; }))
控制台输出了6,说明找到了符合条件的值,并进行返回了,如果找不到会显示undefined。可以利用这一特性判断数据是否重复
ES6中新增的数组知识(2)
fill( )实例方法
fill()也是一个实例方法,它的作用是把数组进行填充,它接收三个参数,第一个参数是填充的变量,第二个是开始填充的位置,第三个是填充到的位置(可以根据自己理解用索引还是用位置来记)
letarr=[0,1,2,3,4,5,6,7,8,9];arr.fill('ES6',2,5);console.log(arr); =>[0,1,"ES6","ES6","ES6",5,6,7,8,9]
数组的遍历 for…of循环
先来看一个最简单的for…of循环
letarr=['www','baidu','com']for(letitemofarr){console.log(item); }
for…of数组索引:有时候开发中是需要数组的索引的,那我们可以使用下面的代码输出数组索引
letarr=['www','baidu','com']for(letindexofarr.keys()){console.log(index); }
entries( )实例方法
entries()实例方式生成的是Iterator形式的数组,那这种形式的好处就是可以让我们在需要时用next()手动跳转到下一个值。我们来看下面的代码:
letarr=['www','baidu','com']letlist=arr.entries();console.log(list.next().value); =>打印的是索引+值 构成的数组console.log(list.next().value);console.log(list.next().value);
同时输出数组的内容和索引:我们用entries()这个实例方法,配合我们的for…of循环就可以同时输出内容和索引了
letarr=['www','baidu','com']for(let[index,val]ofarr.entries()){console.log(index+':'+val);}
=>注意此处乃是实例方法,并不是数组方法
ES6中的箭头函数和扩展
看一下ES5中的函数写法先
functionadd(a,b){returna+b;}console.log(add(1,2));
我们声明了一个add函数,然后传入a和b两个值,返回a+b的值。 然后我们在控制台打印了这个函数的返回结果,这里是3.
默认值
在ES6中给我们增加了默认值的操作,我们修改上边的代码,可以看到现在只需要传递一个参数也是可以正常运行的
functionadd(a,b=1){returna+b;}console.log(add(1));
有人觉得好像ES5也可以,我们来看看ES5的代码
"use strict";functionadd(a){varb =arguments.length >1&&arguments[1] !==undefined?arguments[1] :1;returna + b; }console.log(add(1));
主动抛出错误
在使用Vue的框架中,可以经常看到框架主动抛出一些错误,比如v-for必须有:key值。那尤大神是如何做到的那?其实很简单,ES6中我们直接用throw new Error( xxxx ),就可以抛出错误。
functionadd(a,b=1){if(a ==0){thrownewError('This is error') }returna+b; }console.log(add(0));
如果你使用的是谷歌浏览器 开启了断点模式 无法正常显示我们设置的错误 需要关闭断点
函数中的严谨模式
我们在ES中就经常使用严谨模式来进行编程,但是必须写在代码最上边,相当于全局使用。在ES6中我们可以写在函数体中,相当于针对函数来使用。
functionadd(a,b=1){ 'use strict'if(a ==0){thrownewError('This is error'); }returna+b;}console.log(add(1));
上边的代码如果运行的话,你会发现浏览器控制台报错,这是ES6中的一个坑,如果没人指导的话,可能你会陷进去一会。这个错误的原因就是如果你使用了默认值,再使用严谨模式的话,就会有冲突,所以我们要取消默认值的操作,这时候你在运行就正常了。
functionadd(a,b){ 'use strict'if(a ==0){thrownewError('This is error'); }returna+b; }console.log(add(1,2));
获得需要传递的参数个数
如果你在使用别人的框架时,不知道别人的函数需要传递几个参数怎么办?ES6为我们提供了得到参数的方法(xxx.length).我们用上边的代码看一下需要传递的参数个数。
functionadd(a,b){ 'use strict'if(a ==0){thrownewError('This is error'); }returna+b;}console.log(add.length);
箭头函数
这个有多实用就不用多说了吧
{}的使用
在箭头函数中,方法体内如果是两句话,那就需要在方法体外边加上{}括号。例如下边的代码就必须使用{}.
varadd =(a,b=1) =>{console.log('ES6')returna+b;};console.log(add(1));
对比一下,箭头函数 其实省略了 function { } 以及return 如果方法体内是一句话的话
varadd=(a)=>console.log(a)add(3)
箭头函数中不可加new,也就是说箭头函数不能当构造函数进行使用
ES6中的函数和数组补漏
对象的函数解构
我们在前后端分离时,后端经常返回来JSON格式的数据,前端的美好愿望是直接把这个JSON格式数据当作参数,传递到函数内部进行处理。ES6就为我们提供了这样的解构赋值。
letjson = {a:'baidu',b:'guge'}functionfun({a,b='guge'}){console.log(a,b);}fun(json);
数组的函数解构
函数能解构JSON,那解构我们的数组就更不在话下了,我们看下边的代码。我们声明一个数组,然后写一个方法,最后用…进行解构赋值。
letarr = ['baidu','guge','sougou'];functionfun(a,b,c){console.log(a,b,c);}fun(...arr); =>之前提到过 是不是记到了呢
in的用法
in是用来判断对象或者数组中是否存在某个值的。我们先来看一下用in如何判断对象里是否有某个值。
对象判断
letobj={a:'baidu',b:'guge'}console.log('a'inobj);//true
数组判断
先来看一下ES5判断的弊端,以前会使用length属性进行判断,为0表示没有数组元素。但是这并不准确,或者说真实开发中有弊端。
letarr=[,,,,,];console.log(arr.length);//5
上边的代码输出了5,但是数组中其实全是空值,这就是一个坑啊。那用ES6的in就可以解决这个问题
letarr=[,,,,,];console.log(0inarr);//falseletarr1=['baidu','guge'];console.log(0inarr1);// true
注意:这里的0指的是数组下标位置是否为空
因为数组是有序的集合,而对象是无序的,所以我们只能通过属性判断对象,可以使用下标索引判断数组
ES6中对象
对象对于Javascript是非常重要的。在ES6中对象有了很多新特性
对象赋值
ES6允许把声明的变量直接赋值给对象,我们看下面的例子
letname="js666";letskill='web';varobj= {name,skill};console.log(obj);//Object {name: "js666", skill: "web"}
对象Key值构建
有时候我们会在后台取出key值,而不是我们前台定义好的,这时候我们如何构建我们的key值那。比如我们在后台取了一个key值,然后可以用[ ] 的形式,进行对象的构建。
letkey='skill';varobj={ [key]:'web'}console.log(obj.skill);
自定义对象方法
对象方法就是把对象中的属性,用匿名函数的形式编程方法
varobj={add:function(a,b){returna+b; } } 这个应该很好理解哈console.log(obj.add(1,2));//3
Object.is( ) 对象比较
对象的比较方法,以前进行对象值的比较,经常使用===来判断,比如下面的代码
varobj1 = {name:'js'};varobj2 = {name:'js'};console.log(obj1.name === obj2.name);//true.
那ES6为我们提供了is方法进行对比
varobj1 = {name:'js'};varobj2 = {name:'js'};console.log(obj1.name === obj2.name);//trueconsole.log(Object.is(obj1.name,obj2.name));//true
区分=== 和 is方法的区别是什么,看下面的代码输出结果
console.log(+0===-0);//trueconsole.log(NaN===NaN);//falseconsole.log(Object.is(+0,-0));//falseconsole.log(Object.is(NaN,NaN));//true
是不是头都炸了 诡异的一批 ===为同值相等,is()为严格相等
Object.assign( )合并对象
操作数组时我们经常使用数组合并,那对象也有合并方法,那就是assgin( )。看一下啊具体的用法
vara={a:'www'};varb={b:'baidu'};varc={c:'com'};letd=Object.assign(a,b,c)console.log(d);
Symbol在对象中的作用
Symbol的打印
我们先声明一个Symbol,然后我们在控制台输出一下
varg =Symbol('ES6');console.log(g);console.log(g.toString());
这时候我们仔细看控制台是有区别的,没有toString的是红字,toString的是黑字
Symbol在对象中的应用
看一下如何用Symbol构建对象的Key,并调用和赋值。
vares =Symbol();varobj={ [es]:'666'}console.log(obj[es]);obj[es]='web';console.log(obj[es]);
Symbol对象元素的保护作用
在对象中有很多值,但是循环输出时,并不希望全部输出,那我们就可以使用Symbol进行保护。
没有进行保护的写法
varobj={name:'javascript',skill:'web',age:18};for(letiteminobj){console.log(obj[item]); }
现在我不想别人知道我的年龄,这时候我就可以使用Symbol来进行循环保护
letobj={name:'javascript',skill:'web'};letage=Symbol(); obj[age]=18;for(letiteminobj){console.log(obj[item]); }console.log(obj);=>当然这里是可以显示的
Set和WeakSet数据结构
Set数据结构,注意这里不是数据类型,而是数据结构。它是ES6中新的东西,并且很有用处。Set的数据结构是以数组的形式构建的。
Set的声明
letsetArr =newSet(['js','css','html','js']);console.log(setArr);//Set {"js", "css", "html"}
Set和Array 的区别是Set不允许内部有重复的值,如果有只显示一个,相当于去重。虽然Set很像数组,但是他不是数组。
Set值的增删查 追加add:
在使用Array的时候,可以用push进行追加值,那Set稍有不同,它用更语义化的add进行追加
letsetArr =newSet(['js','css','html','js']);console.log(setArr);//Set {"js", "css", "html"}setArr.add('vue');console.log(setArr); =>在后面会增加vue
删除delete
letsetArr =newSet(['js','css','html','js']);console.log(setArr);//Set {"js", "css", "html"}setArr.add('vue');console.log(setArr);setArr.delete('vue');console.log(setArr);//Set {"js", "css", "html"}
查找has
用has进行值的查找,返回的是true或者false。
letsetArr =newSet(['js','css','html','js']);console.log(setArr);//Set {"js", "css", "html"}setArr.clear();console.log(setArr);//清空
set的循环 for…of…循环:
letsetArr =newSet(['js','css','html','js']);console.log(setArr);//Set {"js", "css", "html"}for(letitemofsetArr){console.log(item);}
size属性
size属性可以获得Set值的数量。
letsetArr =newSet(['js','css','html','js']);console.log(setArr);//Set {"js", "css", "html"}for(letitemofsetArr){console.log(item);}console.log(setArr.size);//3
forEach循环 这真不是数组console.log(Array.isArray(setArr))=>falseconsole.log(setArr instanceof Array)=>false
letsetArr =newSet(['js','css','html','js']);console.log(setArr);//Set {"js", "css", "html"}setArr.forEach((value)=>console.log(value));
WeakSet的声明
letweakObj=newWeakSet();letobj={a:'we',b:'love'}weakObj.add(obj);console.log(weakObj);
这里需要注意的是,如果你直接在new 的时候就放入值,将报错。
WeakSet里边的值也是不允许重复的,我们来测试一下。
letweakObj=newWeakSet();letobj={a:'we',b:'love'}letobj1=obj;weakObj.add(obj);weakObj.add(obj1);console.log(weakObj);=>不变
在实际开发中Set用的比较多,WeakSet用的并不多,但是他对传入值必须是对象作了很好的判断,我们灵活应用还是有一定的用处的。
map数据结构
我们知道的数据结构,已经有了json和set。那map有什么特点。
Json和map格式的对比
map的效率和灵活性更好
先来写一个JSON,这里我们用对象进行模拟操作。
letjson = {name:'js',skill:'web'}console.log(json.name);
但是这种反应的速度要低于数组和map结构。而且Map的灵活性要更好,你可以把它看成一种特殊的键值对,但你的key可以设置成数组,值也可以设置成字符串,让它不规律对应起来。
letjson = {name:'js',skill:'web'}console.log(json.name);varmap=newMap();map.set(json,'iam');console.log(map);
当然也可key字符串,value是对象。我们调换一下位置,依然是符合map的数据结构规范的。
letjson = {name:'js',skill:'web'}console.log(json.name);varmap=newMap();// map.set(json,'iam');// console.log(map);map.set('iam',json);console.log(map);
map的增删查 取值get
现在取json对应的值。
letjson = {name:'js',skill:'web'}console.log(json.name);varmap=newMap();map.set(json,'iam');// console.log(map);// map.set('iam',json);// console.log(map); console.log(map.get(json));
删除delete
letjson = {name:'js',skill:'web'}console.log(json.name);varmap=newMap();map.set(json,'iam');// console.log(map);// map.set('iam',json);// console.log(map); map.delete(json);console.log(map)
size属性
console.log(map.size);
查找是否存在has
consolec .log(map.has('iam'))
清除所有元素clear
map.clear()
用Proxy进行预处理
如果你学过Vue,一定会知道钩子函数,那如果你并没有学习Vue,那这里简单解释一下什么是钩子函数。当我们在操作一个对象或者方法时会有几种动作,比如:在运行函数前初始化一些数据,在改变对象值后做一些善后处理。这些都算钩子函数,Proxy的存在就可以让我们给函数加上这样的钩子函数,也可以理解为在执行方法前预处理一些代码。你可以简单的理解为他是函数或者对象的生命周期。
Proxy的应用可以使函数更加强大,业务逻辑更加清楚,而且在编写自己的框架或者通用组件时非常好用。
先来看看定义对象的方法。.
varobj={add:function(val){returnval+10; },name:'javascript'};console.log(obj.add(100));console.log(obj.name);
声明了一个obj对象,增加了一个对象方法add和一个对象属性name,然后在控制台进行了打印
声明Proxy
我们用new的方法对Proxy进行声明。可以看一下声明Proxy的基本形式。
new Proxy({},{})
需要注意的是这里是两个花括号,第一个花括号就相当于我们方法的主体,后边的花括号就是Proxy代理处理区域,相当于我们写钩子函数的地方。
现在把上边的obj对象改成我们的Proxy形式。
varobj={add:function(val){returnval+10; },name:'javascript'};// console.log(obj.add(100));// console.log(obj.name);varpro =newProxy({add:function(val){returnval +10; },name:'javascript'}, {get:function(target,key,property){console.log('come in Get');returntarget[key]; } });console.log(pro.name);
可以在控制台看到结果,先输出了come in Get。相当于在方法调用前的钩子函数。
get属性
get属性是在你得到某对象属性值时预处理的方法,他接受三个参数
target:得到的目标值
key:目标的key值,相当于对象的属性
property:这个不太常用,用法还在研究中,还请大神指教留言。
set属性
set属性是值你要改变Proxy属性值时,进行的预先处理。它接收四个参数。
target:目标值。
key:目标的Key值。
value:要改变的值。
receiver:改变前的原始值。
varpro =newProxy({add:function(val){returnval +10; },name:'javascript'}, {get:function(target,key){console.log('come in Get');returntarget[key]; },set:function(target,key,value,receiver){console.log(` setting${key}=${value}`);returntarget[key] = value; } });console.log(pro.name); pro.name='前端';console.log(pro.name);
这里比较复杂 看清输出顺序 建议看专门讲解此内容的专栏进行加深
其实proxy的知识是非常多的,这里我建议看阮一峰大神的《ES6》。我这里只能算是入门
promise的基本用法
promise执行多步操作非常好用,那我们就来模仿一个多步操作的过程,那就以吃饭为例吧。要想在家吃顿饭,是要经过三个步骤的。
洗菜做饭。
坐下来吃饭。
收拾桌子洗碗。
这个过程是有一定的顺序的,你必须保证上一步完成,才能顺利进行下一步。我们可以在脑海里先想想这样一个简单的过程在ES5写起来就要有多层的嵌套。那我们现在用promise来实现。
letstate=1;functionstep1(resolve,reject){console.log('1.开始-洗菜做饭');if(state==1){ resolve('洗菜做饭--完成'); }else{ reject('洗菜做饭--出错'); } }functionstep2(resolve,reject){console.log('2.开始-坐下来吃饭');if(state==1){ resolve('坐下来吃饭--完成'); }else{ reject('坐下来吃饭--出错'); } }functionstep3(resolve,reject){console.log('3.开始-收拾桌子洗完');if(state==1){ resolve('收拾桌子洗完--完成'); }else{ reject('收拾桌子洗完--出错'); } }newPromise(step1).then(function(val){console.log(val);returnnewPromise(step2); }).then(function(val){console.log(val);returnnewPromise(step3); }).then(function(val){console.log(val);returnval; });
Promis在现在的开发中使用率算是最高的,而且你面试前端都会考这个对象,大家一定要掌握好
class类的使用
我们在ES5中经常使用方法或者对象去模拟类的使用,虽然可以实现功能,但是代码并不优雅,ES6为我们提供了类的使用。需要注意的是我们在写类的时候和ES5中的对象和构造函数要区分开来,不要学混了。
先声明一个最简单的coder类,类里只有一个name方法,方法中打印出传递的参数。
classcoder{name(val){ console.log(val); } }
我们已经声明了一个类,并在类里声明了name方法,现在要实例化类,并使用类中的方法。
classCoder{ name(val){console.log(val); }}letjs=newCoder;js.name('javascript');
类的多方法声明
classCoder{ name(val){console.log(val);returnval; } skill(val){console.log(this.name('js')+':'+'Skill:'+val); }}letjs=newCoder;js.name('javascript');js.skill('web');
类的传参
在类的参数传递中我们用constructor( )进行传参。传递参数后可以直接使用this.xxx进行调用。
classCoder{ name(val){console.log(val);returnval; } skill(val){console.log(this.name('js')+':'+'Skill:'+val); }constructor(a,b){this.a=a;this.b=b; } add(){returnthis.a+this.b; } }letjs=newCoder(1,2);console.log(js.add());
我们用constructor来约定了传递参数,然后用作了一个add方法,把参数相加。这和以前我们的传递方法有些不一样,所以需要小伙伴们多注意下。
class的继承
classCoder{ name(val){console.log(val);returnval; } skill(val){console.log(this.name('js')+':'+'Skill:'+val); }constructor(a,b){this.a=a;this.b=b; } add(){returnthis.a+this.b; }}classhtmlerextendsCoder{ }letjs=newhtmler;js.name('javascript');
声明一个htmler的新类并继承Coder类,htmler新类里边为空,这时候我们实例化新类,并调用里边的name方法。结果也是可以调用到的。
ES6的模块化开发可以参考我的另一篇文章
https://www.jianshu.com/p/01f3c09324bb
对ES6的知识点做了简单的整理与应用,详解可以查找其他文章,多练多看才能立于不败(装X)之地
作者:感觉不错哦
链接:https://www.jianshu.com/p/b65176f3e935
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。