程序猿前端之JavaScript - Day02 - 流程控制与ATM取款机案例实战

JavaScript 基础 - 第2天

理解什么是流程控制,知道条件控制的种类并掌握其对应的语法规则,具备利用循环编写简易ATM取款机程序能力

  • 运算符

  • 语句

  • 综合案例

运算符

算术运算符

数字是用来计算的,比如:乘法 * 、除法 / 、加法 + 、减法 - 等等,所以经常和算术运算符一起。

算术运算符:也叫数学运算符,主要包括加、减、乘、除、取余(求模)等

运算符作用
+求和
-求差
*求积
/求商
%取模(取余数),开发中经常用于作为某个数字是否被整除

注意:在计算失败时,显示的结果是 NaN (not a number)

// 算术运算符
console.log(1 + 2 * 3 / 2) //  4 
let num = 10
console.log(num + 10)  // 20
console.log(num + num)  // 20
​
// 1. 取模(取余数)  使用场景:  用来判断某个数是否能够被整除
console.log(4 % 2) //  0  
console.log(6 % 3) //  0
console.log(5 % 3) //  2
console.log(3 % 5) //  3
​
// 2. 注意事项 : 如果我们计算失败,则返回的结果是 NaN (not a number)
console.log('pink老师' - 2)
console.log('pink老师' * 2)
console.log('pink老师' + 2)   // pink老师2

赋值运算符

赋值运算符:对变量进行赋值的运算符

= 将等号右边的值赋予给左边, 要求左边必须是一个容器

运算符作用
+=加法赋值
-+减法赋值
*=乘法赋值
/=除法赋值
%=取余赋值
<script>
let num = 1
// num = num + 1
// 采取赋值运算符
// num += 1
num += 3
console.log(num)
</script>

自增/自减运算符

符号作用说明
++自增变量自身的值加1,例如: x++
--自减变量自身的值减1,例如: x--
  1. ++在前和++在后在单独使用时二者并没有差别,而且一般开发中我们都是独立使用

  2. ++在后(后缀式)我们会使用更多

注意:

  1. 只有变量能够使用自增和自减运算符

  2. ++、-- 可以在变量前面也可以在变量后面,比如: x++ 或者 ++x

<script>
    // let num = 10
    // num = num + 1
    // num += 1
    // // 1. 前置自增
    // let i = 1
    // ++i
    // console.log(i)
​
    // let i = 1
    // console.log(++i + 1)
    // 2. 后置自增
    // let i = 1
    // i++
    // console.log(i)
    // let i = 1
    // console.log(i++ + 1)
​
    // 了解 
    let i = 1
    console.log(i++ + ++i + i)
  </script>

比较运算符

使用场景:比较两个数据大小、是否相等,根据比较结果返回一个布尔值(true / false)

运算符作用
>左边是否大于右边
<左边是否小于右边
>=左边是否大于或等于右边
<=左边是否小于或等于右边
===左右两边是否类型都相等(重点)
==左右两边是否相等
!=左右值不相等
!==左右两边是否不全等
<script>
  console.log(3 > 5)
  console.log(3 >= 3)
  console.log(2 == 2)
  // 比较运算符有隐式转换 把'2' 转换为 2  双等号 只判断值
  console.log(2 == '2')  // true
  // console.log(undefined === null)
  // === 全等 判断 值 和 数据类型都一样才行
  // 以后判断是否相等 请用 ===  
  console.log(2 === '2')
  console.log(NaN === NaN) // NaN 不等于任何人,包括他自己
  console.log(2 !== '2')  // true  
  console.log(2 != '2') // false 
  console.log('-------------------------')
  console.log('a' < 'b') // true
  console.log('aa' < 'ab') // true
  console.log('aa' < 'aac') // true
  console.log('-------------------------')
</script>

逻辑运算符

使用场景:可以把多个布尔值放到一起运算,最终返回一个布尔值

