曾经 var 如帝王一般统治过 JS 的变量声明,直到后来大佬们实在是忍不了 var 那稀烂的声明规则,便引入了 letconst 这两大刀斧手,var 被轻轻松松的斩落马下,如今,再难看见 var 的身影。

变量声明

在 JS 中,所有变量都可以用 varletconst 这三个关键字声明。

// 字符串
var name1 = '前端路引';
let name2 = '前端路引';
const name3 = '前端路引';
// 数字
var age1 = 18;
let age2 = 18;
const age3 = 18;
// 布尔值
var isDev1 = true;
let isDev2 = true;
const isDev3 = true;
// 空值
var null1 = null;
let null2 = null;
const null3 = null;
// 数组
var arr1 = [1, 2, 3];
let arr2 = [1, 2, 3];
const arr3 = [1, 2, 3];
// 对象
var obj1 = {};
let obj2 = {};
const obj3 = {};
// 函数
var fn1 = function () {
console.log('前端路引');
}
let fn2 = function () {};
const fn3 = function () {};

以上的各种声明方法都是有效的,JS 语法也没强制要求必须用某个关键字声明变量。

区别

它们之间有哪些恩恩怨怨,为什么会在新的语法中引入 letconst 来取代 var 呢?

作用域

var 申明的变量,拥有函数作用域,在整个函数体内部都能访问。

let 和 const 申明的变量是块级作用域,出了代码块(就是 {} 包裹的代码片段)就不可以再访问了。

function funcScope() {
if (true) {
var a = 1; // 函数作用域
let b = 2; // 块级作用域
const c = 3; // 块级作用域
}
console.log(a); // 1(var 穿透了 if 代码块)
console.log(b); // ReferenceError: b is not defined
console.log(c); // ReferenceError: c is not defined
}

变量申明提升

var 申明的变量,不论在哪个位置申明,都会提升到作用域顶部。

let 和 const 申明存在 暂时性死区(TDZ),这些名词道道记不住也罢,反正您只要知道在申明之前使用会报错就对了。

console.log(x); // undefined(变量提升)
var x = 10;
console.log(x); // 10 console.log(y); // ReferenceError: y is not defined(暂时性死区)
let y = 20;

var 申明的变量,在申明之前使用会获取 undefined,这就是所谓的 变量申明提升

重复声明

var 允许同一个变量重复声明。

let 和 const 禁止重复声明。

var a = 1;
var a = 2; // 允许
console.log(a) // 2 let b = 1;
let b = 2; // SyntaxError: Identifier 'b' has already been declared const c = 1;
const c = 2; // SyntaxError: Identifier 'c' has already been declared

let 和 const 重复声明同一个变量,会报语法错误。

全局作用域下的行为

如果在全局作用域中使用 var 申明一个变量,那么这变量会变成全局对象(如 window)的一个属性。

let 和 const 则不会绑定到全局对象。

什么是全局作用域?比如新建一个 a.js,使用 <script src="a.js"></script> 引入这个 JS 文件到 html 页面中,那么这个 JS 文件最外层就称之为全局作用域。

新建一个 test.html,引入 a.js:

<script src="a.js"></script>

新建一个 a.js:

// 全局作用域
var globalVar = 1;
console.log(window.globalVar); // 1 let globalLet = 2;
console.log(window.globalLet); // undefined function test () {
// 函数作用域
}; {
// 块级作用域
}

可变性

var 和 let 声明的变量可以重新赋值。

const 声明的是常量,必须初始化且不可重新赋值(但对象/数组的内容可修改)。

var str = '前端路引';
str = 'web3dev'; // 允许修改变量 let num = 1;
num = 2; // 允许修改变量 const PI = 3.14;
PI = 3; // TypeError: Assignment to constant variable.(不可重新赋值) const obj = { a: 1 };
obj.a = 2; // 允许(修改属性)
obj = {}; // TypeError: Assignment to constant variable.(不可重新赋值)

为什么 const 申明的数组和对象可以修改?

这就涉及到 引用 这个概念了,可以理解为 数组对象 就像现实中的房子。const 申明就像给房子打上了标签贴,拥有了这个房子的使用权,但这房子不止 const 一个拥有者,房子的主人还能对房子进行室内装修改变。const 的标签贴只能使用一次,要想把这标签再贴在另一座房子,那么就行不通了!!

循环

var 申明的变量会泄露到循环体外部。

let 仅作用于循环体内部。

for (var i = 0; i < 3; i++) {}
console.log(i); // 3 for (let j = 0; j < 3; j++) {}
console.log(j); // ReferenceError: j is not defined

let 解决异步回调问题:

// var 的问题
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i)); // 输出 3, 3, 3
} // let 的解决方案
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j)); // 输出 0, 1, 2
}

写在最后

最佳实践推荐:所有变量声明优先考虑使用 const ,如果确定变量需要修改再使用 let

果您的代码确实需要兼容 2017 年之前的浏览器,那么使用 var 吧,别考虑 constlet 了。当然也可以使用 babel 等编译器,将 constlet 转换成 var 兼容低版本浏览器。

