当前位置: 首页 > news >正文

【ES6】var let const 之面试题系列

关于 var、let、const 是前端开发人员经常用到的关键字,也是经典的面试题,接下来就站在面试题的角度来看待它们之间的区别。

一、区别

1. var 声明的范围是函数作用域,let 和 const 声明的范围是块作用域,块作用域是函数作用域的子集,因此适用于 var 作用域限制的也同时限制于 let。  

function fn() {var a = 1;console.log(a)  // 1
}
console.log(a)  //Error
{let a = 1;console.log(a)  // 1
}
console.log(a)  // Error

2. var 声明的变量会被提升到函数作用域的顶部,let 和 const 声明的变量不存在提升,并且具有暂时性死区的特征。

function fn() {console.log(a)  // undefinedvar a = 1;
}
function fn() {console.log(a)  // Errorlet a = 1
}

暂时性死区:在解析代码时,JS 引擎会注意到块后面的 let 声明,但在此之前不能以任何方式来引用未声明的变量。

3. var 允许在同一个作用域中重复声明同一个变量,let 和 const 不允许。

var a = 1;
var a = 'hello'
console.log(a)  // hello
let a = 1;  // a报错
let a = 'hello'  // a报错
const a = 1;  // a报错
const a = 'hello'  // a报错

4. 在全局作用域中使用 var 声明的变量会成为 window 对象,let 和 const 声明的变量不会。

var a = 1;  
console.log(window.a)  // 1
let a = 1;  
console.log(window.a)  // undefined
const a = 1;  
console.log(window.a)  // undefined

5. const 的行为与 let 基本相同,唯一一个重要的区别是,使用 const 声明的变量必须进行初始化,并且不能被修改。

let a;
console.log(a)  // undefined
a = 1;
console.log(a)  // 1
const a;  // a报错// const 必须在声明时赋初始值,并不能重新赋值
const a = 1;
a = 'hello'  // a报错// const 声明的限制只适用于它指向的变量的引用,如果 const 变量引用的是一个对象,那么修改这个对象内部的属性是不受限制的
const obj = {name: 'bao',age: 18
}
console.log(obj.age)  // 18
obj.age = 20;
console.log(obj.age)  // 20

二、经典面试题

1. 块级作用域

// var
for(var i = 0; i < 5; i++) {...
}
console.log(i)  // 5// let
for(let i = 0; i < 5; i++) {...
}
console.log(i)  // Error

var 声明的变量没有块作用域,所以迭代变量 i 会渗透到循环体外部,属于全局变量,当 i 递增到5时退出循环,打印出来的结果自然是5。又因为 let 有块级作用域,所以在块级作用域外面无法访问到此变量,则打印Error。

2. 同步与异步

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

使用 var 之所以是这样的结果,是因为在退出循环时,迭代变量保存的是导致循环退出的值,也就是5,在之后 setTimeout 异步调用的时候已经是循环结束的值,所以打印5个5。

而使用 let 声明迭代变量时,JS 引擎在后台会为每个迭代循环声明一个新的迭代变量,每个 setTimeout 引用的都是不同的变量实例,所以最后打印的值是期望的值,也就是循环执行过程中每个迭代变量的值。

三、总结

ES6 增加 let 和 const 从客观上为这门语言更精确地声明作用域和语义提供了更好的支持,var 所造成的问题,随着这两个关键字的出现,也被慢慢的解决,有效的提升了代码的质量,变量有了明确的作用域已经不能改变的限制。

对于新的两个关键字,优先使用const,let 次之。使用 const 声明可以让浏览器运行时强制保持不变,也可以让静态代码分析工具提前发现不合法的赋值操作。只在提前知道未来会有修改时,才使用 let,这样可以让开发者更有信心地推断某些变量的值永远不会变,同时也能迅速的发现因意外赋值导致的非预期行为。

http://www.lryc.cn/news/28377.html

相关文章:

  • Vue基础入门讲义(四)-组件化
  • Android onLayout布局流程解析
  • 浅分析BIG-建筑展示系统
  • 模电基础(1) 半导体基础知识
  • 阅读笔记:TF - IDF 原理
  • 【C语言】float 关键字
  • Linux 网络编程(实现多路IO转接服务器)
  • DC-4 靶场学习
  • QML组件
  • canvas 学习指南
  • 【华为OD机试2023】开心消消乐 C++
  • 学历?能力?
  • 使用ECharts打造一个数据可视化面板
  • 【论文简述】PVSNet: Pixelwise Visibility-Aware Multi-ViewStereo Network(arxiv 2020)
  • CSS隐藏元素的几种方式以及display、visibility、opacity的区别
  • 【Java|golang】1487. 保证文件名唯一---golang中string方法的坑
  • flstudio21水果language选项中文设置方法教程
  • Ubuntu中安装StaMPS
  • Spring Security 实现自定义登录和认证(1)
  • Linux 进程:辨析wait与waitpid
  • 移除元素(每日一题)
  • 打印名片-课后程序(Python程序开发案例教程-黑马程序员编著-第一章-课后作业)
  • 为啥预编译SQL能够防止SQL注入
  • IGKBoard(imx6ull)-SPI接口编程-回环测试
  • Python基础学习10——类
  • 项目实战典型案例14——代码结构混乱 逻辑边界不清晰 页面美观设计不足
  • SpringBoot 读取自定义Properties参数
  • 机器学习100天(三十七):037 朴素贝叶斯-挑个好西瓜!
  • c#遍历窗口,根据标题获取handle并显示窗口
  • MyBatis高频面试专题