已经好久没有动前端的知识了,再来到一个新落点,让在下感概的是前端轻量度远高于Java后端,重新技术到陈旧版本有点不太适应,而对于新落点的前端依然可使用VS Code开发Vue先后分离项目,在于习惯IDEA开发,SpringBoot开发的高效,忽然使用eclipse,Spring MVC 3.x版本、不联网的开发,我也0疼...看着那个前端妹子打的噼啪噼啪好是羡慕javascript
一时兴起,那就学习一下ES6,虽然一段时间了,也补一补基础,我的比较喜欢vue前端
es6 弥补 es三、es5 中的不足,好比常量、做用域、对象代理、类、继承等等,这些功能在es三、es5也能够实现,可是比较复杂,es6对其作了封装,开发中使用会很是的方便、快捷vue
关于es三、es五、es6的区别通常体现也比较模糊,下面一边对比一边认识的方式作个学习记录,来体现es6的好处java
es6以前是没有常量的,不过作后端的并不陌生,就不会在乎,es三、es5是没有常量的概念,好比还有箭头函数、默认参数等等都是es6特有的,对面新技术,有着饥渴的欲望,落后的我一步一步学习es6
快速搭个vue来学习,很是的快捷-> 搭建方式后端
将搭建好的应用导入 VS code (推荐使用),下面是简单的目录展现,在conponents中能够写代码,router是配置路由数组
es3: 没有闭包
es5: 利用向对象添加属性的方式来实现,js中全局对象是window,对于常量实现就是绑定在window上eclipse
语法 使用Object的defineProperty定义属性的方法,再设置属性只读,就能够达到做为一个常量的存在函数
es6: 使用const定义常量
//es5 常量 Object.defineProperty(window, "const_es5", { value: 123, writable: false }) //es6 常量 const const_es6=456
es6的做用域有明显是界线---块做用域
//es5 var ary = [] for (var i = 0; i <= 2; i++) { ary[i] = function () { return i * 2; } }
上面输入的数组的元素都是6 , 不是应该有0才对, 以往在javascript中只有全局做用域和函数做用域,并不存在块做用域
注意: for中使用的是var定义的i变量,会有一个叫作变量提高效果,意思是var i=0;提高到for前面,而不属于for循环中,被认为是全局的i变量,第一步当i=0赋值ary[0],此步是对的,可是function函数体中的i并未取值,function中的i是对变量的引用,而不是对变量值的引用,体现出function函数体内是一个表达式,而不是一个值的存在,不会跑到for上面去获取i变量,此处称为闭包,因此i*2这步并非0,i++的效果一直覆盖着全局的i变量,直到不知足条件中止循环,function紧接着执行,这时候,全局i为3,结果都是6
//es6 var ary = [] for (let i = 0; i <= 2; i++) { ary[i] = function () { return i * 2; } }
使用let代替var,输出的结果就是0,2,4
let有块做用域的做用,当前的闭包取做用于当前的块做用域,每次循环,保存当前变量i,供后面闭包使用,每次循环都会生成新的做用域
es6中{}就能够起到块做用域的简单区分,es3,es5须要使用当即执行函数来起到做用域的隔离做用
两种函数的简单示例 :
es3,es5 function a(){ } es6 ()=>{ }
用对数组的遍历操做来作一个demo实践
{ //es3,es5 var ary = [1, 2, 3, 4, 5] var e = ary.map(function (v) { return v + 1; }) } { //es6 let ary = [1, 2, 3, 4, 5] let e = ary.map(v => v + 1) }
箭头函数的写法 和 后端的lambda表达式差很少, 当只有一个参数的时候能够省去括号等等语法,作一个简单的体会
箭头函数有一个重要的特性,就是和this绑定
{ //es3,es5中声明一个类,用一个函数做为类的构造器 var factory=function(){ this.a='a' this.b='b' this.c={ a:'a+', b:function(){ return this.a } } } console.log(new factory().c.b()) //输出是 a+ }
从上面能够看出来es3,es6中,this的指向是c中的a,有人总结过this的套路:this的指向是该函数被调用的对象,就是函数被执行的时候,执行哪一个对象调用了他,上面能够看到b()是被c调用的,因此this指向c中的a
下面使用es6 再操做一次
{ //es6 let factory=function(){ this.a='a' this.b='b' this.c={ a:'a+', b:()=>{ return this.a } } } console.log(new factory().c.b()) //输出是 a }
能够看出 es6 箭头函数的this区别了,es6箭头函数中的this指向定义时this的指向,c中的b在定义时,b中this指向外侧函数体中this,外侧this指向factory实例,因此输出时factory实例的a值
默认参数是开发是常用的,好比一个function,函数中的几个参数,参数无关紧要,没有的时候,入函数体逻辑的时候就有一个默认值
{ //es3,es5 function a(x,y,z){ x=x||1 if(y==undefined){ y=2 } if(z==undefined){ z=3 } return x+y+z } }
看到上面的code,都会有种想省,省优化都能拖出来一腿
{ //es6 function a(x=1,y=2,z=3){ return x+y+z } }
es6默认参数不只能够默认值,还能够对必填参数作校验,好比非空
{ //es6 function checkEmpty(){ throw new Error('this is empty'); } function foo(x=checkEmpty,y=1){ return x+y } }
若是没有值,函数体就抛出error
扩展: 可变参数,对函数体录入的参数不肯定是几个的状况
{ //es3,es5 function a(x){ var b=Array.prototype.slice.call(arguments) var sum=0 b.forEach(element => { sum+=element+1 }); return sum } console.log(a(1,2,3)) //9 }
利用arguments来实现可变参数,arguments是一个伪数组,能够用数组的方式操做
{ //es6 function foo(...x){ var sum=0 x.forEach(y=>{ sum+=sum+1 }) return sum } }
...是扩展运算符 , 还有合并数组的做用
{ //es3,es5 合并数组 var ary=[1,2] var ary1=[3,4].concat(ary) } { //es6 合并数组 var ary=[1,2] var ary1=[3,4,...ary] }
好比封装一个数据,该数据只供内部方法使用,其余地方访问不到,作事后端就知道相似私有属性的做用,es6提供对象代理的功能,来实现属性私有化
加一个中间代理层,好比
{ let a=new Proxy(对象, { get(target, key) { return target(key) }, set(target,key,value){ //逻辑 if(key == 'tom'){ //.. } } }) }
在对比下,可见es6的改变仍是比较大的,新型的操做十分便利,以上只是es6的一小部分
还有不少知识,好比解构赋值、模版字符串、正则扩展、数字扩展、Class、Module、Iterator、Set和Map、函数扩展、Symbol、对象扩展、Generator等等, 继续扩展学习
----------------------------------------------------------