ES6新增语法 var 、let 、 const的区别

本文介绍了ES6中的var、let和const的区别,包括它们的作用域、声明提升、变量重复声明等。let和const提供了更细粒度的作用域控制,const用于声明不可变的常量。推荐使用const优先,let次之的声明风格。此外,还提及了字符串模板、解构赋值和箭头函数等新特性。
摘要由CSDN通过智能技术生成

var关键字

要定义变量,可以使用var操作符(注意var是一个关键字),后跟变量名,用他也可以保存任何类型的值。

var name
var name="likeqin"

上面 name被定义为一个保存字符串值的likeqin的变量,只是一个简单的赋值,可以改变值也可以改变值的类型,如下:

var name="likeqin"
likeqin=100;//合法但不推荐

1.var 声明作用域

使用var操作符定义的变量会成为包含它的函数的局部变量,比如使用var在一个函数内部定义一个变量,那么该变量在函数退出时被销毁。例如:

function test(){
  var name="hi";//局部变量
}
test();
console.log(name);//报错!!!!

上面这个name变量是在函数内部使用var定义的 函数叫test(),调用它 会创建这个变量并给它赋值。调用之后随之被销毁 所以报错!

如果需要定义多个变量,用逗号分隔每一个变量

var name="hi",
    lalal=kkk,
    age=123;

2.var声明提升 

console.log(x)//undefined
var x=1;

使用var时,上面的代码不会报错,因为使用这个关键字声明的变量会自动提升到函数作用域顶部。

var反复多次声明同一个变量也没有问题。

var x=1;
var x=12;
var x=1221;
console.log(x)//1221

let声明

let跟var的作用差不多,但是有着非常重要的区别。最明显的区别是,let声明的范围是块作用域,而var声明的范围是函数作用域。

if(true){
  var name='Matt';
  console.log(name);//Matt
}
console.log(name);//Matt
if(true){
  let age=22;
  console.log(age);//22
}
console.log(age);//ReferenceError:age没有定义

let不允许同一个块作用域中出现冗余声明,会报错

let age;
let age; //SyntaxError:标识符age已经声明过了

当然,JavaScript引擎会记录用于变量声明的标识符及其所在的块作用域,因此嵌套使用相同的标识符不会报错,而这是因为同一个块中没有重复声明。

var name='shenmowanyi';
console.log(name); //'shenmowanyi'
if(true){
   var name='hahaha';
   console.log(name);  //'hahaha'
}

let age=50;
console.log(age); //50
if(true){
   let age=60;
   console.log(age); //60
}

对声明冗余报错不会因为混用let和var受影响。这两个关键字声明的并不是不同类型的变量,他们只是指出变量在相关作用域如何存在。

var name;
let name; //SyntaxError

1.暂时性死区

let与var另一个最重要的区别就是,let声明的变量不会在作用域中被提升。

不举代码例子了大家应该都知道。

在解析代码时,JavaScript引擎也会注意出现在块后面的let声明,只不过在此之前不能以任何方式来引用未声明的变量。在let声明之前的执行瞬间被称为“暂时性死区”(temporal dead zone),在此阶段引用任何后面才声明的变量都会抛出Reference Error

2.全局声明

与var关键字不同,使用let在全局作用域中声明变量不会成为window对象的属性   var会

var x=20
console.log(window.x) //20
let y=30
console.log(window.y)  //undefined

3.条件声明

let的作用域是块,所以不可能检查前面是否已经使用let声明过同名变量,同时也就不能再没有声明的情况下声明它。

不能进行let条件声明是件好事,它是一种反模式,让程序变得更难理解。

4.for循环中的let声明

在let出现之前,for循环定义的迭代变量会渗透到循环体外部:

for(var i=0; i<5; i++){
   
}
 console.log(i)//5

改成let之后,这个问题就消失了,因为迭代变量的作用域仅限于for循环快内部:

for(let i=0; i<5; i++){
   
}
 console.log(i)//报错 i没有被定义

在使用var的时候,最常见的问题就是对迭代变量的奇特声明和修改:

for(var i=0; i<5; i++){
   setTimeout(()=>console.log(i),0)
}
 //你可能以为会输出0、1、2、3、4
 //其实会输出 5、5、5、5、5

之所以会这样,是因为在退出循环时,迭代变量保存的是导致循环退出的值:5 。在之后执行超时逻辑时,所有的i都是用一个变量所以输出同一个值。

而在使用let声明迭代变量时js引擎会在后台为每个迭代循环声明一个新的迭代变量。每个setTimeout引用的都是不同的变量实例,所以输出的是我们期望的值,也就是循环执行过程中每个迭代变量的值。

for(let i=0; i<5; i++){
   setTimeout(()=>console.log(i),0)
}    //输出0、1、2、3、4

const声明

let const let定义变量 const定义常量
     


        let x=20
        x=40
        console.log(x)
        const http="http://localhost:8088"
        http=123
        console.log(http)


声明风格及最佳实践

1.不使用var

有了let和const,大多数开发者会发现自己不再需要var了。限制自己只使用let和const有助于提升代码质量,因为变量有了明确的作用域、声明位置,以及不变的值。

2.const优先,let次之

使用const声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不合法的操作。因此,很多开发者认为应该优先使用const来声明变量,只在提前知道未来会有修改时,再使用let。这样可以让开发者更有信心的推断某些变量的值永远不会变,同时也能迅速发现因为意外赋值导致的非预期行为。





二、字符串模板

        //字符串模块 快速字符串和变量拼接
        let area=100//
        //面积为 area 平方米
        console.log("面积为"+area+"平方米")
        //使用字符串模板进行
        //`` 里面的变量放到${变量名}
        console.log(`面积为"${area}"平方米`)

