网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 人工智能 > 大模型 >

零基础入门前端JavaScript 核心语法:var/let/const、

时间:2026-03-22 20:17

人气:

作者:admin

标签:

导读:文章浏览阅读596次,点赞19次,收藏4次。setTimeout 循环陷阱是 JS 面试超高频考点,也是开发中极易踩坑的场景,其本质是。同样是 ES6 引入的声明方式,用于声明只读常量,除了赋值约束...

一、变量声明三剑客:var、let、const 的本质差异

变量声明是 JS 代码的基础,ES6 的推出彻底重构了 JS 的变量声明体系,letconst的出现解决了var长期存在的作用域缺陷,三者的核心差异集中在作用域规则、声明特性、赋值约束三个维度。

1.1 var:函数作用域的 “老牌声明”

var是 ES5 及之前唯一的变量声明方式,其核心设计围绕函数级作用域展开,也是开发中最容易出现全局污染、变量覆盖问题的根源。

核心特性:

  • 函数级作用域:仅在声明它的函数内部生效,if/for等代码块无法限制其作用域,全局声明会自动挂载到window对象上;
  • 变量提升:声明会被提升到当前作用域顶部,可在声明前调用,值为undefined,不会报错;
  • 允许重复声明:同一作用域内可多次声明同一变量,后声明的值会直接覆盖前声明;

代码示例(修正原文笔误后的可运行版本):

// var无块级作用域,块内声明可在块外访问
if(true){
    var a = 10;
}
console.log(a); // 正常输出10

变量提升典型示例:

console.log(b); // 输出undefined,而非引用错误
var b = 20;

// 上述代码JS引擎实际执行顺序
var b;
console.log(b);
b = 20;

1.2 let:块级作用域的 “标准解决方案”

ES6 引入的let是为了解决var的设计缺陷而生,核心特性是块级作用域,也是现代 JS 开发中循环变量、临时变量的首选声明方式。

核心特性:

  • 块级作用域:仅在声明它的{}代码块内生效,if/for/独立{}都会形成独立作用域,块外无法访问;
  • 暂时性死区:无变量提升,必须先声明后使用,声明前访问会直接抛出引用错误;
  • 禁止重复声明:同一作用域内重复声明同一变量,会直接报语法错误;
  • 全局声明不会挂载到window对象上,避免全局污染。

代码示例(修正原文笔误后的可运行版本):

// let是块级作用域,仅在块内生效
if(true){
    let a = 10;
    console.log(a); // 块内正常输出10
}
console.log(a); // 报错:Uncaught ReferenceError: a is not defined

1.3 const:只读常量的 “终极约束”

const同样是 ES6 引入的声明方式,用于声明只读常量,除了赋值约束外,其余核心特性与let完全一致,是现代开发中常量、固定引用的首选。

核心特性:

  • let一致:块级作用域、暂时性死区、禁止重复声明、不挂载window
  • 强制初始化:声明时必须立即赋值,否则直接报语法错误;
  • 只读约束:基本类型数据(number/string/boolean 等)声明后不可修改;引用类型数据(object/array/function 等)不可修改栈内存中的引用地址,但可自由修改堆内存中的内部属性 / 元素。
// const声明引用类型,不可修改引用地址,可修改内部属性
const person={name:"张三",age:18};
// 合法操作:修改引用类型的内部属性,未改变引用地址
person.age=20;
person.name="李四";
console.log(person); // 输出 {name: '李四', age: 20}

// 非法操作:直接修改引用地址,相当于重新赋值
person={name:"李四",age:18}; // 报错:Uncaught TypeError: Assignment to constant variable.

二、箭头函数(=>):语法简化与 this 绑定的革新

ES6 引入的箭头函数,不仅极大简化了函数的写法,更从根本上解决了传统函数this指向漂移的经典问题,是现代 JS 开发中回调函数、简化函数定义的核心工具。

2.1 箭头函数的基础语法

箭头函数的核心是省略function关键字,用=>连接参数与函数体,可根据参数数量、函数体行数灵活简写,修正原文笔误后的完整语法示例如下:

1. 传统函数与箭头函数基础对比
// 传统函数写法
function add(a,b){
    console.log("aaaaa");
    return a + b;
}

// 多参数箭头函数:参数需用()包裹,多行函数体需用{}包裹,手动return
const add1 = (a,b) => {
    console.log("aaaaa");
    return a + b;
};
2. 单参数简写形式
// 只有1个参数时,可省略参数的()
// 函数体只有一行return语句时,可省略{}和return关键字
const add2 = a => a + a;
console.log(add2(5)); // 输出10
3. 无参数写法
// 无参数时,必须保留()
const add3 = () => console.log("aaa");
add3(); // 执行输出aaa

2.2 箭头函数的核心特性(与传统函数的本质区别)

