资讯专栏INFORMATION COLUMN

白话es6系列二:你真的会声明变量吗

maybe_009 / 1712人阅读

摘要:新增了二个声明变量的关键字,和,再加上之前的,这样声明变量就有三个关键字了,大有三国鼎立之势。当的值为时,该变量不会被声明并初始化。如果上面的那个循环中用声明变量,那么循环完了,变量也就随时销毁,不能再被访问。

ES6新增了二个声明变量的关键字,let和const,再加上ES6之前的var,这样声明变量就有三个关键字了,大有三国鼎立之势。那到底用哪个来声明变量呢?
var

首先,得说说var的特殊行为,变量提升,来看一个例子:

var condition = false

if (condition) {
  var value = "red"
  console.log(value)
} else {
  // value 在这里可以访问,值为undefined
  console.log(value)
}

在上面代码中,即使condition为false,变量value也是存在的,相当于如下定义:

var condition = false
var value

if (condition) {
  value = "red"
  console.log(value)
} else {
  // value 在这里可以访问,值为undefined
  console.log(value)
}

就是说,使用var关键字声明的变量,无论其实际声明位置在何处,都会被视为声明于所在函数的顶部(如果声明不在函数内,则视为在全局作用域的顶部),这就是变量提升。

对这种特殊行为,如果你不理解,就很可能导致bug。我们来看一个循环的例子:

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

// i 在这里依旧可以访问
console.log(i)  // 6

for循环完了,已经不再需要变量i,但是它依旧可以被访问。

所以,ES6引入了块级作用域,让变量的生命周期更加可控,于是,let出现了。

块级声明-let

我们来看看用let声明的代码:

var condition = false

if (condition) {
  let value = "red"
  console.log(value)
} else {
  // value 在这里不可以访问,会报错
  console.log(value)
}

由于变量value声明使用的是let,所以就没有被提升到函数定义的顶部,变量value在if代码块外部是无法访问的。当condition的值为false 时,该变量不会被声明并初始化。
如果上面的那个for循环中用let声明变量i,那么循环完了,变量i也就随时销毁,不能再被访问。

常量声明-const

使用const声明的变量会被认为是常量(constant),意味着它们的值在被设置完成后就不能再被改变,常量声明与let声明一样,都是块级声明。
来看个小例子:

const num = 12
num = 13 // 报错

const obj = { name: "moddx", age: 28 };
obj.age = 26 // 正常

上面用const声明了一个变量num,当重新给其赋值时会报错,而变量obj初始化之后,再将其age属性改变,不会报错,因为对象是一个引用类型,其指向的内存中的地址是没有被改变的,除非将其重新赋值给一个新对象,就会报错,如下:

const obj = { name: "moddx", age: 28 };
obj = { name: "foo" } // 报错
总结

说了这么多,那到底时候用什么关键字来声明呢?就没有一个标准或者约定俗成的习惯吗?
目前,被广泛认可的变量声明方式是:默认情况下应当使用const,当你确定声明的变量需要改变时,用let声明。其依据是大部分变量在初始化之后都不应当被修改,因为预期外的改动是bug的源头之一。(那var呢?好吧,基本被抛弃了)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102676.html

相关文章

  • 深入理解JavaScript

    摘要:深入之继承的多种方式和优缺点深入系列第十五篇,讲解各种继承方式和优缺点。对于解释型语言例如来说,通过词法分析语法分析语法树,就可以开始解释执行了。 JavaScript深入之继承的多种方式和优缺点 JavaScript深入系列第十五篇,讲解JavaScript各种继承方式和优缺点。 写在前面 本文讲解JavaScript各种继承方式和优缺点。 但是注意: 这篇文章更像是笔记,哎,再让我...

    myeveryheart 评论0 收藏0
  • 白话es6系列一:Array.of()和Array.from()

    摘要:更重要的是,代码意图也直观数组长度,每一项按照约定的规则进行初始化。上面代码创建了一个长度为的数组其中的项为数字。的强大不止于此,它还能接受一个映射函数上面代码中,被直接传递给方法,从而将它包含的值转换成了数组。 es6新增了二种方法:Array.of()和Array.from(),它们有什么用途呢?在平时的开发中能给我们带来什么方便呢?本篇将从一个创建数组的小问题开始,逐步揭开它们的...

    newtrek 评论0 收藏0
  • 真的懂switch?聊聊switch语句中的块级作用域

    摘要:最近在代码中不小心不规范的,在里面定义了块级变量,导致页面在某些浏览器中出错,本文讨论以下语句中的块级作用域。而与无关每一个并不会构成一个独立的块级作用域。   最近在代码中不小心不规范的,在switch里面定义了块级变量,导致页面在某些浏览器中出错,本文讨论以下switch语句中的块级作用域。 switch语句中的块级作用域 switch语句中的块级作用域可能存在的问题 规范和检...

    zone 评论0 收藏0
  • 真的懂switch?聊聊switch语句中的块级作用域

    摘要:最近在代码中不小心不规范的,在里面定义了块级变量,导致页面在某些浏览器中出错,本文讨论以下语句中的块级作用域。而与无关每一个并不会构成一个独立的块级作用域。   最近在代码中不小心不规范的,在switch里面定义了块级变量,导致页面在某些浏览器中出错,本文讨论以下switch语句中的块级作用域。 switch语句中的块级作用域 switch语句中的块级作用域可能存在的问题 规范和检...

    pkwenda 评论0 收藏0

发表评论

0条评论

maybe_009

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<