三步彻底搞懂let与var关键词

已被阅读 1101 次 | 文章分类:日常随笔 | 2018-11-03 22:20

相信很多人对let与var关键字理解都是云里雾里,并不能准确get他们区别的实质;这节会通过小demo彻底搞懂这两个关键字的区别

一:let是块作用域关键字

var关键字在块外可以访问(当然函数作用域内除外),但是let关键字只能在它的块内访问

                                            
{var varnum=1;}
{let letnum=1;}
console.log("num",varnum); // 1
console.log("num",letnum); // Uncaught ReferenceError: num is not defined
                            
                                            
                                        

在for循环函数块{}中是一个道理,for循环块外面无法访问

                                            
for(var i=0;i<=4;i++){
}
// 上面等同于
var i;
for(var i=0;i<=4;i++){
}


for(let j=0;j<=4;j++){
}
                                 
// 上面等同于 四个块中的i互不认识
{let i=0;} //i=0的块
{let i=1;} //i=1的块
{let i=2;)} //i=2的块
{let i=3;)} //i=3的块
{let i=4; } //i=4的块

console.log("i",i);  // 5
console.log("j",j);  // Uncaught ReferenceError: j is not defined
                                            
                                        

二:重复使用性

let不允许重复声明,但var关键字可以

                                            
var a=1;
var a=2;
console.log("a",a);  // 2
let b=1;
let b=2;
console.log("b",b);  // Uncaught SyntaxError: Identifier 'b' has already been declared
                                            
                                        

三:变量提升

var关键字允许变量提升,let关键字不可以

                                            
console.log(a);  //undefined
var a=1;
//相当于下面
var a;
console.log(a);//undefined
a=1;

console.log(b);  //Uncaught ReferenceError: a is not defined
let b=1;
                                            
                                        

相当于声明了a,但没有赋值,理解很简单;但是如果let的话,为定义直接使用会报错

四:常见面试for循环魔咒

1.首先来看正常例子

                                            
//这里主要用到了var关键字的重复声明特性
for(var num=0;num<=4;num++){
    console.log("num:",num);    
}
// num:0
// num:1
// num:2
// num:3
// num:4  

//这里用到了let块作用域的特性
for(let num=0;num<=4;num++){
console.log("num:",num);
                                
}
//等同于                                                        
let i=0;console.log(i)} //i=0的块
{let i=1;console.log(i)} //i=1的块
{let i=2;console.log(i)} //i=2的块
{let i=3;console.log(i)} //i=3的块
{let i=4;console.log(i)} //i=4的块
// num:0
// num:1
// num:2
// num:3
// num:4               
                                            
                                        

2.接下来看这个常见面试问题

遇到很多考官会拿var的变量提升说问题,我觉得与提不提升没任何关系,还是作用域问题

                                            
for(var num=0;num<=4;num++){
    setTimeout(function(){
        console.log("num",num);          //输出五次4
    },0); 
}                    
                            
                            
for(var num=0;num<=4;num++){
    setTimeout(function(){
        console.log("num",num);          //输出0,1,2,3,4
    },0); 
}     
                                            
                                        

其实这里考到了两点,作用域和异步事件队列的知识;直接画图解释吧 再插一句:浏览器执行是多线程(包括了主线程,异步线程等等)的,像ajax请求,鼠标交互,settimeout等都属于异步线程,但是javascript执行只有一个线程:主线程

/net/upload/image/20181028/6367636332760235935764248.png

var关键字:有一个num,输出五次;等主线程中的for循环结束后,只有一个num,值为4,然后将事件队列中的四个console.log(4)按照顺序一一输出,就得到了5个4

let关键字:有五个num,分别输出;等主线程中的for循环结束后,有五个值的num,分别为num=0,num=1,num=2,num=3,num=4,然后将事件队列中的五个console.log(num)按照顺序一一输出,就得到了5个不同值

QQ:3410192267 | 技术支持 微信:popstarqqsmall

Copyright ©2017 xiaobaigis.com . 版权所有 鲁ICP备17027716号