Web前端入门第 56 问:JavaScript 变量声明 var、let、const 区别的更多相关文章

  1. JavaScript变量声明var,let.const

    var声明变量的作用域限制在其声明位置的上下文中 var x = 0; // x是全局变量,并且赋值为0. console.log(typeof z); // undefined,因为z还不存在. f ...

  2. javaScript 变量提升 var let const,以及JS 的解析阶段和执行阶段

    我们先来看一道面试题,大家猜想一下,下面这段代码,打印出来的结果是什么 var name = 'World!'; (function () { if (typeof name === 'undefin ...

  3. web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史

    秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...

  4. Android零基础入门第56节:翻转视图ViewFlipper打造引导页和轮播图

    原文:Android零基础入门第56节:翻转视图ViewFlipper打造引导页和轮播图 前面两期学习了 ViewAnimator及其子类ViewSwitcher的使用,以及ViewSwitcher的 ...

  5. 浅谈JavaScript变量声明提升

    前段时间阿里实习生内推,一面就被刷了,也是郁闷.今天系统给发通知,大致意思就是内推环节不足以了解彼此,还可以参加笔试,于是赶紧再投一次.官网流程显示笔试时间3月31日,时间快到了,开始刷题.网上搜了一 ...

  6. javascript变量声明 及作用域

    javascript变量声明提升(hoisting) http://openwares.net/js/javascript_declaration_hoisting.html 可能要FQ一下 java ...

  7. 【转】javascript变量声明 及作用域

    javascript变量声明提升(hoisting) javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 先看 ...

  8. javascript变量声明及作用域总结

    javascript变量声明及作用域总结 一.总结 一句话总结:还是得好好看书,光看视频是不得行的,浅学无用,要相互印证,要真正理解才有用,比如<Javascript权威指南> 书 1.j ...

  9. JavaScript 变量声明提升

    JavaScript 变量声明提升 一.变量提升的部分只是变量的声明,赋值语句和可执行的代码逻辑还保持在原地不动 二.在基本的语句(或者说代码块)中(比如:if语句.for语句.while语句.swi ...

  10. JavaScript变量声明及赋值

    1.变量声明 var a; //声明一个变量 a var b,c,d; //同时申明多个变量时,变量名之间用逗号隔开 console.log(a); //在控制台显示变量a的值,输出为undefine ...

随机推荐

  1. [Windows] 联发科秒开bl一键版(mtk)

    声明 不是所有的联发科都可 天机 8000 8100 9000等不行 已知 天机820 天机1000 mtk G90t 天机800 可以 其余自己测试 除了新款均可 第一步 下载软件 (是个压缩包需要 ...

  2. Easyexcel(3-文件导出)

    响应头设置 通过设置文件导出的响应头,可以自定义文件导出的名字信息等 //编码格式为UTF-8 response.setCharacterEncoding("UTF-8"); // ...

  3. datagrid源码

    /** * jQuery EasyUI 1.2.3 * * Licensed under the GPL terms * To use it on other terms please contact ...

  4. 解决Mac M芯片 Wireshark 运行rvictl -s 后,出现Starting device failed

    前言 mac os big sur 之后,苹果系统的安全性能提升,导致 rvictl -s 创建虚拟网卡失败. $ rvictl -s 000348120-001621w21184C01E boots ...

  5. 如何在 Github 上获得 1000 star?

    作为程序员,Github 是第一个绕不开的网站.我们每天都在上面享受着开源带来的便利,我相信很多同学也想自己做一个开源项目,从而获得大家的关注.然而,理想很丰满,现实却是开发了很久的项目仍然无人问津. ...

  6. JOKER 低代码平台 20250313 重磅更新:全方位升级,解锁开发新体验

    JOKER 低代码平台于 2025 年 3 月 13 日迎来了一次全面且深度的升级.本次更新聚焦前端交互.服务端功能以及通用操作等多个关键领域,致力于打造更卓越的开发环境,为开发者们带来更加高效.稳定 ...

  7. 还原大师-遍历残缺字符串匹配md5杂凑值

    题目: 我们得到了一串神秘字符串:TASC?O3RJMV?WDJKX?ZM,问号部分是未知大写字母, 为了确定这个神秘字符串,我们通过了其他途径获得了这个字串的32位MD5码. 但是我们获得它的32位 ...

  8. 爬虫管理平台-TaskPyro的任务管理

    官网:https://docs.taskpyro.cn/ 任务管理 TaskPyro提供了强大而灵活的任务管理功能,让您能够轻松创建和管理Python脚本的定时任务. 创建任务 在TaskPyro中创 ...

  9. supOS蓝卓工业互联网与iNeuOS工业互联网操作系统对比

    最近有一个企业正在调研工业互联网平台,其中调研的是supOS蓝卓工业互联网和iNeuOS工业互联网操作系统.让我们给出一个对比情况表,我们自己总结了一份,由于不太了解supOS,于是也问了deepse ...

  10. [源码系列:手写spring] IOC第十二节:FactoryBean

    内容介绍 在 Spring 框架中,FactoryBean 是一个特殊的工厂类接口,用于创建和管理复杂的 bean 对象.它允许你自定义 bean 的创建逻辑,并且可以在 bean 创建过程中执行一些 ...