符号名称日常读法特点口诀
&&逻辑与并且符号两边有一个假的结果为假一假则假
||逻辑或或者符号两边有一个真的结果为真一真则真
!逻辑非取反true变false false变true真变假,假变真
ABA && BA || B!A
falsefalsefalsefalsetrue
falsetruefalsetruetrue
truefalsefalsetruefalse
truetruetruetruefalse
<script>
    // 逻辑与 一假则假
    console.log(true && true)
    console.log(false && true)
    console.log(3 < 5 && 3 > 2)
    console.log(3 < 5 && 3 < 2)
    console.log('-----------------')
    // 逻辑或 一真则真
    console.log(true || true)
    console.log(false || true)
    console.log(false || false)
    console.log('-----------------')
    // 逻辑非  取反
    console.log(!true)
    console.log(!false)
​
    console.log('-----------------')
​
    let num = 6
    console.log(num > 5 && num < 10)
    console.log('-----------------')
  </script>

运算符优先级

逻辑运算符优先级: !> && > ||

语句

表达式和语句

分支语句

分支语句可以根据条件判定真假,来选择性的执行想要的代码

分支语句包含:

  1. if分支语句(重点)

  2. 三元运算符

  3. switch语句

if 分支语句

语法:

if(条件表达式) {
  // 满足条件要执行的语句
}

小括号内的条件结果是布尔值,为 true 时,进入大括号里执行代码;为false,则不执行大括号里面代码

小括号内的结果若不是布尔类型时,会发生类型转换为布尔值,类似Boolean()

如果大括号只有一个语句,大括号可以省略,但是,俺们不提倡这么做~

<script>
    // 单分支语句
    // if (false) {
    //   console.log('执行语句')
    // }
    // if (3 > 5) {
    //   console.log('执行语句')
    // }
    // if (2 === '2') {
    //   console.log('执行语句')
    // }
    //  1. 除了0 所有的数字都为真
    //   if (0) {
    //     console.log('执行语句')
    //   }
    // 2.除了 '' 所有的字符串都为真 true
    // if ('pink老师') {
    //   console.log('执行语句')
    // }
    // if ('') {
    //   console.log('执行语句')
    // }
    // // if ('') console.log('执行语句')
​
    // 1. 用户输入
    let score = +prompt('请输入成绩')
    // 2. 进行判断输出
    if (score >= 700) {
      alert('恭喜考入黑马程序员')
    }
    console.log('-----------------')
​
  </script>
if双分支语句

如果有两个条件的时候,可以使用 if else 双分支语句

if (条件表达式){
  // 满足条件要执行的语句
} else {
  // 不满足条件要执行的语句
}

例如:

 <script>
    // 1. 用户输入
    let uname = prompt('请输入用户名:')
    let pwd = prompt('请输入密码:')
    // 2. 判断输出
    if (uname === 'pink' && pwd === '123456') {
      alert('恭喜登录成功')
    } else {
      alert('用户名或者密码错误')
    }
  </script>
if 多分支语句

使用场景: 适合于有多个条件的时候

 <script>
    // 1. 用户输入
    let score = +prompt('请输入成绩:')
    // 2. 判断输出
    if (score >= 90) {
      alert('成绩优秀,宝贝,你是我的骄傲')
    } else if (score >= 70) {
      alert('成绩良好,宝贝,你要加油哦~~')
    } else if (score >= 60) {
      alert('成绩及格,宝贝,你很危险~')
    } else {
      alert('成绩不及格,宝贝,我不想和你说话,我只想用鞭子和你说话~')
    }
  </script>
三元运算符(三元表达式)

使用场景: 一些简单的双分支,可以使用 三元运算符(三元表达式),写起来比 if else双分支 更简单

符号:? 与 : 配合使用

语法:

条件 ? 表达式1 : 表达式2

例如:

// 三元运算符(三元表达式)
// 1. 语法格式
// 条件 ? 表达式1 : 表达式2 
​
// 2. 执行过程 
// 2.1 如果条件为真,则执行表达式1
// 2.2 如果条件为假,则执行表达式2
​
// 3. 验证
// 5 > 3 ? '真的' : '假的'
console.log(5 < 3 ? '真的' : '假的')
​
// let age = 18 
// age = age + 1
//  age++
​
// 1. 用户输入 
let num = prompt('请您输入一个数字:')
// 2. 判断输出- 小于10才补0
// num = num < 10 ? 0 + num : num
num = num >= 10 ? num : 0 + num
alert(num)
switch语句(了解)

使用场景: 适合于有多个条件的时候,也属于分支语句,大部分情况下和 if多分支语句 功能相同

