4、JavaScript基础:变量与数据类型、运算符、流程控制、函数定义与调用、事件处理

JavaScript是Web程序设计的核心脚本语言,负责为网页赋予动态行为与交互逻辑。在计算机二级Web程序设计考试中,本章内容占据基础且关键的地位。理解变量与数据类型的存储机制、掌握运算符的优先级规则、熟练运用流程控制语句构建程序逻辑、学会定义与调用函数以实现代码复用,以及通过事件处理机制响应用户操作,是构建任何动态网页的必备技能。本章将系统拆解这五大核心模块,并结合实际代码案例,帮助考生建立扎实的JavaScript语言基础。

JavaScript 核心知识结构图 JavaScript 基础 变量与数据类型 运算符 流程控制 函数定义与调用 事件处理 var / let / const Number / String Boolean / null undefined / Object 算术 + - * / % 比较 == === != 逻辑 && || ! 赋值 = += -= if / else if / else switch / case for / while / do-while break / continue function 声明 匿名函数 / 箭头函数 参数与返回值 作用域与闭包 onclick / onchange onmouseover / onmouseout onkeydown / onkeyup addEventListener 五大模块相互关联,共同构成 JavaScript 编程基础

4.1 变量与数据类型

核心原理:变量是程序中用于存储数据的命名容器。JavaScript是一种动态类型语言,变量本身不绑定数据类型,其类型由当前存储的值决定。ES6 引入了 let 和 const 以弥补 var 在块级作用域上的不足。基本数据类型包括 Number(数值)、String(字符串)、Boolean(布尔)、null(空对象指针)、undefined(未定义值),以及 ES6 新增的 Symbol 和 BigInt。引用数据类型主要为 Object(对象),包含 Array、Function、Date 等。

判断方法/操作流程:使用 typeof 运算符检测变量类型。注意 typeof null 返回 "object",这是历史遗留 bug,但考试常考。区分 undefined(声明未赋值)与 null(主动赋空值)。
数据类型typeof 返回值典型示例注意事项
Number"number"let age = 25;包含整数和浮点数,NaN 也属于 number
String"string"let name = "张三";单引号、双引号、反引号均可
Boolean"boolean"let isOK = true;仅 true / false 两个值
null"object"let obj = null;表示空引用,需手动赋值
undefined"undefined"let x;声明但未初始化
Object"object"let arr = [1,2];数组、函数、日期均属对象

案例拆解:考虑一个用户注册表单的验证场景。需要获取用户名输入值并判断其长度。使用 let 声明变量,通过 typeof 检查输入是否为字符串,再通过 .length 属性判断长度。若输入为空,则 undefined 或空字符串都会导致验证失败,需分别处理。

let username = document.getElementById("username").value;
if (typeof username === "string" && username.trim().length > 0) {
    console.log("用户名有效:" + username);
} else {
    console.log("用户名不能为空");
}
常见误区:① 混淆 == 与 ===,前者会进行类型转换,后者要求类型和值都相等;② 忘记变量提升(var 声明提升至作用域顶部,但赋值不提升);③ 在循环中错误使用 var 导致闭包捕获同一变量。

4.2 运算符

核心原理:运算符用于执行程序中的运算操作。JavaScript 运算符分为算术运算符(+、-、*、/、%)、赋值运算符(=、+=、-=)、比较运算符(==、===、!=、!==、>、<)、逻辑运算符(&&、||、!)、三元运算符(?:)以及位运算符等。理解运算符优先级是正确书写表达式的关键,优先级从高到低依次为:括号 → 一元运算符 → 算术 → 比较 → 逻辑 → 赋值。

操作流程:在复杂表达式中,建议使用括号明确运算顺序,避免依赖记忆优先级。逻辑与(&&)和逻辑或(||)具有短路特性:a && b 若 a 为 false 则直接返回 a;a || b 若 a 为 true 则直接返回 a。这一特性常用于默认值设置。

// 短路求值示例:设置默认参数
function greet(name) {
    name = name || "访客";  // 若 name 为 undefined 或空字符串,则使用默认值
    console.log("你好," + name);
}
greet();       // 输出:你好,访客
greet("李四"); // 输出:你好,李四
运算符类别常用运算符示例结果
算术+ - * / %7 % 31
赋值= += -= *= /=let x=5; x+=2;x = 7
比较== === != > <"5" == 5true(类型转换)
比较== === != > <"5" === 5false(严格相等)
逻辑&& || !true && falsefalse
三元? :age >= 18 ? "成年" : "未成年"条件成立取前值
经验提醒:字符串与数字使用 + 运算时,数字会被转换为字符串进行拼接;而使用 -、*、/ 时,字符串会尝试转换为数字。例如 "5" - 2 结果为 3,而 "5" + 2 结果为 "52"。

4.3 流程控制

核心原理:流程控制语句决定程序执行的路径。条件分支包括 if/else if/else 和 switch/case;循环结构包括 for、while、do-while。选择哪种结构取决于具体场景:多条件区间判断用 if;离散值精确匹配用 switch;已知循环次数用 for;未知次数但需先判断条件用 while;至少执行一次用 do-while。

判断方法/操作流程:编写流程控制时,先画出逻辑流程图,再翻译为代码。注意 switch 使用严格相等(===)比较,且每个 case 后必须加 break,否则会发生穿透(fall-through)。循环中 break 用于立即退出循环,continue 用于跳过本次迭代进入下一次。

// 使用 switch 判断星期几
let day = 3;
let dayName;
switch (day) {
    case 1: dayName = "星期一"; break;
    case 2: dayName = "星期二"; break;
    case 3: dayName = "星期三"; break;
    default: dayName = "未知";
}
console.log(dayName); // 输出:星期三

