js中var,let,const的区别及相关面试题讲解

 更新时间:2025年05月21日 09:45:52   作者:遗憾随她而去.  
这篇文章主要介绍了js中var,let,const的区别及相关面试题的相关资料,var函数作用域且提升,let块作用域无提升,const需初始化且不可重新赋值,强调let在循环中避免闭包问题,const限制仅针对引用,需要的朋友可以参考下

一. var 

1. var声明作用域 

使用var在一个函数内部定义一个变量,就意味着该变量将在函数退出时被销毁: 

function test(){
  var a='hi' //局部变量
}
test()
console.log(a)//报错

//如果省略操作符 
function test(){
  a='hi' //全局变量
}
test() 
console.log(a) //'hi' 
//去掉var操作符之后,就变成了全局变量,只要调用一次test(),就会定义这个变量,并且可以在函数外部访不  
//推荐这样做,容易造成混乱

 2. 声明提升 ,也就是把所有变量声明都拉倒函数作用域的订单,此外,使用var声明同一个变量也没有问题;

function test(){
  console.log(a)
  var a='hi'
}
test() // undefined 

//等价于下列代码 
function test(){
  var a; 
  console.log(a)
  a='hi'
}

//声明同一个变量
function foo(){
  var a=10;
  var a=20;
  var a=30;
  console.log(a); 
}
foo(); //30

二. let 

1.let 跟var 的作用差不多,最明显的区别是,let声明的范围是块作用域,而var声明的范围是函数作用域 

//var 没有块作用域   块作用域是是函数作用域的子集 因此let也没有函数作用域
if(true){
 var name='matt'; 
 let age=26;
 console.log(name); //matt
 console.log(age); //26
}
console.log(name); //matt 
console.log(age); //age没有定义 

2. let 也不允许同一个块作用域出现冗余声明

var name; 
var name; 

let age;
let age; // age已经声明过了


//不在同一个块中可以重复声明 
let age=30;
console.log(age); //30
if(true){
 let age=26;
 console.log(age); //26
}

//在同一作用域内,不能混用 var 和 let 声明同名变量,否则会抛出 SyntaxError。

var name;
let name;//SyntaxError 

let age; 
var age; //SyntaxError

3. let 有暂时性死区 就是let声明的变量不会在作用域中被提升

// var 会提升
console.log(name); //undefined 
var name='Matt'

//let 不会提升.
console.log(age)// age没有定义
let age=16; 
在let声明之前的执行瞬间被称为"暂时性死区"

4. 使用let在全局作用域中声明的变量不会变成window对象的属性(var声明的则会)

var name='matt'
console.log(window.name); //matt 

let age=26
console.log(window.age); //undefined 

5.for循环中的let声明和var 声明

在let 出现之前,for循环定义的迭代变量会渗透到循环体外部;

for(var i=0;i<5;++i){
  //循环逻辑
}
console.log(i); //5

//改成使用let之后,这个问题就消失了,因为迭代变量的作用域仅限于for循环内部;
for(let i=0;i<5;++i){
 //循环
}
console.log(i); //没有定义

 还有个面试经常提及的问题,在for循环的循环体内定义一个定时器,循环结束后,查看结果

 1. 使用var 的时候 

for(var i=0;i<5;i++){
  setTimeout(()=>console.log(i),1000)
}
//你可能会以为输出0,1,2,3,4
//实际会输出5,5,5,5,5

解释: 我们知道,循环结束的条件是i=5, 从事件循环机制的角度来分析上面的代码,是这样的: 

调用堆栈:用于存储程序按顺序调用的函数的详细信息的堆栈。

   1. 首先在Call Stack(调用堆栈)中执行同步代码var i=0,此时i小于5,执行下一行代码,发现是一个setTImeout计时器,它是一个宏任务,这个时候会被推入到WEB API中,计时器开始执行; 

   2. 执行i++,在Call Stack中进入下一次迭代循环,重复上面操作 

    其实上面的代码中WEB API一共存放过5个计时器,每个计时器进入到WEB API, 1s之后就会被推      入到QUEUE(队列)中(最后队列中也会有5个计时器),等待EVENT LOOP(事件循环)检测到Call           Stack为空时,将QUEUE中每一个计时器推入到Call Stack执行,最后全部代码执行完成,从调用栈       中退出

       使用var 的时候,由于每一次循环得到的迭代变量会被上一次的覆盖,最后i=5,退出循环,迭代变           量也被泄露了出去了,每一个计时器引用同一个i,因此会打印5个5

     《JavaScript高级程序设计4》: 是因为在退出循环时,迭代变量保存的是导致循环退出的值 

       在之后执行超时逻辑时,所有i都是同一个变量,因而输出的都是同一个最终值