注意:

  1. switch case语句一般用于等值判断, if适合于区间判断

  2. switchcase一般需要配合break关键字使用 没有break会造成case穿透

  3. if 多分支语句开发要比switch更重要,使用也更多

例如:

// switch分支语句
// 1. 语法
// switch (表达式) {
//   case 值1:
//     代码1
//     break
​
//   case 值2:
//     代码2
//     break
//   ...
//   default:
//     代码n
// }
​
<script>
  switch (2) {
    case 1:
    console.log('您选择的是1')
    break  // 退出switch
    case 2:
    console.log('您选择的是2')
    break  // 退出switch
    case 3:
    console.log('您选择的是3')
    break  // 退出switch
    default:
    console.log('没有符合条件的')
  }
</script>
断点调试

作用:学习时可以帮助更好的理解代码运行,工作时可以更快找到bug

浏览器打开调试界面

  1. 按F12打开开发者工具

  2. 点到源代码一栏 ( sources )

  3. 选择代码文件

断点:在某句代码上加的标记就叫断点,当程序执行到这句有标记的代码时会暂停下来

循环语句

使用场景:重复执行 指定的一段代码,比如我们想要输出10次 '我学的很棒'

学习路径:

1.while循环

2.for 循环(重点)

while循环

while : 在…. 期间, 所以 while循环 就是在满足条件期间,重复执行某些代码。

语法:

while (条件表达式) {
   // 循环体    
}

例如:

// while循环: 重复执行代码

// 1. 需求: 利用循环重复打印3次 '月薪过万不是梦,毕业时候见英雄'
let i = 1
while (i <= 3) {
  document.write('月薪过万不是梦,毕业时候见英雄~<br>')
  i++   // 这里千万不要忘了变量自增否则造成死循环
}

循环三要素:

1.初始值 (经常用变量)

2.终止条件

3.变量的变化量

例如:

<script>
  // // 1. 变量的起始值
  // let i = 1
  // // 2. 终止条件
  // while (i <= 3) {
  //   document.write('我要循环三次 <br>')
  //   // 3. 变量的变化量
  //   i++
  // }
  // 1. 变量的起始值
  let end = +prompt('请输入次数:')
let i = 1
// 2. 终止条件
while (i <= end) {
  document.write('我要循环三次 <br>')
  // 3. 变量的变化量
  i++
}

</script>
中止循环

break 中止整个循环,一般用于结果已经得到, 后续的循环不需要的时候可以使用(提高效率)

continue 中止本次循环,一般用于排除或者跳过某一个选项的时候

<script>
    // let i = 1
    // while (i <= 5) {
    //   console.log(i)
    //   if (i === 3) {
    //     break  // 退出循环
    //   }
    //   i++

    // }


    let i = 1
    while (i <= 5) {
      if (i === 3) {
        i++
        continue
      }
      console.log(i)
      i++

    }
  </script>
无限循环

1.while(true) 来构造“无限”循环,需要使用break退出循环。(常用)

2.for(;;) 也可以来构造“无限”循环,同样需要使用break退出循环。

// 无限循环  
// 需求: 页面会一直弹窗询问你爱我吗?
// (1). 如果用户输入的是 '爱',则退出弹窗
// (2). 否则一直弹窗询问

// 1. while(true) 无限循环
// while (true) {
//   let love = prompt('你爱我吗?')
//   if (love === '爱') {
//     break
//   }
// }

// 2. for(;;) 无限循环
for (; ;) {
  let love = prompt('你爱我吗?')
  if (love === '爱') {
    break
  }
}

综合案例-ATM存取款机

分析:

①:提示输入框写到循环里面(无限循环)

②:用户输入4则退出循环 break

③:提前准备一个金额预先存储一个数额 money

④:根据输入不同的值,做不同的操作

(1) 取钱则是减法操作, 存钱则是加法操作,查看余额则是直接显示金额

(2) 可以使用 if else if 多分支 来执行不同的操作

完整代码:

<script>
  // 1. 开始循环 输入框写到 循环里面
  // 3. 准备一个总的金额
  let money = 100
