首页 > 编程知识 正文

es5跟es6的区别,es6相对于es5的新特性

时间:2023-05-03 18:34:29 阅读:236120 作者:2835

这篇可以帮助刚入门的小伙伴对es6有个简单的理解。

常量对比 // es5常量写法Object.defineProperties(window,"PI2",{ value:3.14159, writable:false,//只读不可写})//需要用api去声明常量。给对象定义一个属性,让这个属性变成只读,常量挂载在window下//运行console.log(window.PI2)//es6常量写法,不需要api声明常量//声明一个常量const PT=3.14159//只读,不允许给其赋值console.log(PI) 作用域 //es5的写法const callbacks=[]//声明一个数组for(var i=0;i<=2;i++){//用的是var声明的一个i变量,会得到一个变量的提升,因为var i=0放在前面,不属于for循环只内的,//但赋值callbacks[0],var i是从callbacks[0]取值为0, callbacks[i]=function(){//但是这个函数并没有把这个i取值为0, return i*2 //这里是对变量的引用并不是对变量的值的引用,所以这个函数体内是一个表达式而不是一个值,而这个表达式用到的是i变量,所以这里会有一个闭包 }}//所以执行callbacks[0]()的时候,i已经变成3了//因为这个闭包的作用域i就是一个全局 console.table([ callbacks[0](), callbacks[1](), callbacks[2](), ]) //输出的值都是6 //es6中的作用域 const callbacks2=[] for(let j=0;j<=2;j++){//用let声明的变量会有一个叫跨作用域的一个概念,也就是以下的闭包是取决于当前的跨作用域,他会把当前跨作用域下的变量保存下来供后面的闭包所使用,循环的时候没循环一次就会重新生成一次新的作用域,所以这闭包就会导向闭包中的作用域的导向 callbacks2[j]=function(){ return j*2 } }console.table([ callbacks2[0](), callbacks2[1](), callbacks2[2](),])//输出为0 2 4 立即执行函数 //es5立即执行函数(function(){//这个作用域是有个函数,也就是说这个作用域在函数体内,声明了一个变量是有个foo函数 const foo=function(){ return 1 } console.log("foo()===1",foo()===1) //为了分隔这个作用域就叫立即执行作用域 ;((function(){ const foo=function(){ return 2 } console.log("foo()===2",foo()===2) })())})()//声明了两个函数,表示的是整两个函数已经被两个作用域给隔离开,在es5中保证一块代码要执行所在作用域的问题//输出的是foo()===1 true// foo()===2 true//es6就会很简单直接用{}就能指定一个跨作用域{ function foo(){ return 1 } console.log('foo()===1',foo()===1); { function foo(){ return 2 } console.log('foo()===2',foo()===2); }}//也就是说在es6中,一个{}就把作用域进行了隔离,而在es5中必须使用立即执行函数(function(){})()才能对作用域进行隔离 箭头函数 function a(){()=>{//()是声明参数的,如果参数只有一个的话这个()是可以被省略的,如果{}中的表达式直接作为返回值的话是可以省略{}的}}//es5声明一个函数{ //es5,es3中对数组的遍历 var evens=[1,2,3,4,5]; var odds=evens.map(function(v){ return v+1 }) console.log(evens,odds);}//输出结果为 [1,2,3,4,5] [2,3,4,5,6]{ //es6中的写法 let evens=[1,2,3,4,5]; let odds=evens.map(v => v + 1) console.log(evens,odds);}//输出结果为 [1,2,3,4,5] [2,3,4,5,6]//箭头函数跟普通函数的区别//es3,es5{var factory=function(){ this.a='a'; this.b='b'; this.c={ a:'a+', b:function(){ return this.a } } //this的指向是该函数被调用的对象,也就是所函数被执行的时候,this指向的是哪个对象调用的function,也就是 //b()是c调用的,而c本身就是一个对象,所以这个this指向的是c,c中的a也就是a+} console.log(new factory().c.b())//输出结果为 a+};//es6写法{ var factory=function(){ this.a='a'; this.b='b';//这里的this指向的是这个构造函数factory的实例 this.c={ a:'a+', b:()=>{ return this.a }//b在定义这个函数的时候this指向的是函数体中的this的 } }//箭头函数中this的指向是定义式this的指向 console.log(new factory().c.b())//输出结果为 a // new factory().c.b()中c.b()实例就是 new factory(),而new factory()的实例也就是这个构造函数中的a}//这就是es6中的箭头函数 默认参数 //默认参数function a(x,y){ x=x||1; y=y||2;};{ //es3,es5中的写法 function f(x,y,z){ if(y===underfined){ y=7; } if(z===underfined){ z=42 } return x+y+z } console.log(f(1,3) )//输出 46};{ //es6 function f(x,y=7,z=42){ return x+y+z } console.log(f(1))//输出50 console.log(f(1,3))//输出46,默认参数起作用} 可变参数 { //es3,es5可变参数 function f(){ var a=Array.prototype.slice.call(arguments)//argument是一个伪数组,他不是一个真正的数组 var sum=0; a.forEach(function(item){ sum+=item*1 }) return sum; }//通过arguments来获取函数当前的参数列表然后进行一个循环一个运算,这就是一个可 //变参数的获取然后的一个求和 console.log(f(1,2,3));//输出结果 6 console.log(f(1,2,3,6));//输出结果 12}{ //es6中的可变参数 function f(...a){//...a是一个扩展运算符,a表示的就是一个可变参数的列表而且它是一个数组 var sum=0; a.forEach(item=>{ sum+=item*1 }) return sum; }//在es6中去获取一个可变的参数只需要...a,不需要伪数组什么的了 console.log(f(1,2,3));//输出结果 6 console.log(f(1,2,3,6));//输出结果 12}

