01 · NOTES / WebGIS 开发
第 10 节 · 运算符与流程控制
2026 年 9 月 1 日
第 10 节 · 运算符与流程控制
📌 版本信息:基于 ECMAScript 2025(基础语义多年稳定;2026-08-29 核对) 📚 来源:现代 JS 教程 · 运算符 | 现代 JS 教程 · 条件分支 | 现代 JS 教程 · 循环
一、这一节的目标
- 掌握算术、比较、逻辑运算符(重点:
&&||!和短路求值) - 会用现代三元运算符和空值合并
?? - 掌握
if/else、switch、三种循环 - 能独立写出"猜数字"游戏——程序的"判断 + 重复"两大骨架成型
二、算术与赋值
let distance = 10 + 3 * 2; // 16(先乘除后加减)
distance = (10 + 3) * 2; // 26(括号最优先)
10 / 3 // 3.3333...(JS 没有整数除法,都是浮点)
10 % 3 // 1(取余:判断奇偶、循环取格子的常客)
2 ** 10 // 1024(幂运算:缩放级别 × 2 的经典运算,第 04 模块会见到)
let zoom = 10;
zoom += 1; // 等价 zoom = zoom + 1,还有 -=、*=、/=
zoom++; // 自增;zoom-- 自减
💡 GIS 记忆点:瓦片金字塔每升一级瓦片数 ×4,即
4 ** zoom;缩放级别与分辨率的换算全靠幂运算。
三、比较与逻辑运算符
// 比较运算返回布尔值
30.59 > 30 // true
'5' === 5 // false(上节的规矩:永远严格相等)
// 逻辑与 或 非
const hasKey = true;
const isVip = false;
hasKey && isVip // false:两边都真才真
hasKey || isVip // true :一边真就真
!hasKey // false:取反
短路求值:逻辑运算符的第二身份
&& 和 || 返回的不一定是布尔值,而是"决定结果的那个操作数":
const userInput = '';
const displayName = userInput || '匿名用户'; // '' 是 falsy → 返回 '匿名用户'
// 习惯用法:给默认值
const map = null;
// map && map.getZoom(); // map 为 null 时短路,不会报错(防御式访问的老写法)
const zoom = null;
const safeZoom = zoom ?? 10; // ?? 空值合并:只在 null/undefined 时用默认值
// ?? 和 || 的区别:zoom 为 0 时,zoom || 10 会错误地变成 10,zoom ?? 10 保持 0
// → "缩放级别 0"是合法值!处理数字和布尔默认值时永远优先 ??
⚠️
??是 2020 年加入的现代运算符,专治||把0、''、false误伤成默认值的 bug。地图场景里zoom: 0合法,这条必须用对。
三元运算符:一行 if
const level = count > 100 ? '重度' : '轻度';
// 读法:条件 ? 真值 : 假值。嵌套会难读,最多一层
四、条件分支
// if / else if / else
function zoomToScale(zoom) {
if (zoom >= 18) {
return '楼栋级';
} else if (zoom >= 14) {
return '街道级';
} else if (zoom >= 10) {
return '城市级';
} else {
return '洲际级';
}
}
// switch:同一个变量的多种固定取值
function tileProvider(name) {
switch (name) {
case 'osm':
return 'OpenStreetMap 瓦片';
case 'tianditu':
return '天地图瓦片(需 key)';
case 'gaode':
return '高德瓦片(GCJ-02)';
default:
return '未知底图';
}
}
// 注意每个 case 末尾的 break——漏了会"穿透"到下一个 case 继续执行
💡 选型直觉:范围判断用 if/else if;固定取值枚举用 switch。
五、循环:让机器替你重复
// ① for:知道循环次数时的首选
for (let i = 0; i < 5; i++) {
console.log('第', i, '次'); // i = 0,1,2,3,4
}
// 遍历数组:for...of(最常用,值)
const cities = ['武汉', '西安', '成都'];
for (const city of cities) {
console.log(city);
}
// 遍历对象:for...in(拿键名,慎用——会把原型链上的也拿出来)
const wuhan = { lat: 30.59, lng: 114.3 };
for (const key in wuhan) {
console.log(key, wuhan[key]);
}
// break 与 continue
for (let i = 0; i < 10; i++) {
if (i === 3) continue; // 跳过本轮,直接进下一轮
if (i === 5) break; // 整个循环终止
console.log(i); // 输出 0 1 2 4
}
💡 现代开发里,数组的循环多数被第 13 节的 map/filter/reduce 接管(更声明式)。但 for 是它们的底层逻辑,且"循环中途 break"只有 for 做得到。三种都要会。
六、动手跟练:10 · 猜数字游戏
配套文件:02-web-basics/examples/10-猜数字游戏.html(一个可玩的页面,代码带注释和 4 个 TODO)
步骤:
- Live Server 打开:电脑随机想一个 1~100 的数,你输入猜测,它提示大了/小了/对了
- 通读代码:随机数怎么生成、表单提交怎么接住、条件分支怎么给提示
- 完成 4 个 TODO:限制猜的次数(≤7 次)、输入范围校验、显示"已猜次数"、加"重开一局"按钮
- 进阶挑战:加一个"作弊模式"——在 Console 里输入
answer直接看答案(把变量挂到 window 上)
通关标准:
- 游戏完整可玩,7 次内必胜(二分法)
- 输入 999 或 -5 会被校验拦截
- 能解释
Math.random()和Math.floor()为什么配合使用
七、自测题
zoom ?? 10和zoom || 10在zoom = 0时分别返回什么?地图场景为什么必须用前者?4 ** 3的值?它在瓦片计算里可能代表什么?- switch 里漏写 break 会发生什么?
for...of和for...in的区别?遍历数组该用哪个?continue和break分别对循环做什么?
参考答案
??返回 0,||返回 10。因为0是 falsy 会被||误伤,而缩放级别 0 是合法值。- 64;瓦片行/列数 = 2^zoom,幂运算就是干这个的。
- 穿透(fall-through):继续执行下一个 case 的代码,直到遇到 break——偶尔故意利用,多数是 bug。
for...of遍历值(数组用它);for...in遍历键名(用于对象,数组慎用)。- continue 跳过本轮进下一轮;break 终止整个循环。
八、下一步
数据会判断会循环了,但都散装着 → 第 11 节:函数与作用域,把逻辑打包成可复用的积木。
TAGSweb