`var`、`let`、`const` 和没有关键字的声明有什么区别?

本贴最后更新于 2143 天前,其中的信息可能已经时过境迁

2019-02-08

回答

无关键字

在变量赋值之前如果没有关键字的话,则会把变量分配给全局变量或覆盖已经声明的变量。在非严格模式下,如果变量还没有被声明的话,他将会把变量做为全局对象(浏览器中的 window)的一个属性。在严格模式下,他将抛出异常以防止创建不需要的全局变量。

var

var 是 ES2015 以前声明变量的默认语句。他在函数作用域内创建的变量可以在该作用域中被重新赋值和重新声明。但是,由于缺少块作用域,变量在块作用域外将继续存在。如果在含有循环的异步回调中变量被重用的话将会产生问题。

以下代码片断中,在执行 setTimeout 回调时,循环完已经完成且变量 i 变为了 10,因此十个回调都引用了函数作用域中的同一个变量。

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

可以通过消除块作用域或创建一个新的函数作用域来解决此问题

for (var i = 0; i < 10; i++) {
  setTimeout(console.log, 1000, i)
}

for (var i = 0; i < 10; i++) {
  ;(i => {
    setTimeout(() => {
      console.log(i)
    })
  })(i)
} 

let

let 是在 ES2015 中引入的,他是一种可在变量声明后可再赋值的常用声明方式。再次声明相同的变量将会抛出异常。他是有块作用域的,因此在循环中使用时将会保持在同一个作用域下迭代。

for (let i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i) // 0 1 2...9
  })
} 

const

const 是在 ES2015 中引入的,他是一种新的默认的常用的声明方式。他声明的所有变量将不可再被重新赋值,如果是对象的话,必须保持对象的引用不变。他是块作用域的,且不能被再次赋值。

const myObject = {}
myObject.prop = "hello!" 
myObject = "hello" // Uncaught TypeError: Assignment to constant variable.

加分回答

  • 所有声明在其范围内都会被提升。
  • letconst 中有一个称为时间死区(temporal dead zone TDZ)的概念。虽然声明会被提升,但在进入作用域之后、声明之前他将无法被访问。
  • 尽可能避免使用 var,将 const 作为所有变量的默认声明语句,如果后面需要对变量进行重新分配就使用 let

返回总目录

每天 30 秒

  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖
  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    728 引用 • 1273 回帖 • 2 关注
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    325 引用 • 1395 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • iTanken

    我之前在有 iframe 的父子页面操作中,如果在父页面用 const 声明,就不能像用 var 声明的被子页面调用到,原来是因为块作用域的原因?

    1 回复
  • Vanessa

    var 的那个声明是不是挂载到 window 上了?

    1 回复
  • iTanken

    是用 var varname=''; 声明的,没有用 window.varname='';,不知道为啥就可以在 window 调用到

    1 回复
  • Vanessa

    作用域的问题。看你的 var 声明的地方

    1 回复
  • iTanken

    哦哦,3Q

  • Lee981265
    • es2015 即 es6

    • let:代码块内的变量声明

      1. 变量声明不会提升
      2. 块级作用域
      3. let 不允许相同作用域内多次声明同一变量
    • const:常量声明

      1. 声明后无法修改值
      2. 块级作用域
      3. const 不允许相同作用域内多次声明同一变量
    • window.console.log,,,window.....
      1.window 对象自身的属性和方法
      2.window 的属性方法使用时可以省略 window

  • tslint 规定 无内存指向变化的必须 为 const 否则为 let 。。。。。

  • wizardforcel

    var 其实就是 Lisp,Python 和 PHP 的那种作用域,叫扁平作用域。

请输入回帖内容 ...
Vanessa
我们终此一生,就是要摆脱他人的期待,找到真正的自己。 昆明