详解JavaScript中var和let的区别

 更新时间:2022年11月24日 10:22:38   作者:掘金小逆  
在JavaScript中,有3个关键字可以声明变量:var、const和let,其中var在ECMAScript的所有版本中都可以使用,而const和let只能在ECMAScript 6及更晚的版本中使用,本文就来说说二者的区别,感兴趣的可以了解一下

变量

ECMAScript变量是松散类型,意思就是说变量可以保存任何类型的数据,每个变量只不过是用于保存任意值的命名占位符。在JavaScript中,有3个关键字可以声明变量:var、constlet,其中varECMAScript的所有版本中都可以使用,而constlet只能在ECMAScript 6及更晚的版本中使用

var 关键字

如果我们想定义变量,我们可以使用var操作符(这里要注意var也是一个关键字~),后跟变量名

var message;

这行代码会定义一个名为message的变量,用于保存任何类型的值如果在不初始化的情况下,默认为undefinedECMAScript实现变量初始化,因此可以同时定义变量并且设置它的值

var message = "hi";

通过上方代码我们可以了解到,message被定义为一个保存字符串值hi的变量,像这样初始化变量不会将它标识为字符串类型,这仅仅是一个简单的赋值而已,我们不仅可以改变保存的值,同时还可以改变值的类型

var message = "hi"
message = 100 ;

通过上方代码我们可以看到,message首先被定义为一个用于保存字符串值hi的变量,然后又被重写为保存了数值100,虽然不推荐改变变量保存值的类型,但是这个在ECMAScript里面是非常有效的

var声明作用域

我们在定义一个函数变量的时候,通常都会考虑他们的作用域,使用var操作符定义的变量将会成为包含它的函数的局部变量,比如用var在一个函数内部定义一个变量,就意味着一旦出了这个区域,此定义无效

<script>
function test() {
    var message = "hi";
}
test();
console.log(message);
</script>

从上方代码我们可以看到,message变量是在函数内部使用var定义的,函数名叫test() ,调用它会创建这个变量并且会给它赋值,调用结束之后这个变量就会被销毁,因此上方代码的倒数第二行会报语法错误,如果我们想要解决这个问题,把message定义成全局变量即可

<script>
function test() {
    message = "hi";
}
test();
console.log(message);
</script>

去掉之前的var操作符之后,message变成了全局变量,我们只需要调用一次函数test() ,就可以定义这个变量,并且在函数外部访问

注意注意!!!

我们虽然可以通过省略var操作符来定义全局变量,但是不推荐这么做,在局部作用域中定义的全局变量很难去维护,也会给我们造成一定的困惑,因为我们不能确定这个var是不是有意而为之,如果像这样给未声明的变量赋值,则会导致抛出ReferenceError

如果我们需要定义多个变量,我们可以在一条语句中用逗号分隔每个变量(及可选的初始化)

<script>
    var message = "hi";
    found = false;
    age = 29;
</script>

这里我们定义了3个初始化变量,因为ECMAScript松散类型的,所以使用不同数据类型初始化的变量可以用一条语句来声明,插入换行和空格缩进不是必需品(因为这里不是Python~)

小tip

严格模式下,不能定义名为evalarguments的变量,否则会导致语法错误

var声明提升

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

<script>
    function foo() {
        console.log(age);
        var age = 26;
    }
    foo();
</script>

之所以这个代码不会报错,是因为ECMAScript已经帮我们解决啦~(它自己会自动调整阅读顺序),这就是所谓的提升,也就数把所有变量声明都拉到函数作用域的顶部,此外,反复多次使用var声明同一个变量也是没有问题的

let声明

letvar的作用差不多,但是有着十分重要的区别,最明显的区别就是,let声明的范围是块作用域,而var声明的范围是函数作用域

<script>
   if(true){
       var name = "Matt"
       console.log(name);  //Matt
   }
   console.log(name);    //Matt
   if(true){
       let age = 26 ;
       console.log(age)   //26
   }
   console.log(age)        //ReferenceError
</script>

在这里,age变量之所以不能在if块外部被引用,是因为它的作用域仅限于该块内部,块作用域是函数作用于的子集,因此适用于var的作用域也适用于let

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

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

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

<script>
    var name = "Nicholas";
    console.log(name);        // Nicholas
    if (true) {
        var name = "Matt";
        console.log(name);    // Matt
    }
    let age = 30;
    console.log(age);         // 30
    if (true) {
        let age = 26;
        console.log(age);     // 26
    }
</script>

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

var name ;
let name ;    //SyntaxError
let age ;
var age ;     //SynatxError

到此这篇关于详解JavaScript中var和let的区别的文章就介绍到这了,更多相关JavaScript var let内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Javascript Promise用法详解

    Javascript Promise用法详解

    这篇文章主要介绍了Javascript Promise用法详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • JavaScript函数式编程(Functional Programming)箭头函数(Arrow functions)用法分析

    JavaScript函数式编程(Functional Programming)箭头函数(Arrow functions)

    这篇文章主要介绍了JavaScript函数式编程(Functional Programming)箭头函数(Arrow functions)用法,结合实例形式分析了javascript函数式编程中箭头函数相关概念、原理、用法及操作注意事项,需要的朋友可以参考下
    2019-05-05
  • javascript编写简易计算器

    javascript编写简易计算器

    这篇文章主要为大家详细介绍了javascript编写简易计算器的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • JS冒泡事件的快速解决方法

    JS冒泡事件的快速解决方法

    这篇文章主要是对JS冒泡事件的快速解决方法进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • js中判断控件是否存在

    js中判断控件是否存在

    在动态页面中,页面中包含一些动态产生的控件,在有些情况下需要判断动态生成的控件是否存在。
    2010-08-08
  • 世界上最短的数字判断js代码

    世界上最短的数字判断js代码

    本文给大家分享世界上最短的数字判断js代码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • js数组合并的8种方法(最全)

    js数组合并的8种方法(最全)

    在JavaScript中,有多种方法可以合并数组,本文主要介绍了8种方法,主要包括concat()、spread operator、push()、unshift()、splice()、Array.from()、Array.prototype.reduce()和ES6的Array.prototype.flat(),感兴趣的可以了解一下
    2023-08-08
  • 关于js datetime的那点事

    关于js datetime的那点事

    关于js datetime的一些使用经验分享,想要了解datetime日期操作的朋友可以参考下。
    2011-11-11
  • 基于dropdown.js实现的两款美观大气的二级导航菜单

    基于dropdown.js实现的两款美观大气的二级导航菜单

    这篇文章主要介绍了基于dropdown.js实现的两款美观大气的二级导航菜单,通过调用js插件实现导航效果,非常简单实用,需要的朋友可以参考下
    2015-09-09
  • JavaScript是如何实现继承的(六种方式)

    JavaScript是如何实现继承的(六种方式)

    大多OO语言都支持两种继承方式: 接口继承和实现继承 ,而ECMAScript中无法实现接口继承,ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现,下文给大家技术js实现继承的六种方式,需要的朋友参考下
    2016-03-03

最新评论