while (true) {
  let re = +prompt(`
请您选择操作:
1.存钱
2.取钱
3.查看余额
4.退出
`)
  // 2. 如果用户输入的 4 则退出循环, break  写到if 里面,没有写到switch里面, 因为4需要break退出循环
  if (re === 4) {
    break
  }
  // 4. 根据输入做操作
  switch (re) {
    case 1:
      // 存钱
      let cun = +prompt('请输入存款金额')
      money = money + cun
      break
      case 2:
      // 存钱
      let qu = +prompt('请输入取款金额')
      money = money - qu
      break
      case 3:
      // 存钱
      alert(`您的银行卡余额是${money}`)
      break
  }
}
</script>

理解

一、理论理解

流程控制(Flow Control)是编程中最核心的基础模块之一,它让程序具备“判断能力”和“重复执行能力”。JavaScript 的流程控制可分为:

  • 顺序结构:代码从上往下依次执行;

  • 选择结构(条件判断):通过 if/elseswitch 判断某个条件成立与否来执行不同的代码分支;

  • 循环结构:通过 whilefor 等实现重复操作;

  • 跳转语句:如 breakcontinue 控制循环的中断或跳过;

  • 表达式简化结构:如三元运算符 ? :,让双分支判断更紧凑。

流程控制的本质是构建代码的“行为路径”:让程序对输入产生决策结果,并据此改变执行方向,这是构建一切逻辑应用、交互系统的底层思维框架。

ATM 案例正是流程控制的综合实践:以无限循环构建主逻辑,以条件判断处理用户输入分支,以变量和分支共同模拟状态变化。


二、大厂实战理解(BAT / 字节 / Google / OpenAI / NVIDIA)

字节跳动:条件控制+配置驱动 UI 构建

字节在中后台系统中广泛使用 if/else + 状态映射表 控制页面的状态渲染。例如:

if (user.status === 'PENDING') showPendingBanner()
else if (user.status === 'REJECTED') showReapplyButton()

这种逻辑处理方式+UI渲染分离,使产品具备可配置性与快速迭代能力。

阿里巴巴:流程控制+职责链设计模式

在蚂蚁金服的表单校验流程中,阿里会将每一步表单校验逻辑抽象成中间件,通过职责链顺序执行:

if (!checkLogin()) return redirectLogin();
if (!checkProfile()) return redirectProfile();
if (!checkPermission()) return showAccessDenied();

这种设计强调“前置判断+提前 return”,提高代码可读性与可维护性。

Google / Chrome V8 团队:循环优化

Google V8 引擎会对 forwhile 结构做优化,如 热点循环 JIT 编译,使其运行效率更接近原生 C++,这要求开发者写出“结构规范、终止条件明确”的循环体。

OpenAI:推理逻辑中的分支预测

在 GPT 模型推理中,虽然不能直接使用 if/else,但其多分支推理路径(例如生成多个候选 token)本质上是基于“条件概率”的分支控制思想——模型通过评分函数在多条路径中选择概率最高的一条,这和 switch-case 的“条件映射表”结构在本质逻辑上一致。

NVIDIA:状态机编程在图形渲染中的应用

在游戏引擎或图形渲染中,NVIDIA 设计了基于“状态-行为表”的 FSM(有限状态机)来控制角色行为,这就需要精确的流程判断与状态更新,体现出条件判断与循环的系统化结构。


大厂面试题


❓1. [字节跳动一面] if (a = 0) 为什么条件会为 false?这和 == 有什么区别?

解析:

  • a = 0 是赋值表达式,结果是 0

  • JavaScript 中,0 是“假值”,所以 if (a = 0) 会进入“false”分支

  • 面试考察点:混淆 === 是 JS 初学者常见 bug

let a;
if (a = 0) {
  console.log('执行'); // 不会执行
}

❓2. [腾讯二面] switchif-else if 有什么区别?各自适合什么场景?

解析:

