哈喽大家好,又见面啦,我仍旧是那个可恶的蛙人。
明天又周五了啊,划水人的一天,开心。
话不多说哈,间接搂代码
var 变量晋升机制
咱们在全局作用域中或还是在部分作用域中,应用var
关键字申明的变量,都会被晋升到该作用域的最顶部,这就是咱们常说的变量晋升。
function person(status) { if (status) { var value = "蛙人" } else { console.log(value) // undefined } console.log(value) // undefined}person(false)
下面example中,if
代码块中的var申明的变量就被晋升到了函数的顶端,有的小伙伴就会纳闷了,if
代码块里的都没执行,怎么会晋升到顶端了呢?,这是因为javaScript引擎,在代码预编译时,javaScript引擎会主动将所有代码外面的var
关键字申明的语句都会晋升到以后作用域的顶端, 因而下面的代码就会被解析为上面。
function person(status) { var value; if (status) { value = "蛙人" } else { console.log(value) // undefined } console.log(value) // undefined}person(false)
因为javaScript存在变量晋升,这让很多开发者初学起来这门语言,还得花不少工夫钻研变量晋升,也有时在工作中因为一个变量晋升导致出bug。因而Escript6中为咱们带了块级申明
,那么什么是块级申明呢?
- 只在以后函数下申明的变量无效
- 在代码块和{ }括号之内无效
let申明
let
申明和var申明用法是一样,都是定义变量,应用let申明的变量没有var那样的变量晋升,let申明的变量只在以后作用域中无效。咱们来把下面的example重写一下。
function person(status) { if (status) { let value = "蛙人" } else { console.log(value) // 报错 } console.log(value) // 报错}person(false)
let是块级作用域,所有里面的语句块拜访不到,let是没有变量晋升的,上面咱们来演示一下。
console.log(value) // 报错let value = "蛙人"
禁止反复申明
如果在同一个作用域中某个变量曾经存在,再次应用let关键字申明的话会报错。
var value = "蛙人"let value = "蛙人" // 报错// 再来看一下不同作用域的状况var value = "蛙人" // 全局作用域if(true) { let value = "蛙人" // 代码块中申明,毫无影响}
下面example中,能够齐全看到,只有在雷同作用域中反复申明变量才会报错。
const申明
ECMAscript6中还提供了const关键字申明,const申明指的是常量,常量就是一旦定义完就不能批改的值。还有一点须要留神的是,常量定义必须初始化值,如果不初始化值就会报错。
const value = "蛙人"const age; // 报错 常量未初始化
const 与 let
const与let也没什么大不同,都是块级作用域,const常量也只会在以后代码块内无效,也不能在以后作用域中反复定义雷同的变量,也不存在变量晋升。
if (true) { const name = "蛙人"}console.log(name) // 报错 拜访不到外部变量
console.log(value) // 报错 const申明的变量也不存在变量晋升const value = "蛙人"
let value = "蛙人"const value = "蛙人" // 报错 反复申明
const申明对象
尽管const变量不能批改指针,然而能够批改值,比方咱们定义一个对象,咱们就能够批改对象里的属性值,然而不能够重写整个对象。
const person = { name: "蛙人", age: 23}person.age = 18 // 没问题person = {} // 报错 不能批改对象指针
临时死区
跟var相比,let和const定义变量不会被晋升到作用域顶端,即使是用绝对平安的typeof也会呈现谬误。
console.log(typeof value)let value = "蛙人"
下面example中,console.log(typeof value)
会抛出谬误是因为用let定义并初始化变量语句是不会执行的。此时的value还是处于在JavaScript所谓的临时死区(temporal dead zone)
简称为TDZ 中,尽管JavaScript没有明确规范TDZ,然而人们罕用它形容let和const定义的变量不会晋升。
咱们来说一下TDZ工作原理,JavaScript引擎在扫描代码时发现变量申明时,如果遇到var
就会将它们晋升到以后作用域的顶端,如果遇到let或const
就会将申明放到TDZ中,如果拜访TDZ中的变量就会抛出谬误,只有执行完TDZ中的变量才会将它移出,而后就能够失常办法。这机制只会在以后作用域失效。咱们来看下不同作用域案例
console.log(typeof value) // "undefined"if (true) { let value = "蛙人"}
下面说的如果变量是let和const申明的就会被放到TDZ中,前提是只会针对以后作用域内无效。所以下面代码中console.log(typeof value)
不会抛出谬误,let申明只会在以后的语句中无效。