箭头函数并非只是传统函数的简写,其底层执行机制与传统函数有本质差异,核心特性如下:

  1. this 指向固定不变:箭头函数没有自己的this,其this继承自定义时所在的外层作用域的 this,而非调用时的执行上下文。这是箭头函数最核心的特性,彻底解决了传统函数this随调用者变化的问题,且无法通过call/apply/bind修改其 this 指向。
  2. 无 arguments 对象:箭头函数内部无法访问传统函数的arguments参数列表,如需获取动态参数,可使用 ES6 剩余参数...rest替代。
  3. 不可作为构造函数:箭头函数没有prototype原型,无法使用new关键字实例化,否则会直接报错。
  4. 不可使用 yield 关键字:无法作为 Generator 生成器函数使用。

this 指向典型示例:

const obj = {
    name: "张三",
    // 传统函数:this指向调用者obj
    traditionalFunc: function() {
        console.log(this.name); // 输出 张三
    },
    // 箭头函数:this继承定义时的外层作用域(全局window)
    arrowFunc: () => {
        console.log(this.name); // 输出 undefined
    }
}
obj.traditionalFunc();
obj.arrowFunc();

三、setTimeout 延时器的循环陷阱:作用域与事件循环的碰撞

setTimeout 循环陷阱是 JS 面试超高频考点,也是开发中极易踩坑的场景,其本质是变量作用域规则JS 事件循环机制共同作用的结果,我们将从现象到本质彻底拆解这一经典问题。

3.1 循环陷阱的现象

// 循环陷阱:var版本
for(var i=0;i<10;i++){
    setTimeout(()=>console.log(i),1000);
}
// 1秒后,连续输出10个10
// 标准解决方案:let版本
for(let j=0;j<10;j++){
    setTimeout(()=>console.log(j),1000);
}
// 1秒后,依次输出0 1 2 3 4 5 6 7 8 9

3.2 底层原理深度解析

要彻底搞懂循环陷阱,必须结合 3 个 JS 核心机制:

  1. JS 单线程与事件循环:JS 是单线程语言,setTimeout属于宏任务,会被放入异步任务队列,必须等待主线程的同步代码(for 循环)全部执行完毕后,才会执行任务队列中的回调函数。无论延时时间是 0 还是 1000ms,回调函数一定在 for 循环完全结束后才执行。
  2. var 的全局作用域特性var声明的i是全局作用域变量,整个 for 循环共用同一个i变量。循环同步执行时,只是不断给同一个i重新赋值,循环结束后,全局的i已经变成了 10。此时执行 10 个回调函数,所有回调访问的都是同一个全局i,因此连续输出 10 个 10。
  3. let 的块级作用域特性let声明的j拥有块级作用域,for 循环的每一次迭代,都会创建一个独立的、全新的j变量,每个循环体的块作用域完全隔离。每一次循环,setTimeout 的回调函数都会捕获当前迭代块中独立的j变量,这个值不会被后续循环修改。循环结束后,10 个回调函数分别访问各自捕获的j,因此正常输出 0-9。

四、核心知识点汇总表格

表 1:var、let、const 核心特性对比表

特性varletconst
作用域函数级作用域,无块级作用域块级作用域块级作用域
变量提升存在,声明提升,值为 undefined不存在,存在暂时性死区,必须先声明后使用不存在,存在暂时性死区,必须先声明后使用
重复声明同一作用域内允许同一作用域内不允许同一作用域内不允许
初始化要求声明时可不用初始化声明时可不用初始化声明时必须立即初始化
赋值修改可随意修改可随意修改基本类型不可修改;引用类型不可修改引用地址,可修改内部属性
全局声明挂载 window

表 2:箭头函数与传统函数核心对比表

特性传统函数(function)箭头函数(=>)
写法必须写 function 关键字,语法固定可根据参数和函数体简写,语法更简洁
this 指向指向调用时的执行上下文(调用者),可通过 call/apply/bind 修改继承定义时外层作用域的 this,固定不变,call/apply/bind 无法修改
arguments 对象有,可访问传入的参数列表无,可通过剩余参数...rest 替代
构造函数可作为构造函数,支持 new 实例化不可作为构造函数,无 prototype,使用 new 会报错
Generator 函数支持,可使用 yield 关键字不支持,无法使用 yield 关键字

表 3:setTimeout 循环陷阱解决方案对比表

解决方案实现原理优点缺点适用场景
let 块级作用域每次循环创建独立块级作用域,保存当前迭代值写法最简洁,ES6 标准方案,无额外性能开销需 ES6 + 环境支持现代前端开发,所有 ES6 + 环境
setTimeout 传参利用 setTimeout 第三个参数传参,传入当前迭代值写法简单,无需处理作用域极老旧浏览器(IE9 及以下)不支持第三个参数
温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信