零基础快速入门前端蓝桥杯Web考点深度解析:var、let、const与事件绑定实战(可用于备赛蓝桥杯Web应用开发)

在蓝桥杯 Web 应用开发赛道中,变量声明的特性与 DOM 事件绑定是核心高频考点。本文将结合实战代码,深度解析varletconst的区别,以及两种事件绑定方案的原理,并对应蓝桥杯考点进行拓展。

一、变量声明:var、let、const 的核心特性

1.1 预解析(变量提升)

核心区别

  • var 存在变量提升:声明会被提升到作用域顶部,但赋值仍在原地。

  • let/const 不存在变量提升:声明前使用会触发 "暂时性死区"(ReferenceError)。

代码实例

复制代码
// var 的变量提升
console.log(a, b, c); // 输出:undefined undefined undefined(变量已声明,未赋值)
var a = 'ggx handsome';
var b = 1;
var c = 10;

// let/const 的暂时性死区
// console.log(const1); // 报错:ReferenceError(const1 未初始化)
const const1 = 10; 
console.log(const1); // 输出:10

考点汇总表

|-----|----------|---------------|
| 特性 | var | let/const |
| 预解析 | ✅ 存在变量提升 | ❌ 不存在(暂时性死区) |

1.2 块级作用域

核心区别

  • var 无块级作用域:作用域为函数级全局{} 无法限制其范围。

  • let/const块级作用域:仅在 {} 内有效,可隔离变量

代码实例

复制代码
// let 的块级作用域
let a = 10;
console.log(a); // 输出:10(全局作用域)

if (1 > 0) {
    let a = 20; 
    console.log(a); // 输出:20(块级作用域)
}
console.log(a); // 输出:10(全局作用域不受块级影响)

// for 循环中的 let(蓝桥杯高频场景)
for (let i = 0; i < 5; i++) {
    console.log(i); // 输出:0 1 2 3 4(i 仅在循环内有效)
}
// console.log(i); // 报错:i 未定义(块级作用域隔离)

考点汇总表

|-------|--------------|---------------|
| 特性 | var | let/const |
| 块级作用域 | ❌ 无(函数 / 全局) | ✅ 有({} 内有效) |

1.3 const 的常量特性

const 用于定义常量,核心规则:

  1. 声明时必须赋值(否则报错);

  2. 基本数据类型(如数字、字符串)不可修改

  3. 引用数据类型(如数组、对象)地址不可改,但内部属性 / 元素可修改。

代码实例

复制代码
// 1. 声明时必须赋值
// const const2; // 报错:Missing initializer in const declaration
const const2 = 'ggx handsome'; 

// 2. 基本类型不可修改
// const2 = 'ggx really handsome'; // 报错:Assignment to constant variable

// 3. 引用类型:地址不可改,属性/元素可改
const array1 = [1, 2, 3, 4, 5];
const array2 = [1, 2, 3, 4, 5];
console.log(array1 == array2); // 输出:false(地址不同)

array1[0] = 'ggx'; // 修改元素(地址不变)
console.log(array1); // 输出:['ggx', 2, 3, 4, 5]

const obj1 = { name: 'ggx' };
obj1.name = 'ggxC'; // 修改属性(地址不变)
console.log(obj1); // 输出:{ name: 'ggxC' }

考点汇总表

|----------|-----------------------|
| const 特性 | 规则说明 |
| 声明赋值 | ✅ 必须赋值,否则报错 |
| 基本类型 | ❌ 不可修改值 |
| 引用类型 | ❌ 不可修改地址,✅ 可修改属性 / 元素 |

二、事件绑定的两种方案与蓝桥杯闭包考点

在蓝桥杯 DOM 操作题中,"循环绑定点击事件,获取正确索引" 是经典闭包考点。以下结合代码解析两种方案:

2.1 方案一:var + 自定义属性(ES5 兼容方案)

问题var 无块级作用域,循环内的 i共享变量 ,循环结束后 i 为最大值(如 5),点击时直接用 i 会出错。

解决 :通过 setAttribute 给每个元素存储索引,点击时用 this.getAttribute('index') 获取。

代码实例

