JavaScript基础语法实例:变量、循环与函数代码演示

作者:小括号

时间:2026-10-30

浏览:648

系统讲解JavaScript基础语法中的变量声明、循环控制结构与函数封装。结合清晰直观的原理图解与可运行代码实例,剖析作用域、迭代机制及模块化设计要点。

文章目录

在 JavaScript 程序开发中,变量、循环与函数是构建所有业务逻辑的三大基石。变量负责在内存中开辟空间并暂存动态数据,循环负责以受控的方式自动重复执行既定逻辑,而函数则将一系列操作封装为可复用、具有明确输入输出的独立模块。本文围绕这三个核心要素,结合实际可运行的代码演示与详细原理剖析,帮助读者建立系统而扎实的 JavaScript 编程认知。

一、核心语法执行流与运行环境准备

JavaScript 是一种解释型、弱类型且基于原型的脚本语言。现代浏览器(如 Chrome、Edge、Firefox)均内置了高性能的 JavaScript 执行引擎(例如 V8、SpiderMonkey),读者无需安装复杂配置即可直接进行语法验证。在浏览器任意页面按下 F12 或右键选择“检查”,切换至 Console(控制台) 选项卡,即可直接键入并回车执行 JavaScript 代码;若在本地拥有 Node.js 运行环境,则可以直接在命令行终端输入 node 进入交互式解释器(REPL)进行测试。

JavaScript基础语法实例:变量、循环与函数代码演示
图 1:JavaScript 核心语法执行流与运行链路图

二、变量声明与作用域:var、let 与 const 的本质区别

变量是程序存储与追踪状态的核心手段。在 ECMAScript 6 (ES2015) 规范发布之前,JavaScript 仅支持 var 关键字声明变量。为了解决变量提升、作用域泄漏以及无意覆盖全局变量等设计历史问题,现代规范引入了具备块级作用域的 let 与 const。

1. 三种声明方式的对比

关键字 作用域级别 变量提升现象 重复声明 重新赋值
var 函数作用域 / 全局 存在提升,且初值被初始化为 undefined 允许在同级作用域重复声明 允许重新赋值
let 块级作用域 {} 存在提升,但处于暂存死区(TDZ),声明前不可访问 不允许同级重复声明 允许重新赋值
const 块级作用域 {} 存在提升,但处于暂存死区(TDZ),声明前不可访问 不允许同级重复声明 只读绑定,不可重新指向新引用
JavaScript基础语法实例:变量、循环与函数代码演示
图 2:JavaScript 变量声明方式与作用域特性对比图

2. 变量代码实操演示

// 1. 常量与基础类型
const APP_NAME = "SystemMonitor";
const MAX_CONCURRENT = 5;

// 2. 块级作用域隔离
let currentTaskCount = 0;

if (MAX_CONCURRENT > 0) {
  // 这里的 blockScopedToken 仅在当前 if 分支内可见
  const blockScopedToken = "TOKEN_" + Math.random().toString(16).slice(2);
  currentTaskCount += 1;
  console.log("内部生成 Token:", blockScopedToken, "当前任务数:", currentTaskCount);
}

// 尝试在外部访问将抛出 ReferenceError
// console.log(blockScopedToken); // 报错:blockScopedToken is not defined

// 3. 引用类型常量的修改特性
const serverConfig = {
  host: "127.0.0.1",
  port: 3000,
  routes: ["/home", "/api"]
};

// 允许修改对象属性和向数组追加元素
serverConfig.port = 8080;
serverConfig.routes.push("/status");

console.log("更新后的服务器配置:", serverConfig);

// 若尝试使 serverConfig 指向新的对象地址,则会触发只读赋值报错:
// serverConfig = { host: "0.0.0.0" }; // TypeError: Assignment to constant variable.
注意事项:在编写代码时,应当树立“优先使用 const、其次使用 let、绝不使用 var”的规范。这样能够在编译阶段及早发现变量被意外篡改的缺陷,极大降低大型项目的状态混乱风险。

三、循环控制结构:for、while 与循环跳转控制

循环允许我们以极简洁的代码批量处理大量重复计算。JavaScript 提供了多种形态的循环结构,主要包括基于计数器的标准 for 循环、基于条件成立的 while / do-while 循环,以及针对可迭代对象(如数组、字符串、集合)的 for...of 循环。

