es6的总结下var、let 和 const 的区别

2023-05-16

var 和 let 的区别是老生常谈,看到网上一些文章的总结,有的不太全面,甚至有的描述不太准确,在这里尽量全面的总结下这三者的区别。


let 是 ES6新增的变量类型,用来代替 var 的一些缺陷,跟 var 相比主要有以下区别:

1. let 使用块级作用域

在 ES6之前,ES5中js只有全局作用域和函数作用域,例如:

if(true) {
   var a = 'name'
}
console.log('a',a) // name

作用域是一个独立的地盘,让变量不外泄出去,但是上例中的变量就外泄了出去,所以此时 JS 没有块级作用域的概念。

var a = 1;
function fn() {
   var a = 2;
   console.log('fn',a);
}
console.log('global',a);
fn();

全局作用域就是最外层的作用域,如果我们写了很多行 JS 代码,变量定义都没有用函数包括,那么它们就全部都在全局作用域中。这样的坏处就是很容易冲突。
ES6中加入块级作用域之后:

if(true) {
   let a = 'name'
}
console.log('a',a) // Uncaught ReferenceError: a is not defined

块作用域内用 let 声明的变量,在块外是不可见的,如果引用的话就会报错。

2. let 约束了变量提升而不是没有变量提升

在 js 中变量和函数都会提升:

function fn() {
   console.log('a',a);
   var a = 1;  // undefind
}
fn()

a其实已经在调用前被声明了,只是没有被初始化。JavaScript会把作用域里的所有变量和函数提到函数的顶部声明,相当于:

function fn() {
   var a;
   console.log('a',a);
   a = 1;  // undefind
}
fn()

JavaScript会使用undefined缺省值创建变量a,事实上浏览器并没有把声明语句放到作用域的顶部,在编译阶段,控制流进入域,该域所有的变量和函数的声明先进入内存,文中代码的相对位置不会变动。

变量提升指的是变量声明的提升,不会提升变量的初始化和赋值。

并且函数的提升优先级大于变量的提升:

function fn() {
            console.log('a', a);
            var a = 1;
            function a () {
                console.log('I am a function');
            }
        }
        fn() // ƒ a () {console.log('I am a function');}

在上例中, let 声明的变量的作用域之外引用该变量会报错,但是否可理解为 let 没有变量提升?

let a = 'outside';
if(true) {
   console.log(a);//Uncaught ReferenceError: a is not defined
    let a = "inside";
}

报出错误 a 没有被定义,而不是引用了全局作用域里的 a,说明 let 声明的 a 也被提升了。

原因是 let 设计中的暂时性死区:
当前作用域顶部到该变量声明位置中间的部分,都是该let变量的死区,在死区中,禁止访问该变量。由此,我们给出结论,let声明的变量存在变量提升, 但是由于死区我们无法在声明前访问这个变量。

3. let 禁止重复声明变量

使用 var 可以重复声明变量,但是 let 不允许在同一块作用域内重复声明同一个变量:

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

function fn (){
   let a = 1;
   let a = 2;
   console.log(a); //SyntaxError
}

function fn (a){
   let a = 2;
   console.log(a); //SyntaxError
}

上述代码会报语法错误;

4. let不会成为全局对象的属性

我们在全局范围内声明一个变量时,这个变量自动成为全局对象的属性(在浏览器和Node.js环境下,这个全局对象分别是windowglobal),但let是独立存在的变量,不会成为全局对象的属性:

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

let b = 2;
console.log(window.b); // undefined

5. const 声明的常量

以上 let 的规则同样适用于 const,但是跟 let 的区别是 const 声明的变量不能重新赋值,所以 const 声明的变量必须经过初始化

const a = 1;

a = 2; // // Uncaught TypeError: Assignment to constant variable
const b; // Uncaught SyntaxError: Missing initializer in const declaration

最后

以上大概是总结后的内容,看来,还是多用 let 、const 吧。

转载于:https://my.oschina.net/architectliuyuanyuan/blog/3095772

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