特性if-else ifswitch
匹配类型条件表达式,可为区间精确值匹配(===
适用场景范围判断(如分数区间)枚举型匹配(如菜单、状态码)
执行效率一般来说 switch 更快(优化空间更大)多条件简单判断时,switch 更清晰
易读性与扩展性多层嵌套时可读性差使用 break 逻辑清晰、维护方便
// if 区间判断
if (score >= 90) ...
// switch 值匹配
switch (code) {
  case 200: ...
}

❓3. [阿里巴巴 P6] 写一个 JS 语句,判断某个数字是否是 10 的倍数,并输出结果(要求使用三元运算符)。

let num = 30;
let result = num % 10 === 0 ? '是10的倍数' : '不是10的倍数';
console.log(result);

❓4. [百度实习生笔试题] 写一个循环输出 1~100 中能被 7 整除的数字,要求不能使用 continue

for (let i = 1; i <= 100; i++) {
  if (i % 7 === 0) {
    console.log(i);
  }
}

❓5. [网易前端岗位] 请简述 while(true)for(;;) 有什么区别,是否都可以构造无限循环?

解析:

  • while(true):语义明确,更直观,适用于逻辑主导型死循环(如聊天、服务常驻)

  • for(;;):结构短小,语义不明显但可读性强于 C 风格

  • 两者都可以构造无限循环,关键在于使用 break 跳出

// 等效写法
while (true) { ... }
for (;;) { ... }

大厂场景题


💼 场景 1:[字节跳动 · 多条件筛选系统]

**背景:**在字节广告投放平台中,用户可选择多种筛选条件(如地域、年龄、性别),系统需根据所选条件动态筛选用户数据。

**题目:**请实现一个 filterUsers 函数,满足以下逻辑:

  • 条件全部满足 → 返回 true

  • 条件字段可选(即不存在时跳过判断)

  • 要求使用逻辑运算符处理

function filterUsers(user, conditions) {
  return (!conditions.region || user.region === conditions.region) &&
         (!conditions.age || user.age >= conditions.age) &&
         (!conditions.gender || user.gender === conditions.gender);
}

💼 场景 2:[阿里巴巴 · 双十一库存管理系统]

**背景:**双十一期间,阿里采用守护线程每秒轮询库存,如果某个商品库存为 0,则停止继续请求该商品。

**题目:**模拟实现轮询库存逻辑,当库存为 0 时退出轮询(使用 while + break):

let stock = 5;

while (true) {
  console.log('检查库存中...');
  if (stock <= 0) {
    console.log('库存为0,停止轮询');
    break;
  }
  stock--; // 模拟被抢购
}

💼 场景 3:[腾讯 · 微信登录系统]

**背景:**微信客户端在登录时,通过用户名和密码判断用户是否成功登录,如果失败,提示重新输入,最多允许三次机会。

**题目:**使用循环实现登录验证,三次失败后提示锁定账号:

let count = 0;

while (count < 3) {
  let uname = prompt('请输入用户名');
  let pwd = prompt('请输入密码');
  if (uname === 'weixin' && pwd === '123456') {
    alert('登录成功');
    break;
  } else {
    alert('用户名或密码错误');
    count++;
  }
}

if (count === 3) {
  alert('账户已锁定,请稍后再试');
}

💼 场景 4:[Google · 表单验证组件]

**背景:**Google 表单系统使用 switch-case 判断用户选择的验证方式(邮箱、手机、OAuth),并执行不同分支逻辑。

**题目:**用 switch 实现一个验证路由控制器:

let method = 'email'; // 用户选择验证方式

switch (method) {
  case 'email':
    console.log('正在进行邮箱验证...');
    break;
  case 'phone':
    console.log('正在进行短信验证...');
    break;
  case 'oauth':
    console.log('跳转OAuth授权页面...');
    break;
  default:
    console.log('未知的验证方式');
}

💼 场景 5:[OpenAI · 聊天消息轮询监听]

**背景:**OpenAI 聊天系统中前端需要监听新消息,并在满足条件时展示通知。监听逻辑为无限轮询 + 条件判断 + 中断机制。

**题目:**模拟实现一个“新消息检测”系统,满足:

  • 每轮模拟检测一条消息

  • 如果消息内容包含关键词 "重要",立即弹窗提醒

  • 使用 for(;;) 实现无限轮询 + break 中断

const messages = ['你好', '今天天气不错', '重要通知:系统维护', '晚安'];

for (let i = 0; i < messages.length; i++) {
  console.log('检测到消息:', messages[i]);
  if (messages[i].includes('重要')) {
    alert('🔔 新消息提醒:' + messages[i]);
    break;
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏驰和徐策

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值