…a还可以有其他的用途,在es6中可用合并,如下所示:

{ //es5关于合并,合并数组 var params=['hello',true,1]; var other=[1,2].concat(params);//把[1,2]数组与patams合并 console.log(other);//输出[1,2,'hello',true,7]}{ //es6利用扩展运算符合并数组 var params=['hello',true,1]; var other=[1,2,...params];//把[1,2]数组与patams合并 console.log(other);//输出[1,2,'hello',true,7]} 对象代理,解决私有变量的问题,数据的隐私保护,添加有个代理层对原始数据达到一个保护的效果 { //es3数据保护 var Preson=function(){ var data={//内部声明一个局部作用域,因为没有被类访问到,所以对象的实例是拿不到data的数据的,我们就是利用这个原理把数据保护起来 name:'es3', sex:'male', age:15 } //或想让外部去操作这个数据,只能get添加一个api this.get=function(key){ return data[key]//读取走这个借口 } //想赋值,这时候要检查 this.set=function(key){ if(key!=='sex'){ data[key]=value//如果key不等于性别就可以进行赋值 } } } //声明一个实例 var person =new Preson(); //读取 console.table({ name:person.get('name'), sex:person.get('sex'), age:person.get('age'), }) //修改 person.set('name','es3-cname'); console.table({ name:person.get('name'), sex:person.get('sex'), age:person.get('age'), })//输出的表格中name已经被修改为es3-cname person.set('sex','csex'); console.table({ name:person.get('name'), sex:person.get('sex'), age:person.get('age'), })//输出的表格中sex没有被修改,因为进行判断了,sex不允许修改}{ //es5中的数据保护 var Person={ name:'es5', age:15 }; Object.defineProperties(Person,'sex',{ writable:false, value:'male' })//在es5中利用这个api达到一个只读的效果,也就达到一个保护的效果,只读不可写 console.table({ name:Person.name, sex:Person.sex, age:Person.age, }) Person.name='es5=cname'; console.table({ name:Person.name, sex:Person.sex, age:Person.age, })//输出的表格中name已经被修改为es5=cname Person.sex='es5=sex'; console.table({ name:Person.name, sex:Person.sex, age:Person.age, })//报错,不能给一个只读的属性赋值}{ //es6 let Person={ name:'es6', sex:'male', age:15 }; let person=new Proxy(Person,{//new Proxy()是es6提供的一个原生的语法,一个代理,也就是代理Person //代理之后可以写一个get和set的操作 get(target,key){ return target[key] }, set(target,key,value){ if(key!=='sex'){ target[key]=value } } })//这个person是将来暴露给用户操作的一个对象,把最前面的Person保护起来,以后操作的就是这个person, //二这个person通过Proxy()这个代理挂上钩,代理的就是一个原始数据,这里面的target就是代理的数据,key就是数据里面的属性 console.table({ name:person.name, sex:person.sex, age:person.age }) //修改 try{ person.sex='female'; }catch(e){ console.log(e) }finally{ }//报错,不允许修改}

好啦,以上就是对es6相比于es5,es3的不同之处做了简单的对比。
需要转载的麻烦备注文章来源

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。