如何选择Var、Let、Const?

在ES6标准中JS对变量声明语法增加了let和const关键字,但是在工作中我还是常常发现很多朋友习惯于var,部分朋友可能会说“哦!我知道let,它用来声明局部变量。const的话,当然就是常量咯。”可是真的就是这样简单吗?那为什么很多人还是喜欢用var,或者仅仅只是在花括号中使用let?本片文章我们就这三个变量声明Key进行说明。

什么是变量声明和变量初始化?

我们先从变量初始化说起,相信这个问题很多朋友都可以正确回答出来,但我觉得还是需要在这里说明一下。先看看下面的代码:

<script>
    // 变量声明
    var codertoy;
​
    document.writeln(codertoy); // undefined
​
    document.writeln('<br />');
    // 变量初始化
    codertoy = '码农玩具';
​
    document.writeln(codertoy); // 码农玩具
</script>

我们可以看到我们在页面显示第一个codertoy变量时结果是“undefined”,在我们给codertoy赋值之后再次调用codertoy变量结果是“码农玩具”。所以变量初始化应该是给变量一个具体的值,如果我们只是写了上面例子中的第二行的代码,这只是说明我们声明了一个变量,这里我们稍作扩展,再来看看下面的例子:

<script>
    document.writeln(codertoy); // ReferenceError
</script>

这个例子中我们直接调用codertoy,我们发现提示“ReferenceError”引用错误,这是因为我们并没有声明过codertoy这个变量。我们继续看下面一个例子:

<script>
    document.writeln(codertoy); // undefined
    // 变量声明
    var codertoy;
</script>

我们发现这次并没有引用错误提示,而是显示“undefined”,这说明在JavaScript中变量声明并不一定要在引用之前。下面继续看一个例子:

<script>
    document.writeln(codertoy); // 码农玩具
    // 变量初始化
    codertoy = '码农玩具';
</script>

这个例子中我们并没有使用var关键字,而是直接给codertoy赋值,浏览器给我们正常显示出了“码农玩具”。那我们来总结一下:

  • 变量声明后默认值是undefined;

  • 变量初始化会先进行隐式变量声明,然后给变量赋值;

  • 变量声明和变量初始化可以在JavaScript中的任意位置,与顺序无关;

什么是Scope(作用域)?

Scope这个词我们可以在各类语言中都可以见到,这么多语言都在使用Scope这一概念,说明它真的相当重要,所以我们必须要搞清楚它。这篇博文我对这个概念仅作基本介绍,稍后的其他博文再对Scope做进一步说明。

我们用一个例子来说明Scope。一栋大楼,大楼本身、大楼的每一层、每一个房间都可以看作一个Scope,我们叫大楼本身的Scope为全局Scope,每一层为层级Scope,每一个房间为块级Scope。在这个例子中,全局Scope包含了层级Scope,层级Scope包含了块级Scope。所以Scope其实就是一个域,每个域中可以有自己的变量和函数,域对同级和父级的域,它的变量和函数是不可见的,但子集的域可以访问父级域的变量和函数。看下面的代码:

function getCodertoy () {
  var codertoy = '码农玩具';
  return codertoy;
}
getCodertoy();
console.log(codertoy); // Reference Error

在上面的例子中codertoy变量声明在getCodertoy这个函数域中,所以在函数作用域的外面直接调用codertoy会报引用错误。

如何使用var、let和const?

有了上面的内容做铺垫,我们现在开始聊聊var、let和const这三者的区别。先看下面一个例子:

<script>
    function getCodertoy() {
        var codertoy = '码农玩具';
        return codertoy;
    }
​
    getCodertoy();
    document.write(codertoy); // Reference Error
</script>

这个例子中我们在getCodertoy函数作用域中声明了一个codertoy变量,在函数作用域外面调用这个变量,得到引用错误提示。说明var并非是直接声明一个全局变量。我们再看看下面一个例子:

<script>
    for(var i=0; i< 5; i++) {
        document.write(i);
    }
    document.write(i);
    // 012345
</script>

这个例子中我们最终获得了“012345”的结果,哇哦!这是怎么回事?是不是与你期望的“01234”以及一个“Reference Error”提示不一样呢?那么这就是了,这里会涉及JavaScript参数引用声明这一知识点,这里我先不讲了。我们会发现如果我把var换成let,那么得到的结果就和我们预期的一样啦。我们总结一下:

  • 在函数作用域中使用var和let在函数作用域外调用都是不可以的;

  • 在for循环这种作用域中使用var声明的变量可以在for循环之外继续使用,但let声明的变量则不能在for循环之外继续使用。

var和let的另外一个区别是let声明的函数并不会执行声明提升,声明提升(Hoisting)。我们看下面一个例子:

<script>
    document.write(codertoy); // Reference Error
    let codertoy = '码农玩具';
</script>

还记得我们在上面讲变量声明和变量初始化的时候举的一个关于var的类似例子吗?如果我们使用var进行变量声明,则不会报引用错误,而我们使用let就会得到这个提示。

建议:优先于var使用let作为变量声明的原则,这样可以防止全局作用域变量污染。

什么时候用const呢?const的作用与let基本相同,不过很多朋友会将const理解为常量,其实这个关键字声明的变量准确的应该说是不可重复赋值的变量。常量是赋值之后不可以修改,而不可重复赋值的意思就是只可以赋值一次,但可以修改值。是不是优点困惑这样的解释?我们先来看看例子:

<script>
    const codertoy = {
        name:'码农玩具'
    };
    
    codertoy.name = 'Coder Toy'; 
    document.write(codertoy.name); // Coder Toy
​
    codertoy = 'Coder Toy'; // Type Error
</script>

我们可以看到我们成功的修改了codertoy.name的值,但当我们想给codertoy变量重新赋值时却提示我们“Type Error”类型错误。所以大家应该明白常量和不能重新赋值的区别了吧。

建议:优先使用const,根据需要使用let,最后使用var。
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值