2.使用let 的时候 

for(let j=0;j<5;j++){
  setTimeout(()=>{
    console.log('j',j) //1 2 3 4 5
  })
}

 个人理解 for每次循环都是不同的块级作用域,let声明的变量是块级作用域的,所以也不存在重复声明的问题

《JavaScript高级程序设计4》: 在使用let声明迭代变量时,js引擎在后台会为每个迭代循环声明一个新的迭代变量,每个setTimeout引用的都是不同变量实例,所以console.log()输出的使我们期望的值,也就是循环执行过程中每个迭代变量的值 

这种每次迭代声明一个独立变量实例的行为适用于所有风格的for循环,包括for-in和for-of循环

三. const 

1. const 的行为与let基本相同,唯一一个虫重要的区别是用它声明变量时必须同时初始化变量,且尝试修改const声明的变量会导致运行时的错误

const age=26;
age=36; //TypeError: 给常量赋值 

2.const声明的限制只适用于它指向变量的引用,换句话说,如果const变量引用的是一个对象,那么修改这个对象内部的属性并不违反const的限制 

const person={ }
person.name='Matt'; //ok 

3. js引擎会为for循环中的let声明分别创建独立的变量实例,虽然const变量跟let变量很相似,但是不能用const 来声明迭代变量(因为迭代变量会自增);

for (const i=0; i<10;++i)() //TypeError: 给常量赋值

总结 

到此这篇关于js中var,let,const的区别及相关面试题讲解的文章就介绍到这了,更多相关js中var,let,const区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • js将字符串中的每一个单词的首字母变为大写其余均为小写

    js将字符串中的每一个单词的首字母变为大写其余均为小写

    本文主要介绍了javascript将字符串中的每一个单词的首字母变为大写其余均为小写的方法。具有一定的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • Javascript es7中比较实用的两个方法示例

    Javascript es7中比较实用的两个方法示例

    这篇文章主要给大家分享了关于Javascript es7中比较实用的两个方法示例,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-07-07
  • js实时获取窗口大小变化的实例代码

    js实时获取窗口大小变化的实例代码

    下面小编就为大家带来一篇js实时获取窗口大小变化的实例代码。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • javascript 二进制运算技巧解析

    javascript 二进制运算技巧解析

    javascript 中的二进制运算的一些技巧,晒出来和你们分享一下,希望可以帮助你们
    2012-11-11
  • 详解微信小程序开发用户授权登陆

    详解微信小程序开发用户授权登陆

    这篇文章主要介绍了微信小程序开发用户授权登陆,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 老生常谈 js中this的指向

    老生常谈 js中this的指向

    下面小编就为大家带来一篇老生常谈 js中this的指向。小编觉得挺不错的, 现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • JS+CSS实现闪烁字体效果代码

    JS+CSS实现闪烁字体效果代码

    这篇文章主要介绍了JS+CSS实现闪烁字体效果代码,可实现文字按照指定颜色逐次闪烁显示的功能,代码非常简单实用,需要的朋友可以参考下
    2016-04-04
  • Bootstrap每天必学之响应式导航、轮播图

    Bootstrap每天必学之响应式导航、轮播图

    Bootstrap每天必学之响应式导航、轮播图,本文的主要内容是在导航条的下方做一张轮播图,自动播放最新的重要动态,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • Javascript中的匿名函数与封装介绍

    Javascript中的匿名函数与封装介绍

    这篇文章主要介绍了Javascript中的匿名函数与封装介绍,本文分析了jQuery 封装、Backbone 封装、Underscore 封装等内容,需要的朋友可以参考下
    2015-03-03
  • javascript制作loading动画效果 loading效果

    javascript制作loading动画效果 loading效果

    项目中多处要给ajax提交的时候增加等待动画效果,所以就写了一个简单的通用js方法,大家参考使用吧
    2014-01-01

最新评论