三、数据结构(先简单了解)

解构:顾名思义 将复杂结构中内容,解构成简单结构

        let user={
            name:"wagnyi",
            age:21, 
            uimg:"123123.png"
        }

需求中需要大量的使用 对象中的某一个属性
user.name 
让name变量对应 user.name属性 
name变量  解构
解构的语法:左右结构相同
左侧和右侧的key相对应 

        let {name,age}=user
        console.log(name)//小王
        console.log(age)//21
        let arr=[1,23,4]
        let [a,b,c]=arr
        console.log(a)//1
        console.log(b)//23
        console.log(c)//4

解构做交互变量 

        let a=20
        let b=30;
        [a,b]=[b,a]
        var x=30
        console.log(++x)
        console.log(a)//30
        console.log(b)//20

四、箭头函数

1.传统的function定义函数  this指向性不明确 , 随着使用环境的变化发生改变

           function show(){
              console.log(this)
           }//this指向谁??
           show()//window  直接调用show就指向window

或者:

<button id="bt1">点击我</button>
<script>
        function show(){
            console.log(this)
        }
        bt1.onclick=show // bt1  变成事件源了
</script>

再或者:

        function show(){
            console.log(this)
        }
        //封装到对象的方法里
        let obj={
            name:"wangyi",
            show:show
        }
        obj.show()//obj


箭头函数: this指向明确 ,永远指向生产环境

定义一个箭头函数:

<button id="bt1">确定</button>   
    //如何定义一个箭头函数
    let show=()=>{
        console.log(this)
    }
    show()//window
    bt1.onclick=show //还是window

        //let obj={
           // name:"wangyi",
            //show:show
        //}
       // obj.show()//还是window


2.传统function定义 有默认的提升功能,箭头函数没有。因为箭头函数是用let语句定义的因为let语句没有提升功能 所以箭头函数也没有  如果这么做会报错。

3.传统function 可以作为构造函数,箭头函数不可以

因为this的指向性  箭头函数永远指向生产环境

4.传统function 函数中具有arguments参数集合,箭头函数没有   只有 rest 参数,rest定义才会有

什么是arguments参数集合(用实参决定内容 有点反逻辑) :

举个例子:编写一个函数 计算n个数字的和 ,用户传入多少,就计算多少

    function sum(){  
        //每个函数内部都有一个arguments集合
        console.log(arguments) //Arguments(10) [1, 2, 3, 4, 5, 6, 7, 9, 10, 12, callee: ƒ, Symbol(Symbol.iterator): ƒ]   实参的集合 
        let s=0
        for(let n=0;n<arguments.length;n++){
            s+=n
        }
         return s
    }
    console.log(sum(1,2,3,4,5,6,7,9,10,12))//45

如何定义rest参数:用了一个拓展运算符的语法 rest参数

    let show=(...args)=>{  //把所有的实参都放到args(args叫什么名字都可以)里
        console.log(args)
    }
    show(1,2,3,4) //输出数组 [1, 2, 3, 4]

arguments参数集合与rest 参数的区别在哪  一个是集合一个是数组

但重点是:arguments与形参没有任何关系 永远是实参的集合  就像下面的代码一样

function sum(a,b,c){  
        console.log(arguments) //  还是输出    Arguments(10) [1, 2, 3, 4, 5, 6, 7, 9, 10, 12, callee: ƒ, Symbol(Symbol.iterator): ƒ]   实参的集合
 }
console.log(sum(1,2,3,4,5,6,7,9,10,12))//45

但是rest前面可以加形参    rest只能加在形参的后面  然后会抛出形参外所有实参 ,例如下面这串代码会输出什么:

    let show=(a,b,...args)=>{  
        console.log(args)
    }
    show(1,2,3,4) //输出数组 [3, 4]

箭头函数应用场景---定时变色

点击后3s 背景色变成蓝色  

        <style>
        .box{
            width: 300px;
            height: 300px;
            background-color: red;
        }
        </style>

        <div class="box">

        </div>

<script>

        let box=document.getElementsByClassName("box")[0]
        box.onclick=function(){
            //延时定时器:异步操作 统一在window进行  所以定时器的this指向性指向window
            //所以会报错
            //setTimeout(function(){  },3000)  延时定时器
            setTimeout(function(){
                //console.log(this)
                that.style.backgroundColor="blue"
            },3000)
        }
</script>

正常思路会用    延时定时器:异步操作 统一在window进行  所以定时器的this指向性指向window
然后会报错

如何解决(第一种原本简单的解决方式):

        let box=document.getElementsByClassName("box")[0]
        box.onclick=function(){
            let that=this
            setTimeout(function(){
                //console.log(that)
                that.style.backgroundColor="blue"
            },3000)
        }

用let变量存一个this       let that=this   然后就会用that来表示

还可以用箭头函数来解决:因为箭头函数this永远指向与它所创建的环境,下面的代码箭头函数是在事件处理函数里面创建的所以 永远指向事件源

        let box=document.getElementsByClassName("box")[0]
        box.onclick=function(){
           setTimeout(()=>{
               this.style.backgroundColor="blue"
           },3000)
        }

在ES6里  只是增加了一个小功能 并不是箭头函数替代了function

function:在构造函数的时候或者很多时候都可以用

箭头函数:this指向性不变的 使用箭头函数

箭头函数简写:

编写一个方法,传入一个参数,返回其平方

1.如果箭头函数中有且只有一个参数,那么可以省略括号()

     let pow=(n)=>{return n*n}
     let pow=n=>{return n*n}  //省略后

2.如果箭头函数内部有且只有一行语句,并且是return语句的话 可以省略{}和return

    let pow=n=>{return n*n}
    let pow= n=>n*n   //省略后

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RORONOA~ZORO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值