前言:
🤡 作者简介:我是Morning,计算机的打工人,想要翻身做主人 🙈 🙈 🙈
🏠 个人主页:Morning的主页
📕系列专栏:前端面试备战
📞 如果小编的内容有欠缺或者有改进,请指正拙著。期待与大家的交流
🔥如果感觉博主的文章还不错的话,👍点赞👍 + 👀关注👀 + 🤏收藏🤏
目录
一.变量提升
知识补充:
当执行js代码的时候,会生成执行环境。函数中的代码会产生函数执行环境,代码只要不是在函数中的,就是在全局执行环境中
面试点一:什么是提升?
(带下划线文字给出了明确答案)
console.log(a); //undefined
b() //函数b
var a=11
function b(){
console.log("函数b");
}
想必大家也看出了端倪,这就是函数和变量提升的原因
提升通俗来将,便是将声明的代码移动到了顶部,这样解释也没什么大问题,便于理解
更加准确的解释应该是:在生成执行环境时,会有两个阶段。第一阶段是创建的阶段,js解释器会找出需要提升的变量和函数,并且给他们在内存中开辟好空间。函数的话会直接将整个函数直接存入内存中,变量的话只声明且赋值为undefined。第二个阶段,也就是代码执行阶段,我们可以直接使用
- 在提升的过程中,相同的函数会覆盖上一个函数,并且函数优先于变量提升
b() //函数b two
function b(){
console.log("函数b one");
}
function b(){
console.log("函数b two");
}
var b='字符串b' //如果变量提升优先的话,会报错b不是函数
var会产生很多错误,所以在ES6中引入了let、const。二者都不能再声明之前使用,但是这不代表其不会提升,提升了,而且也在内存中开辟好了空间。但是因为这个声明的特性,导致了不能在声明前使用
面试点二:什么是暂时性死区
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
上面代码中,存在全局变量tmp
,但是块级作用域内let
又声明了一个局部变量tmp
,导致后者绑定这个块级作用域,所以在let
声明变量前,对tmp
赋值会报错。
ES6 明确规定,如果区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用let
命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
if (true) {
// TDZ开始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ结束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
上面代码中,在let
命令声明变量tmp
之前,都属于变量tmp
的“死区”。
该知识点摘自阮一峰 ECMAScript 6 (ES6) 标准入门教程 第三版
二.var、let、const区别
- var存在提升,我们能在声明之前使用。let、const因为暂时性死区的原因,不能在声明之前使用
- var在全局作用域下声明变量会导致变量挂载在window上,其他二者不会
- let与const基本一致,但是const声明的变量不能再次赋值