// 使用 for 循环计算 1-100 的和
let sum = 0;
for (let i = 1; i <= 100; i++) {
    sum += i;
}
console.log(sum); // 输出:5050
案例拆解:实现一个简单的登录验证逻辑。用户输入用户名和密码,程序判断是否匹配预设值。使用 if 嵌套实现多条件验证,并使用 while 循环限制尝试次数。
let attempts = 0;
const maxAttempts = 3;
let isLoggedIn = false;

while (attempts < maxAttempts && !isLoggedIn) {
    let user = prompt("请输入用户名:");
    let pass = prompt("请输入密码:");
    if (user === "admin" && pass === "123456") {
        isLoggedIn = true;
        console.log("登录成功!");
    } else {
        attempts++;
        console.log("用户名或密码错误,剩余尝试次数:" + (maxAttempts - attempts));
    }
}
if (!isLoggedIn) {
    console.log("尝试次数过多,账号已锁定。");
}
常见误区:① 在 for 循环中使用 var 声明循环变量,导致循环结束后变量仍可访问;② switch 忘记写 break 造成逻辑错误;③ 使用 while(true) 时忘记设置退出条件,造成死循环。

4.4 函数定义与调用

核心原理:函数是一段可重复调用的代码块。定义方式有三种:函数声明(function declaration)、函数表达式(function expression)、箭头函数(arrow function)。函数声明会提升(hoisting),可以在声明前调用;函数表达式和箭头函数不会提升。函数参数按值传递,但对象类型传递的是引用地址。函数内部可以通过 arguments 对象访问所有传入参数。

操作流程:定义函数时明确输入参数和返回值;调用时确保参数个数和类型匹配。若参数不足,未传入的参数值为 undefined。可以使用默认参数(ES6)为形参赋初值。箭头函数不绑定自己的 this,它继承外层作用域的 this,这在事件处理和回调函数中尤为重要。

// 函数声明
function add(a, b) {
    return a + b;
}

// 函数表达式
const multiply = function(a, b) {
    return a * b;
};

// 箭头函数
const subtract = (a, b) => a - b;

// 默认参数
function divide(a, b = 1) {
    return a / b;
}

console.log(add(5, 3));      // 8
console.log(multiply(4, 2)); // 8
console.log(subtract(10, 4));// 6
console.log(divide(10));     // 10(b 使用默认值 1)
定义方式语法提升this 绑定适用场景
函数声明function fn() {}是动态绑定全局函数、工具函数
函数表达式const fn = function() {}否动态绑定回调函数、按需定义
箭头函数const fn = () => {}否词法绑定(继承外层)回调、简洁逻辑
经验提醒:在事件处理中,若需要使用 this 指向当前触发事件的 DOM 元素,应使用普通函数而非箭头函数。例如 btn.onclick = function() { this.style.color = "red"; } 中 this 指向按钮;若改为箭头函数,this 将指向外层作用域。

4.5 事件处理

核心原理:事件是用户与网页交互时触发的动作,如点击、键盘输入、鼠标移动等。事件处理机制包括三个要素:事件源(触发事件的元素)、事件类型(如 click、keydown)、事件处理程序(响应的函数)。注册事件处理程序有三种方式:HTML 内联属性(onclick="fn()")、DOM 属性赋值(element.onclick = fn)、addEventListener 方法(推荐,支持多个监听器)。

操作流程:使用 addEventListener 注册事件时,第一个参数为事件类型(不带 "on" 前缀),第二个参数为处理函数,第三个可选参数为布尔值(true 表示捕获阶段,false 表示冒泡阶段,默认 false)。事件对象(event)作为参数传递给处理函数,包含 target(触发元素)、type(事件类型)、preventDefault()(阻止默认行为)、stopPropagation()(阻止冒泡)等属性和方法。

// 使用 addEventListener 注册点击事件
const btn = document.getElementById("myBtn");
btn.addEventListener("click", function(event) {
    console.log("按钮被点击");
    console.log("事件类型:" + event.type);
    console.log("触发元素:" + event.target.id);
    event.preventDefault(); // 阻止默认行为(如表单提交)
});

// 键盘事件
document.addEventListener("keydown", function(e) {
    if (e.key === "Enter") {
        console.log("按下了回车键");
    }
});
案例拆解:实现一个表单实时验证功能。当用户在输入框中输入邮箱地址时,实时检查格式是否正确,并给出提示。使用 input 事件监听输入变化,使用正则表达式验证格式。
const emailInput = document.getElementById("email");
const tip = document.getElementById("tip");

emailInput.addEventListener("input", function() {
    const value = this.value;
    const pattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (pattern.test(value)) {
        tip.textContent = "邮箱格式正确";
        tip.style.color = "green";
    } else {
        tip.textContent = "邮箱格式不正确";
        tip.style.color = "red";
    }
});
常见误区:① 使用 HTML 内联事件处理时,作用域指向全局,且无法移除监听器;② 忘记调用 preventDefault() 导致表单自动提交或页面刷新;③ 在循环中注册事件时,使用 var 导致所有事件处理函数捕获同一个循环变量值,应使用 let 或闭包解决。

总结复盘

本章系统梳理了 JavaScript 基础的五大核心模块。变量与数据类型是程序的基石,需掌握 let/const 与块级作用域;运算符需理解优先级和短路特性;流程控制需根据场景选择合适的结构;函数定义需区分三种方式的差异,特别注意箭头函数的 this 绑定;事件处理推荐使用 addEventListener,并理解事件对象的使用。在计算机二级考试中,这些知识点常以程序阅读题、改错题和简单编程题的形式出现。建议考生多动手编写小案例,将语法规则内化为编程直觉,同时注意细节陷阱,如严格相等、类型转换、变量提升等高频考点。