复制代码
var names = document.querySelectorAll('.name');
var lastIndex = 0;

for (var i = 0; i < names.length; i++) {
    var div = names[i];
    div.setAttribute('index', i); // 存储索引到自定义属性

    div.onclick = function() {
        var index = this.getAttribute('index'); // 获取当前元素的索引
        names[lastIndex].className = 'name'; // 清除上一个高亮
        names[index].className = 'name highLight'; // 当前元素高亮
        lastIndex = index;
        
        console.log(i); // 点击任意元素,输出:5(var 的共享特性)
    };
}

2.2 方案二:let + 块级作用域(ES6 推荐方案)

优势let 有块级作用域,每次循环的 i 都是独立变量 ,事件绑定可直接使用 i,无需额外操作 DOM。

代码实例

复制代码
var names = document.querySelectorAll('.name');
var lastI = 0;

for (let i = 0; i < names.length; i++) {
    names[i].onclick = () => {
        console.log(i); // 点击对应元素,输出:0、1、2...(let 的块级绑定)
        names[lastI].classList.remove('highLight'); // 清除上一个高亮
        names[i].classList.add('highLight'); // 当前元素高亮
        lastI = i;
    };
}

2.3 蓝桥杯考点:闭包与作用域辨析

考点逻辑

  • var 方案:i 是全局变量,点击事件触发时才读取 i(此时 i 已为循环结束值),需通过自定义属性 "保存" 索引。

  • let 方案:每次循环生成独立的块级作用域,i 被绑定在当前作用域,点击时直接读取作用域内的 i,天然解决闭包问题。

考法示例

  • 给出 var 循环绑定事件的代码,问点击后输出什么(答案:循环结束值);

  • 要求修复索引错误(方案:改用 let,或用闭包 / 自定义属性)。

三、知识点终极汇总表

3.1 var、let、const 全面对比

|-------|--------------|-------------|---------------------|
| 特性 | var | let | const |
| 预解析 | ✅ 存在变量提升 | ❌ 暂时性死区 | ❌ 暂时性死区 |
| 块级作用域 | ❌ 无(函数 / 全局) | ✅ 有({} 内有效) | ✅ 有({} 内有效) |
| 重新赋值 | ✅ 可以 | ✅ 可以 | ❌ 基本类型不可改,引用类型地址不可改 |
| 声明时赋值 | ✅ 可以不赋值 | ✅ 可以不赋值 | ❌ 必须赋值 |
| 重复声明 | ✅ 同一作用域可重复 | ❌ 同一作用域不可 | ❌ 同一作用域不可 |

3.2 两种事件绑定方案对比

|-----|---------|-----------|-----------|-------|
| 方案 | 变量声明 | 解决方式 | 蓝桥杯适配性 | 代码简洁度 |
| 方案一 | var | 自定义属性存储索引 | ✅ 兼容 ES5 | ⭐⭐ |
| 方案二 | let | 块级作用域绑定索引 | ✅ 推荐(ES6) | ⭐⭐⭐⭐⭐ |

蓝桥杯备考建议

  • 优先用 let/const 替代 var,避免作用域陷阱;

  • 循环绑定事件时,let 是最简洁的解决方案;

  • 若需兼容 ES5,再考虑自定义属性或闭包。

相关推荐
宁雨桥2 小时前
前端项目实现光暗主题切换的完整方案
前端
IT从业者张某某2 小时前
Dockerfile详解
java·开发语言
南境十里·墨染春水2 小时前
C++笔记 类模板(面向对象)
开发语言·c++·笔记
happymaker06262 小时前
vue指令扩展以及监视器的使用
前端·javascript·vue.js
还是大剑师兰特2 小时前
EventBus核心方法用法
javascript·vue.js·大剑师
小白学大数据2 小时前
攻克滑动拼图反爬:Python 高效爬取网页图片实战案例
开发语言·爬虫·python
煜磊2 小时前
C/C++语言部署安装_C/C++Api学习
开发语言·c++
笨笨没好名字2 小时前
结构工程/机械工程/工业设计/硬件工程师面试题目(题源大疆:12+28)
人工智能·面试·职场和发展