一文带你了解var let const三者的异同

114 阅读3分钟

前言

最近有了跳槽的念头(目前这个行情竟然萌生了这种念头,哈哈哈),准备翻一翻之前的笔记,发现竟然找不到了😬😬,突然意识到问题的严重性🤣,那就整理巩固一下吧!开始了一个小白的救赎之路。

正文

继ES5之后,ES6又新增了两个定义变量的方法let const。

重复声明

var str = '哦豁'
var str = '哦哟'
console.log(str) // 哦哟
// str: 覆盖重名变量
let str = '哦豁'
let str = '哦哟' // 此行直接报错 Identifier 'str' has already been declared  (译;标识符“str”已声明)
console.log(str)
const str = '哦豁'
const str = '哦哟' // 此行直接报错 Identifier 'str' has already been declared
console.log(str)

即var定义重复变量直接覆盖,let、const不允许重复声明变量,声明重名变量直接报错

变量提升

console.log(str)
var str = '哦豁'
// 输出undefined,那么我们得知在log之前,str确实是已经定义了,只是没有赋值而已
// 以上代码相当于
var str
console.log(str)
str = '哦豁'
console.log(str) // 此行直接报错 Cannot access 'str' before initialization  (译;初始化前无法访问“str”), 因为let/const的暂时性死区,必须先声明后使用,以至于不存在变量的提升
let str = '哦豁'
console.log(str) // 此行直接报错 Cannot access 'str' before initialization  (译;初始化前无法访问“str”)
const str = '哦豁'

即var存在变量的提升,let const不存在变量的提升

块级作用域

(function(type) {
    if(type === 'var') {
        var str = 'actionScope'
        console.log('str1', str) // actionScope
    } else {
        console.log('str2', str) // 可以访问到 undefined
    }
    console.log('str3', str) // actionScope
})('var')
// 当参数type为'var'时,str1与str3均为'actionScope'
// 当参数type不为'var'时,str2与str3均为undefined

由此可见,var 声明的变量没有块的概念,可以跨块访问,但是不能跨函数访问(作用域不同)

(function(type) {
  if(type === 'let') {
    let str = 'actionScope'
    console.log('str1', str) // actionScope
  } else {
    console.log('str2', str) // 报错 str is not defined
  }
  console.log('str3', str) // 报错 str is not defined
})('let')
// 当参数type为'let'时,str1为'actionScope',log(str3)报错
// 当参数type不为'let'时,log(str2)报错

let声明的str变量是在type为var的’{}‘中,由于块级作用域的缘故,只能在声明的’{}‘作用域中被访问
const 同let

const定义常量,不允许被修改

const str = 'constant'
str = 'change' // 直接报错 Assignment to constant variable.

const定义常量必须初始化

const str; // SyntaxError: Missing initializer in const declaration
a = 'actionScope'
console.log(a)

也就是说const定义常量时必须给一个初始值

同一变量只能用一种方式声明

var str = 'action'
let str = 'scope'

报错 Identifier 'str' has already been declared

总结:

  1. var定义的变量,没有块的概念,可以跨块访问,不能跨函数访问。
  2. let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问.
  3. const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改
  4. 同一个变量只能使用一种方式声明,不然会报错
  5. let,const不存在变量的提升,var存在变量的提升