es6的总结下var、let 和 const 的区别 的相关文章

  • Swift 中“static var”和“var”的区别

    Swift 中 static var 和 var 的主要区别是什么 有人可以用一个小例子向我解释这种差异吗 static var属于类型本身 而var属于类型的实例 特定类型的特定值 例如 struct Car static var num
  • 为什么Java中每次long和double都工作时会有这么多类型的数字?

    现在我一直在尝试学习Java编程 我想知道为什么我们使用这样的东西Float short and int当我们可以只是使用Long and Double 我不明白那部分 很好的问题 特别是如果你来自这样的语言JavaScript它不区分数字
  • /var/log/daemon.log 占用更多空间如何减少?

    下面是文件 rw r 1 root adm 4 4G Mar 6 09 04 daemon log rw r 1 root adm 6 2G Mar 1 06 26 daemon log 1 rw r 1 root adm 50M Feb
  • 如何访问 Ajax 调用中的变量集

    我正在尝试在通过 Ajax 调用一些 PHP 代码的函数中设置一个变量 可以说 问题在于该变量无法从函数外部访问 var startPageSelected function getSavedStartPage post webroot h
  • 如何在 Swift 中创建自定义 getter 方法?

    我正在尝试使用以下代码为我的属性创建自定义设置方法 var myProperty String get if CONDITION1 return CONDITION1 STRING else if CONDITION2 return CON
  • ES6 面试题 | 14.精选 ES6 面试题

    前端开发工程师 主业 技术博主 副业 已过CET6 阿珊和她的猫 CSDN个人主页 牛客高级专题作者 在牛客打造高质量专栏 前端面试必备 蓝桥云课签约作者 已在蓝桥云课上架的前后端实战课程 Vue js 和 Egg js 开发企业级健康管理
  • VUE实践优化:轮询机制与代码结构升级

    前言 我们之前探讨过 对于包含处理状态的表格数据 我们可以通过轮询的方式进行处理 轮询更新进度条 JavaScript中的定时器和异步编程技巧 然而 当我们离开页面时 定时器仍会继续触发请求 这会造成资源的浪费 因为返回的数据并没有被渲染出
  • 【JavaScript】Set方法

    基本用法 ES6 提供了新的数据结构 Set 它类似于数组 但是成员的值都是唯一的 没有重复的值 Set 本身是一个构造函数 用来生成 Set 数据结构 const s new Set 2 3 5 4 5 2 2 forEach x gt
  • Let 和 Let* 的方案混淆

    let x 2 y 3 let x 7 z x y z x 对于上面的代码 为什么答案是 35 而不是 70 在第二let x 是 7 所以 z 应该是 7 3 10 然后结果应该是 7 10 70 我知道还有另一个是 let 我在这 2
  • 无法从 Objective-C 视图控制器访问 Swift var - iOS

    我有一个带有 Objective C 和基于 Swift 的视图控制器的应用程序 我正在以编程方式从我的一个基于 Objective C 的视图控制器之一打开一个基于 Swift 的视图控制器 我遇到的问题是我无法从 Objective C
  • 何时在 ColdFusion 组件中对变量进行 var 作用域?

    a 哪些情况下应该在 ColdFusion 组件中使用 var 作用域变量以及 b 哪些情况下不应使用 var 作用域 当您在 CFC 内实现跨多个请求共享的函数时 即应用程序范围内的单例 服务 CFC 您应该对变量进行 var 作用域 如
  • Swift:模型结构,使用选项与空值初始化

    In Swift 比如说我有一个struct为了这model struct Message var message String var timestamp String var id String 我会实例化多个Messages使用这个s
  • 使用 LINQ 和实体框架检查 C# var 中的 null 值

    我对 LINQ 和实体框架以及 C 中的 var 关键字都很陌生 所以如果这听起来像一个 新手 问题 请原谅我 在执行以下操作后 我在检查空值时遇到问题 var entry myDB Entries Where e gt e Email e
  • 前端基础:回顾es6相关知识

    Author note 题记 ECMAscript is international standard of javascript ECMA 是 js的国际标准版语言 let and const 为什么之前用var现在需要用let cons
  • Clojure 中的变量作用域 + eval

    在 Clojure 中 def x 3 eval prn x 打印 3 而 let y 3 eval prn y and binding z 3 eval prn z 生成 无法解析 var 异常 根据http clojure org ev
  • PHP:$var 和 &$var 有什么区别?

    有什么区别 foreach my array as my value And foreach my array as my value 我可以请您举两个现实世界的例子来说明何时使用其中一种以及何时使用另一种吗 第一个示例创建值的副本 而第二
  • 将“var”传递给另一个方法

    我可能完全错过了这里的重点 但是 如何将 var 传递给另一个方法 我正在使用 linq 将 XML 加载到可枚举对象列表中 我有不同的对象类型 具有不同的字段 但无论使用哪个对象 我的过程的最后一步都是相同的 XNamespace xml
  • VB.NET 相当于 C# var 关键字 [重复]

    这个问题在这里已经有答案了 是否有与 C 等效的 VB NETvar关键词 我想用它来检索 LINQ 查询的结果 选项推断 http msdn microsoft com en us library bb384665 aspx必须是on为了
  • 用 let 或 const 声明的变量是否被提升?

    我已经使用 ES6 一段时间了 我注意到虽然用var按预期被吊起 console log typeof name undefined var name John 声明的变量let or const吊装似乎存在一些问题 console log
  • 循环中的 let 语句在 IE 中无法按预期工作

    我正在尝试 ECMAScript 6 中的一些示例 与其他浏览器相比 它的工作方式有所不同 这返回true在 Firefox 中 但它返回false在IE中 为什么这在 Internet Explorer 中的工作方式有所不同 let ca

随机推荐