1. 核心循环语句概述

  • 标准 for 循环:最经典的循环形态,由“初始化语句;条件判定表达式;迭代递增表达式”构成,适合循环次数已知的场景。
  • while 循环:进入前先求值条件表达式,若为真则执行循环体;适合等待外部条件改变或循环次数未知的场景。
  • do...while 循环:先无条件执行一次循环体,再判定条件表达式;保证至少执行一次。
  • for...of 循环:ES6 推荐的集合遍历语法,能够直接取得数组或集合的元素值,相比传统的下标遍历更直观且安全。
  • break 与 continue:break 用于立即终止整个循环并跳转到循环体外;continue 用于终止本轮迭代并跳过剩余语句,直接进入下一轮循环的步进判定。
JavaScript基础语法实例:变量、循环与函数代码演示
图 3:循环结构状态流转与 break / continue 控制路径原理图

2. 循环实操代码演示

// 1. 标准 for 循环遍历与过滤计算
const scores = [88, 59, 94, -1, 76, 60, null, 85];
let validTotal = 0;
let passedCount = 0;

console.log("--- 开始成绩分析 ---");
for (let i = 0; i < scores.length; i++) {
  const current = scores[i];

  // 遇到空数据 null 时触发 break,提前退出后续扫描
  if (current === null) {
    console.log(`下标 ${i} 处遇到无效结束标记 null,中止循环`);
    break;
  }

  // 负数值属于录入异常,跳过本轮累加,直接进入下一轮
  if (current < 0) {
    console.warn(`下标 ${i} 处分数异常(${current}),已跳过`);
    continue;
  }

  validTotal += current;
  if (current >= 60) {
    passedCount++;
  }
}

console.log(`有效总分: ${validTotal}, 及格人数: ${passedCount}`);

// 2. while 循环:模拟资金复利增长直至达到目标
let balance = 1000;
const target = 1500;
const annualRate = 0.08;
let years = 0;

while (balance < target) {
  balance *= (1 + annualRate);
  years++;
}
console.log(`经过 ${years} 年复利增长,本息达到目标: ¥${balance.toFixed(2)}`);

// 3. 现代化 for...of 循环:直观遍历集合元素
const devTools = ["V8", "Webpack", "Vite", "Babel"];
console.log("工具链清单:");
for (const tool of devTools) {
  console.log(" - " + tool);
}

四、函数的声明、参数传递与返回值

函数是组织程序、实现复用和建立抽象边界的核心机制。在 JavaScript 中,函数是“头等公民(First-Class Citizens)”,这意味着函数可以像普通变量一样被传递、作为参数赋予其他函数、或者由函数作为结果返回。

1. 函数常见的三种定义形态

  1. 函数声明式(Function Declaration):使用 function fnName(params) { ... } 形式。具备函数声明整体提升特性,可以在声明语句之前调用。
  2. 函数表达式(Function Expression):将匿名或具名函数赋值给变量 const fn = function() { ... }。遵循变量的提升规则(受 const/let 限制),必须先声明后调用。
  3. 箭头函数(Arrow Function):ES6 引入的简洁语法 const fn = (a, b) => a + b。它不绑定自身的 this、arguments,特别适合轻量级数据运算与回调函数。

2. 参数默认值与不定参数(Rest Parameters)

// 1. 默认参数:当调用者未传参或传入 undefined 时生效
function createHttpRequest(url, method = "GET", timeout = 5000) {
  return {
    url,
    method,
    timeout,
    timestamp: Date.now()
  };
}

console.log(createHttpRequest("/api/users"));
// 输出: { url: '/api/users', method: 'GET', timeout: 5000, timestamp: ... }

// 2. Rest 参数:将不定数量的入参汇聚为真实数组
function calculateWeightedSum(multiplier, ...numbers) {
  let sum = 0;
  for (const num of numbers) {
    sum += num * multiplier;
  }
  return sum;
}

const weightedResult = calculateWeightedSum(1.5, 10, 20, 30);
console.log("加权计算结果:", weightedResult); // (10 + 20 + 30) * 1.5 = 90

五、综合实战案例:变量、循环与函数协同处理数据

在真实的业务开发中,变量、循环与函数并不是孤立存在的,而是相互配合以完成复杂的数据加工任务。下面我们通过一个学生成绩综合评估系统,展示三者的协同协作方式:使用函数封装业务,内部通过变量追踪指标状态,结合循环完成过滤、汇总与分类统计。

