系统讲解JavaScript基础语法中的变量声明(var/let/const)、常用循环控制(for/while/for...of)与函数定义机制,结合完整可运行的代码演示与SVG图解,帮助开发者建立扎实的编程基础。
JavaScript基础语法实例:变量、循环与函数代码演示
时间:2026-10-30
浏览:519
文章目录
一、变量声明:var、let 与 const 的本质区别
在 JavaScript 中,变量是存储数据的具名容器。随着 ECMAScript 规范的演进,语言提供了 var、let 与 const 三种声明关键字。明确它们在作用域控制、重复声明与可变性上的差异,是写出健壮代码的第一步。
1. 作用域与暂时性死区(TDZ)
var 遵循函数作用域(Function Scope),且存在变量声明提升(Hoisting)机制,在声明语句前访问会得到 undefined。而 ES6 引入的 let 和 const 具备严格的块级作用域(Block Scope,以 {} 为边界),并且在声明执行之前存在“暂时性死区(Temporal Dead Zone)”,在声明前访问会直接抛出 ReferenceError,从而杜绝潜在的逻辑漏洞。
// 1. var 的声明提升与函数作用域
console.log(legacyVar); // 输出: undefined(发生变量提升)
var legacyVar = "历史变量";
// 2. let 的暂时性死区与块级作用域
try {
console.log(modernLet); // 抛出 ReferenceError: Cannot access 'modernLet' before initialization
} catch (error) {
console.error("捕获到错误:", error.message);
}
let modernLet = "块级变量";
if (true) {
let blockScoped = 100;
var functionScoped = 200;
}
// console.log(blockScoped); // ReferenceError: blockScoped is not defined
console.log(functionScoped); // 输出: 200,var 穿透了 if 代码块
2. const 的不可变性边界
const 用于声明常量,一旦绑定标识符便不可重新赋值。但需要注意:如果 const 绑定的是对象或数组等引用类型,变量所保存的是内存地址引用,对象内部的属性修改与数组元素的追加是完全允许的。如果需要深度冻结对象,则需配合 Object.freeze()。
const maxRetries = 3;
// maxRetries = 5; // TypeError: Assignment to constant variable.
const userConfig = { timeout: 5000, debug: false };
userConfig.debug = true; // 允许修改对象属性
userConfig.retryCount = 3; // 允许扩展新属性
console.log("更新后的配置:", userConfig);
二、循环控制流:遍历与迭代场景的精准选择
循环结构用于重复执行特定逻辑,直到满足终止条件。JavaScript 提供了多种循环语法,针对集合遍历、数值计数和条件轮询具有不同的语义契约。
1. 经典计数循环:for 与 while / do...while
当已知迭代次数或步长规则明确时,优先使用标准三元 for 循环;当迭代次数依赖于外部状态变化或动态计算时,使用 while。需要确保至少执行一次循环体时,采用 do...while。
// 标准 for 循环:明确区间范围
let sum = 0;
for (let i = 1; i <= 5; i++) {
sum += i;
}
console.log("1 到 5 累加结果:", sum); // 15
// while 循环:依赖状态变更
let balance = 100;
let withdrawals = 0;
while (balance > 30) {
balance -= 25;
withdrawals++;
}
console.log("取款次数:", withdrawals, "剩余余额:", balance); // 次数: 3, 余额: 25
2. 集合遍历:for...of 与 for...in 的关键界限
这是初学者极易混淆的一对语法:
- for...of:用于遍历可迭代对象(Iterable,如 Array、Set、Map、字符串),直接获取集合中的元素值(Value)。
- for...in:用于遍历对象的可枚举属性名(Key),包含原型链上的属性,且遍历顺序在特定实现下不完全保证。严禁使用
for...in遍历数组。
const fruits = ["苹果", "香蕉", "柑橘"];
// 推荐:使用 for...of 遍历数组元素
for (const item of fruits) {
console.log("当前水果:", item);
}
// 对象键名遍历:使用 for...in
const student = { name: "李华", age: 19, grade: "大一" };
for (const key in student) {
if (Object.prototype.hasOwnProperty.call(student, key)) {
console.log(`${key}: ${student[key]}`);
}
}
三、函数体系:声明方式、参数控制与调用生命周期
函数是 JavaScript 中的一等公民(First-Class Citizens),既可以作为逻辑封装单元,也可以作为参数传递、作为返回值输出。掌握函数声明、函数表达式与箭头函数的差异,是构建模块化程序的基石。
1. 函数声明 vs 箭头函数
常规 function 声明具有完整的执行上下文,拥有自己的 this 绑定、arguments 对象,并支持通过 new 关键字实例化为构造函数。
ES6 提供的箭头函数(Arrow Function)采用词法 this 继承,其内部的 this 在定义时就已经确定(由外层词法作用域决定),不能使用 new 实例化,也没有独立的 arguments 对象。这使得箭头函数在回调函数和数组链式调用中极具优势。
// 1. 标准函数声明(支持提升)
function calculateTotal(price, quantity = 1, discount = 0) {
return (price * quantity) * (1 - discount);
}
// 2. 箭头函数(表达式语法与隐式返回)
const formatCurrency = (amount) => `¥${amount.toFixed(2)}`;
// 3. 剩余参数语法(Rest Parameters)
const aggregateScores = (factor, ...scores) => {
let total = 0;
for (const s of scores) {
total += s;
}
return total * factor;
};
const finalPay = calculateTotal(120, 2, 0.1);
console.log("应付款:", formatCurrency(finalPay)); // ¥216.00
console.log("加权积分:", aggregateScores(1.2, 80, 90, 95)); // 318
四、综合演练:串联变量、循环与函数的综合实例
在实际业务开发中,变量、循环与函数总是交织配合工作的。下面通过一个完整的“员工绩效报表分析器”实例,演示如何利用这三项基础语法完成数据归纳、区间过滤与格式化输出。
/**
* 员工绩效分析演示脚本
* 运行环境:Node.js 或 现代浏览器控制台
*/
// 1. 数据常量:使用 const 保持集合引用稳定
const employeeRecords = [
{ id: 101, name: "张明", dept: "研发部", score: 88 },
{ id: 102, name: "王芳", dept: "市场部", score: 94 },
{ id: 103, name: "陈杰", dept: "研发部", score: 76 },
{ id: 104, name: "赵强", dept: "运营部", score: 91 },
{ id: 105, name: "孙丽", dept: "市场部", score: 83 }
];
// 2. 工具函数:根据分数判定评级
const getGradeLevel = (score) => {
if (score >= 90) return "卓越";
if (score >= 80) return "良好";
return "合格";
};
// 3. 主统计函数:融合循环与局部变量计算
function analyzePerformance(records, targetDept = null) {
let matchedCount = 0;
let totalScore = 0;
const detailedList = [];
// 使用 for...of 高效遍历数据集合
for (const item of records) {
// 部门过滤条件
if (targetDept && item.dept !== targetDept) {
continue; // 跳过不符合条件的记录
}
matchedCount++;
totalScore += item.score;
// 组装单项格式化结果
detailedList.push({
name: item.name,
dept: item.dept,
score: item.score,
level: getGradeLevel(item.score)
});
}
// 防御除以零风险
const averageScore = matchedCount > 0
? Number((totalScore / matchedCount).toFixed(1))
: 0;
return {
department: targetDept || "全部部门",
totalHeadcount: matchedCount,
averageScore: averageScore,
details: detailedList
};
}
// 4. 执行业务逻辑并输出测试结果
const overallReport = analyzePerformance(employeeRecords);
console.log("全公司绩效统计:", JSON.stringify(overallReport, null, 2));
const rdReport = analyzePerformance(employeeRecords, "研发部");
console.log("研发部绩效统计:", JSON.stringify(rdReport, null, 2));
代码设计要点提示:
在上述实例中,数据源声明为 const employeeRecords,确保引用不被意外重写;循环内部使用 continue 快速过滤非目标部门数据;累计量 totalScore 和计数器 matchedCount 使用 let 声明,仅在 analyzePerformance 函数的作用域内部可见,避免了外部全局作用域污染。
五、基础语法核心规范与避坑总结
编写规范的 JavaScript 代码不仅有助于减少运行时 Bug,还能极大提升代码的自解释性与维护效率。下表总结了变量、循环与函数编写时的关键准则:
| 语法模块 | 推荐做法(Best Practice) | 需要规避的陷阱(Common Pitfall) |
|---|---|---|
| 变量声明 | 优先使用 const,仅在需要重新赋值时使用 let。 |
坚决弃用 var,避免隐式全局变量(遗漏声明直接赋值)。 |
| 循环结构 | 遍历数组用 for...of 或数组内置迭代方法;已知区间用 for。 |
严禁使用 for...in 遍历数组(会取得索引字符串并枚举额外属性)。 |
| 函数定义 | 短小回调与纯计算使用箭头函数;公用模块与需要提升的顶层逻辑使用函数声明。 | 不要在对象方法或需要动态绑定调用者的地方滥用箭头函数导致 this 丢失。 |
| 参数传递 | 显式提供形参默认值;多变参数采用剩余参数 ...rest。 |
避免在函数内部直接修改外部传入的引用类型对象,造成隐式副作用。 |
结语
变量建立了程序的状态存储,循环赋予了程序批量处理的能力,而函数将离散的逻辑组织为高内聚、可复用的模块。深入理解 let/const 的块级约束、迭代器驱动的 for...of 以及不同函数定义形式的执行上下文规则,是迈向高质量 JavaScript 编程的坚实基石。
实用工具推荐
绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
选择画质和输出格式,预览压缩前后的大小。