es6和es5的对比

这篇可以帮助刚入门的小伙伴对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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值