JavaScript基础语法实例:变量、循环与函数代码演示
图 4:变量、循环与函数协同运作全景与工程实践总结图

完整可运行实战代码

/**
 * 学生成绩综合分析函数
 * @param {Array<{name: string, score: number}>} studentList 学生记录集合
 * @param {number} passScore 及格基准线,默认为 60
 * @returns {object} 包含总览数据与分类名单的分析报告
 */
function analyzeClassScores(studentList, passScore = 60) {
  // 1. 边界检查:防御性编程,确保传入数据为有效非空数组
  if (!Array.isArray(studentList) || studentList.length === 0) {
    return {
      success: false,
      message: "输入学生列表无效或为空",
      summary: null
    };
  }

  // 2. 状态变量初始化
  let accumulatedScore = 0;
  let topStudent = studentList[0];
  const passedStudents = [];
  const failedStudents = [];

  // 3. 循环遍历每名学生的成绩数据
  for (const student of studentList) {
    // 过滤异常缺失值
    if (typeof student.score !== "number" || isNaN(student.score)) {
      console.warn(`检测到学生 ${student.name} 的成绩数据无效,跳过统计`);
      continue;
    }

    accumulatedScore += student.score;

    // 比对并更新最高分获得者
    if (student.score > topStudent.score) {
      topStudent = student;
    }

    // 根据条件分流至不同分类数组
    if (student.score >= passScore) {
      passedStudents.push(student);
    } else {
      failedStudents.push(student);
    }
  }

  // 4. 计算综合指标并封装结构化对象返回
  const totalCount = studentList.length;
  const averageScore = Number((accumulatedScore / totalCount).toFixed(2));
  const passRate = ((passedStudents.length / totalCount) * 100).toFixed(1) + "%";

  return {
    success: true,
    summary: {
      totalCount,
      averageScore,
      passRate,
      topStudentName: topStudent.name,
      topScore: topStudent.score,
      passedCount: passedStudents.length,
      failedCount: failedStudents.length
    },
    passedStudents,
    failedStudents
  };
}

// --- 测试验证案例 ---
const mockData = [
  { name: "赵云", score: 95 },
  { name: "关羽", score: 88 },
  { name: "张飞", score: 56 },
  { name: "黄忠", score: 78 },
  { name: "魏延", score: 45 }
];

const report = analyzeClassScores(mockData, 60);
console.log("【班级成绩评估分析报告】");
console.log("总人数:", report.summary.totalCount);
console.log("平均分:", report.summary.averageScore);
console.log("及格率:", report.summary.passRate);
console.log("最高分学生:", report.summary.topStudentName, "分数:", report.summary.topScore);
console.log("未能及格人员名单:", report.failedStudents.map(s => s.name).join("、"));

六、常见初学者错误与排查指南

在掌握变量、循环与函数的使用过程中,以下几类高频问题值得特别注意:

  1. ReferenceError: ... is not defined(未定义引用异常):

    原因通常是在大括号 {} 之外尝试读取使用 let 或 const 声明的局部变量;或者在声明语句之前提前访问处于暂存死区(TDZ)的变量。排查时应检查变量作用域层级及声明位置。

  2. TypeError: Assignment to constant variable(常量赋值异常):

    对使用 const 声明的变量执行了二次赋值操作。如果变量的值需要动态改变(如递增计数器、循环累加器),应明确将其改为 let 声明。

  3. 无限死循环导致宿主进程卡死(Infinite Loop):

    在 while 或 for 循环中,若遗漏了递增语句(例如忘记写 i++),或者退出判定条件永远无法变为 false,循环将一直占用主线程。排查时需首先核对循环步进语句是否能有效推进状态。

  4. 函数缺少 return 导致默认返回 undefined:

    在 JavaScript 中,如果一个函数内部执行完毕且未显式书写 return,该函数调用的求值结果将自动为 undefined。在需要产出计算结果的场景下,务必检查返回路径是否完整。

排查自检建议:当遇到代码逻辑不符合预期时,可以在循环体内或关键函数入口处添加 console.log("调试追踪:", 变量名),打印变量的实时类型与数值,观察状态在每一步是否符合设计要求。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章