前言
在ES5中我们声明变量都是使用的var关键字,从ES6开始新增了两个关键字可以声明变量:let、const
let 关键字
从直观的角度来说,let和var是没有太大的区别的,都是用于声明一个变量
let name = "sabo"
const 关键字
const关键字是constant的单词的缩写,表示常量、衡量的意思;
const name = "abc"
const关键字表示保存的数据一旦被赋值,就不能被修改;
const name = "abc"
name = "sabo"//错误用法
但是如果传递的是一个引用类型(内存地址), 可以通过引用找到对应的对象, 去修改对象内部的属性, 这个是可以的
const boy = {name:"aaa"}
boy.name = "sabo"
注意 通过let 和 const定义的变量名是不可以重复定义
let name = "sabo"
let name = "aaa"//SyntaxError: Identifier 'name' has already been declared
作用域
在ES5中只有两个东西会形成作用域: 全局作用域、函数作用域
全局作用域
在foo函数中能调用name变量,name存在于全局作用中
var name = "sabo"
function foo() {
function demo(){}
console.log(name)
}
函数作用域
demo函数只要在foo函数中才能调用,demo只存在于foo函数的作用中
var的作用域提升
在声明变量的作用域中,如果这个变量可以在声明之前被访问,那么我们可以称之为作用域提升
var声明的变量是会进行作用域提升的
console.log(foo)//undefined
var foo = "foo"
但是如果是let 和const 声明变量呢?
console.log(foo)//ReferenceError: Cannot access 'foo' before initialization
let foo = "foo"
我们可以看一下ECMA262对let和const的描述:
这些变量会被创建在包含他们的词法环境被实例化时,但是是不可以访问它们的,直到词法绑定被求值;
在这里,创建出来变量了,但是不能被访问,不能let和const称之为作用域提升;
let/const的块级作用域
在ES6中新增了块级作用域,并且通过let、const、function、class声明的标识符是具备块级作用域的限制的
{
let foo = "why"
function demo() {
console.log("demo function")
}
class Person {}
}
console.log(foo) // foo is not defined
var p = new Person() // Person is not defined
demo()//demo function
但是这里有个特殊就是function 不同的浏览器有不同实现的(大部分浏览器为了兼容以前的代码, 让function是没有块级作用域) 携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情