前言
大家好,我叫张开心。我希望能够用通俗易懂的话语帮助前端新手快速入门。如果我在文章中有任何错误,请务必指出来,我们一起共同进步。
正文
一、逐一解析
1.var
作用域范围:在红宝书中,对var的解释是:函数作用域。这个该如何解释?
function test(){
var message = "hei";
};
test();
console.log(message) // !Error
可以看到,当我们在函数内部定义一个变量时, 在函数外部访问会报错。
绑定全局作用域:
当在全局中使用var声明一个变量时,会将这个变量作为全局对象的属性,
var value = 1 ;
console.log(window.value) // 1
声明提升:
当时用var定义一个变量,在声明之前使用这个变量时,不会报错,会报undefined。
在js引擎在扫描代码时,会将var声明的变量放在作用域的最顶部。
function test(){
console.log(message);
var message = "aaa"
}
test(); // undefined
//上面的代码 再js运行时,会看作:
function test(){
var message;
console.log(message);
message = "aaa"
}
test(); // undefined
2.let与const
块级作用域:如何理解这个“块”:{ } 两个花括号之间的区域就叫做块。
{
let value = 1;
console.log(value);// 1
}
console.log(value) // 会报错:value is not defined
如果使用的是var :
{
let value = 1;
console.log(value);// 1
}
console.log(value) // 1
所以当我们需要一个变量只需要再一个块级内被访问,就需要使用let或者const关键字。
不可以重复声明:
{
let value = 1;
let value = 2;
}
//会报错
不会绑定全局作用域:
let value = 1 ;
console.log(window.value) // undefined
暂时性死区:
因为let声明变量 不会再作用域中被提升,所以在let声明一个变量之前执行的瞬间被称为“暂时性死区”,表现为声明之前调用会报错。
{
console.log(value);
let value = 1;
}
//Cannot access 'value' before initialization
3.const 与 let的区别
const用于声明常量,其值一旦被设定就不能再做修改,否则会报错。
注意:const不能修改绑定,但允许修改值。
二、额外扩展
循环中的表现
for(var i = 0; i<5 ;++i){
}
consle.log(i);//5
for(let i = 0; i<5; ++i){
}
console.log(i) // Error;
for循环体中,是用var定义变量,变量提升,循环赋值,最后输出5.
循环体中使用let声明变量,属于块内的变量, 在循环体外部无法访问。
在看一个经典的面试题:
for (var i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0) //5,5,5,5,5
};
for (let i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0) //0,1,2,3,4
};
首先这涉及到js事件队列(事件轮询)的问题,(这里不祥讲)。
当使用var时,上述代码再执行的时候,首先执行的是五次for循环,再执行了五次setTimeout。
当退出循环时,准备执行setTimeout的时候,由于使用的var关键字,setTimeout中引用的i变量都是同一个值, 这个值已经变成5,。
当时用let时,执行的也是先五次for循环,再执行了五次setTimeout。
但是不同的是,每次进行for循环的时候都是一个块级,let关键字都会创建一个新的变量i。再执行setTimeout时,取得i都是自己块级中的i,所以输出了0,1,2,3,4
这种表现在for in for of 的循环中表现一样。
这是肯定有人有疑问了,既然let在循环时,每次都创建了一个新的变量, 那是不是意味着const也是可以用的,于是发现会报错。
for (const i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)
};
//Assignment to constant variable.(常量变量的赋值。)
那这是什么原因呢? 因为在每次循环时,虽然创建了新的变量,但是当下一次进入循环时,会有复制操作,i = i + 1。 也就是这个赋值操作,是的结果报错。
话术总结
个人认为是重中之重!!!
在学习阶段,我们需要梳理知识点,以促进对内容的更好理解。但是在面试时,我们需要将这些知识点有条理地表达出来,避免给面试官一种零散的印象。这就需要通过练习来掌握合适的表达方式,不然就会有茶壶里倒饺子的感觉。
在面试过程中,我建议尽量分点或者分步描述,这样既能保持思路的清晰,又能让面试官听得舒服。逐步划分话题并有条不紊地讲解,会使整个回答更易于理解和吸收。
因此,为了在面试中表达得更加流畅,我们应该在训练中改善自己的话术,确保表达逻辑清晰、层次分明,这样既能更好地展示自己的知识水平,也能给面试官留下良好的印象。
面试官提问:“说一说js中var、let、const的区别”
我:“首先这三种都是用来声明变量的,他的不同点,
第一就是,var是ES5之前提出的,let与const是ES6之后出现的。
第二,var是函数作用域,在函数内部声明变量,在函数外部是不能访问的。而let与const是块级作用域,在两个花括号之间的区域用let与const声明变量,在块区域外是不能访问的。使用var在块中,快外部是可以访问的。
第三,变量提升问题,在使用var 声明一个变量时,如果在声明变量前去调用,存在生命提升,不会报错,会返回undefined。但是用let与const声明变量,会存在暂时性死区,表现为在声明前调用会报错。
第四var可以重复声明,但是let重复声明会不报错。最后let与const的主要区别是,当使用const声明后,值将不会被修改,尝试修改他的值将会报错。
在平时的开发中,尽量使用const,当他的值是可以修改的时候,使用let ,尽量不使用var”
面试官提问:“666”