后端转全栈学习-Day3-JavaScript 基础-1

第3天:JavaScript 基础(一)------ 变量·类型·运算·流程

学习时间:约 1.5 小时


目录

  1. [JavaScript 是什么](#JavaScript 是什么)
  2. 准备环境:浏览器控制台
  3. [变量声明:let 和 const](#变量声明:let 和 const)
  4. 数据类型
  5. 类型转换
  6. 运算符
  7. 字符串
  8. [流程控制:if / else / switch](#流程控制:if / else / switch)
  9. [循环:for / while](#循环:for / while)
  10. 练习
  11. 常见陷阱

1. JavaScript 是什么

1.1 HTML/CSS/JS 的分工

复制代码
HTML = 结构(房子框架)
CSS  = 装修(粉刷、家具)
JS   = 水电 + 智能家居(让房子"动"起来)

你现在的网页只有 HTML + CSS,就像一张海报------好看但不能交互。JS 就是让按钮能点、数据能刷、页面能动的能力。

1.2 JS 能干什么

场景 代码示例 说明
点按钮弹窗 btn.onclick = () => alert('已加入购物车') 用户操作响应
修改页面内容 priceTag.textContent = '¥199' 动态更新数据
发送请求 fetch('/api/products') 和后端通信
表单验证 if (phone.length !== 11) ... 防用户输错
动画 element.style.transform = 'rotate(90deg)' 动态效果

1.3 JS 和 Java 的区别

Java JavaScript
运行环境 JVM 浏览器 / Node.js
类型系统 强类型 弱类型(灵活但也容易踩坑)
面向对象 class 为主 原型链(ES6 也有 class)
编译 编译执行 解释执行(一行一行跑)

一句话:JS 是浏览器的"脚本语言",不用编译就能跑,写一句就能看到效果。


2. 准备环境:浏览器控制台

2.1 不用装任何东西

因为 JS 在浏览器里跑,你只需要浏览器------Chrome 最好。

2.2 打开控制台

复制代码
快捷键:
  Windows:  F12 或 Ctrl+Shift+I
  Mac:      Cmd+Option+I

然后点 Console(控制台)标签

2.3 试试手

在控制台里直接输入下面内容,按回车:

js 复制代码
let name = '小明'
console.log('你好,' + name)

你会看到控制台打印出"你好,小明"。

js 复制代码
let price = 99
let quantity = 2
price * quantity  // 直接回车,控制台会显示结果 198

控制台就是你学 JS 最好的练习场------打开 F12 就能写,不用建文件,不用编译。

2.4 在 HTML 里用 JS

html 复制代码
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>JS 测试</title>
</head>
<body>
  <button id="btn">点我</button>

  <script>
    // 找一个元素,绑定点击事件
    const btn = document.getElementById('btn')
    btn.addEventListener('click', function() {
      alert('你点了我!')
    })
  </script>
</body>
</html>

<script> 标签就是往页面里写 JS 代码的地方。可以放在 <head> 里,也可以放在 </body> 前面(推荐放 body 最后,这样能保证先渲染页面再执行 JS)。


3. 变量声明:let 和 const

3.1 let ------ 可以变的变量

js 复制代码
let price = 99
console.log(price)  // 99

price = 129         // 重新赋值
console.log(price)  // 129

3.2 const ------ 不能变的常量

js 复制代码
const taxRate = 0.13
taxRate = 0.15      // ❌ 报错!const 不能重新赋值

// const 声明的必须立即赋值
const name           // ❌ 报错!缺少初始值

原则:能用 const 就用 const,因为它让代码更安全------你不用担心它被意外改掉。

JS 新手最大的困惑:为什么 const 声明的数组还能 push

js 复制代码
const cart = []
cart.push('iPhone')   // ✅ 可以!数组内容变了
cart = ['iPad']       // ❌ 报错!变量不能重新赋值
复制代码
const 保证的是"变量指向的那个东西不变",不是"那个东西的内容不变"
类比:你的家庭住址不能变,但房间里住的人可以换

3.3 var ------ 已过时,别用

旧的 JS 用 var 声明变量。它有两个坑:

js 复制代码
// 坑 1:没有块级作用域
if (true) {
  var oldWay = '我逃出去了'
}
console.log(oldWay)   // '我逃出去了' ------ 明明在 if 块里,外面也能访问

// let 就不会
if (true) {
  let newWay = '我困在里面'
}
console.log(newWay)   // ❌ 报错!newWay 未定义
js 复制代码
// 坑 2:可以重复声明
var a = 1
var a = 2   // 不报错,覆盖了

let b = 1
let b = 2   // ❌ 报错

记住:永远用 letconst,不要用 var

3.4 命名规范

js 复制代码
// ✅ 驼峰命名(camelCase)------ JS 标准
let productName = 'iPhone'
let userAge = 25

// ✅ 常量全大写
const MAX_COUNT = 100
const TAX_RATE = 0.13

// ❌ 别这样
let ProductName = 'iPhone'   // 类才用大驼峰
let product_name = 'iPhone'  // 这是 Python 风格

3.5 变量与 Java 的对比

java 复制代码
// Java:类型写在前面
String name = "张三";
int age = 25;
double price = 99.9;
js 复制代码
// JS:不需要写类型(弱类型)
let name = '张三'
let age = 25
let price = 99.9

JS 的变量没有类型标签------值才有类型。同一个变量可以先后装不同类型的值:

js 复制代码
let something = 'hello'   // 现在是字符串
something = 42            // 变成数字了
something = true          // 又变成布尔了

这在 Java 里是禁止的,在 JS 里允许。方便但不安全,所以要自己留心变量装的是什么。


4. 数据类型

4.1 JS 类型 vs Java 类型:先看一张对照表

如果你是 Java 后端,JS 的类型体系会让你很不适应------JS 没有 byte/short/int/long/float/double 的区分,所有数字都是一种类型。

java 复制代码
// Java:每个数字类型有明确的字节数和范围
byte   b = 127;           //  1 byte  =   8 bit,    -128 ~ 127
short  s = 32767;         //  2 bytes =  16 bit,    -32768 ~ 32767
int    i = 2147483647;    //  4 bytes =  32 bit,    -21亿 ~ 21亿
long   l = 9_007_199_254_740_991L;  //  8 bytes =  64 bit,   -2^63 ~ 2^63-1
float  f = 3.14f;         //  4 bytes,   IEEE 754 单精度,  约 ±3.4e38
double d = 3.14;          //  8 bytes,   IEEE 754 双精度,  约 ±1.8e308
js 复制代码
// JS:就一种 number,相当于 Java 的 double
let price = 99.9          // 8 bytes, IEEE 754 双精度浮点数
let count = 10            // 同一个类型,只不过没有小数

4.2 基本类型(7 种)

类型 示例 内存 / 范围 说明
number 423.14-10 8 bytes / ±1.8e308 不分整数浮点,一律 IEEE 754 双精度
string 'hello'"你好" 2 bytes/字符(UTF-16) 字符串,不可变
boolean truefalse 理论 1 bit,实际因引擎而异 布尔
null null 0(空引用) 空值(主动设为空)
undefined undefined 0(未初始化) 未定义(声明了没赋值)
bigint 9007199254740991n 按位动态分配 任意精度整数,n 后缀
symbol Symbol('id') 唯一标识 一般用不到

重点 :JS 的 number = Java 的 double。没有 int,没有 long,没有 float。所有的 number 都是 64 位双精度浮点数。

4.3 number ------ 深入拆解

存储模型
复制代码
JS number = IEEE 754 双精度(64 bit)
┌─────────┬──────────────────┬──────────────────────────────┐
│ 1 bit   │ 11 bits          │ 52 bits                      │
│ 符号位   │ 指数位            │ 尾数位(有效数字)             │
│ 0=正 1=负 │ 偏移值 1023      │ 表示有效数字                   │
└─────────┴──────────────────┴──────────────────────────────┘

这解释了 JS 数字的两个关键特征:

特征 1:安全整数范围

js 复制代码
// 因为尾数只有 52 bits,所以能精确表示的整数范围是有限的
Number.MAX_SAFE_INTEGER   // 9007199254740991(≈ 9 千万亿,2^53 - 1)
Number.MIN_SAFE_INTEGER   // -9007199254740991

// 超过这个范围,整数就不连续了
console.log(9007199254740991 + 1)   // 9007199254740992  ✅
console.log(9007199254740991 + 2)   // 9007199254740992  ❌ 没变!精度丢失
console.log(9007199254740991 + 3)   // 9007199254740994  ✅ 跳过了 3

这和你的项目直接相关 :Snowflake ID 是 19 位数字(如 1736158234567475200),远大于 Number.MAX_SAFE_INTEGER(16 位)。这就是为什么项目中把 Long 序列化为 String------前端 JS 拿到 19 位 long 会精度丢失,最后几位变成 0。

java 复制代码
// 项目已配置:所有 Long 序列化为 String
@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
    return builder -> builder.serializerByType(Long.class, ToStringSerializer.instance);
}

特征 2:浮点数不精确

js 复制代码
// 二进制无法精确表示 0.1,就像十进制无法精确表示 1/3
0.1 + 0.2   // 0.30000000000000004

// 值的范围
Number.MAX_VALUE          // 1.7976931348623157e+308
Number.MIN_VALUE          // 5e-324(最小的正数,不是负数最小)
常用写法
js 复制代码
let count = 10
let price = 99.9          // 浮点数
let total = 3.99 * 5      // 运算
let billion = 1_000_000   // 下划线只是好看,值还是 1000000

// 进制
0xFF    // 255(16进制)
0o77    // 63(8进制)
0b1101  // 13(2进制)

// 科学计数法
let mass = 1.6e-19        // 1.6 × 10^-19

// 特殊值
Infinity          // 无穷大,比如 1 / 0
-Infinity         // 负无穷大
NaN               // Not a Number,比如 'abc' * 2

作为 Java 后端的建议 :只要你需要关心整数精度(比如 ID、订单号),就用 bigint 或保持字符串传递。普通计算(金额用分单位整数)用 number 就够了。浮点运算精度问题所有语言都有,JS 只是最诚实的一个。但这里的 16 位安全整数限制是 JS 独有的 ------Java 的 long 有 19 位精度。

4.4 bigint ------ 大整数(ES2020)

当你要处理超过 2^53 的整数时,用 bigint:

js 复制代码
// n 后缀声明 bigint
const snowflakeId = 1736158234567475200n
const big = 9007199254740991n + 2n   // bigint 运算要加 n

// 不能混用 number 和 bigint
1n + 2n   // ✅ 3n
1n + 2    // ❌ TypeError: Cannot mix BigInt and other types

// 比较可以
1n === 1  // false(类型不同)
1n == 1   // true(宽松比较)

4.3 string ------ 字符串

三种写法:

js 复制代码
let s1 = '单引号'
let s2 = "双引号"
let s3 = `反引号`     // 模板字符串,后面细讲

// 都一样,你选一种喜欢的就行。我推荐单引号

转义字符:

js 复制代码
let msg = 'I\'m a student'   // 单引号里写单引号要加反斜杠
let path = 'C:\\Users\\name'  // 反斜杠本身也要转义

4.4 boolean ------ 布尔值

js 复制代码
let isLoggedIn = false
let isOnSale = true
let isStockEmpty = false

4.5 null vs undefined

这是 JS 新手最容易混淆的一对:

js 复制代码
let a      // 声明了没赋值 → undefined
let b = null  // 主动设为"空"

console.log(a)  // undefined
console.log(b)  // null
复制代码
undefined = "还没给值"(语言的默认行为)
null      = "我给清空了"(程序员的主动行为)

实际开发:

  • 你不应该主动给变量赋 undefined------那是 JS 自己的事
  • 你要表示"空"就用 null

4.6 typeof ------ 查看类型

js 复制代码
typeof 42          // 'number'
typeof 'hello'     // 'string'
typeof true        // 'boolean'
typeof undefined   // 'undefined'
typeof null        // 'object'  ← 这是一个 JS 历史遗留 bug,别管它
typeof NaN         // 'number'  ← 又一个坑,NaN 的类型居然是 number

遇到可疑的值,用 typeof 看一下,这是调试的常用技巧。


5. 类型转换

5.1 隐式转换 ------ JS 自作主张

JS 是弱类型语言,在运算时会自己转类型:

js 复制代码
// 数字 + 字符串 → 字符串拼接
'价格:' + 99      // '价格:99'
'5' + 3            // '53'(变成了字符串)

// 字符串 - 数字 → 转成数字运算
'10' - 3           // 7
'10' * 3           // 30
'10' / 2           // 5

// 非布尔 → 布尔
if ('hello') { }   // 'hello' 被当成 true(非空字符串为 true)
if (0) { }         // 0 被当成 false
if ('') { }        // 空字符串为 false

隐式转换的坑

js 复制代码
'5' - 3     // 2(减号触发数字转换)
'5' + 3     // '53'(加号触发字符串拼接)

// 经典坑
0 == false    // true  ← 0 和 false 居然相等
'' == false   // true  ← 空字符串也算 false
null == undefined  // true  ← 这两个也相等

5.2 显式转换 ------ 你说了算

js 复制代码
// 转数字
Number('123')       // 123
Number('12.3')      // 12.3
Number('abc')       // NaN(转不了)
parseInt('123px')   // 123(从开头解析数字)
parseFloat('3.14')  // 3.14
+ '99'              // 99(加号在变量前面也是一元转换)

// 转字符串
String(123)         // '123'
String(true)        // 'true'
(99).toString()     // '99'

// 转布尔
Boolean(1)          // true
Boolean(0)          // false
Boolean('')         // false
Boolean('abc')      // true
Boolean(null)       // false
Boolean(undefined)  // false

实战建议

js 复制代码
// ✅ 尽量用显式转换,少依赖隐式
let num = '42'
let total = Number(num) + 10   // 清晰:先把字符串转数字再加

// ❌ 依赖隐式容易出事
let total2 = num + 10          // '4210' ------ 字符串拼接了!

Falsy 值速记(在 if 里被当成 false 的 6 个值):

复制代码
false、0、''(空字符串)、null、undefined、NaN

其他一切值都是 truthy,包括 'false' 这个字符串(因为它非空)。


6. 运算符

6.1 算术运算符

js 复制代码
let a = 10
let b = 3

a + b   // 13
a - b   // 7
a * b   // 30
a / b   // 3.3333...
a % b   // 1(取余数)
a ** b  // 1000(10 的 3 次方)

// 简写
a += 5   // a = a + 5
a -= 3   // a = a - 3
a *= 2   // a = a * 2

6.2 自增自减

js 复制代码
let count = 0
count++    // count = count + 1
count--    // count = count - 1

// 前置和后置的区别
let i = 0
console.log(i++)   // 0(先取值,再加)
console.log(i)     // 1

let j = 0
console.log(++j)   // 1(先加,再取值)

6.3 比较运算符

js 复制代码
// 基本比较
5 > 3     // true
5 < 3     // false
5 >= 5    // true
5 <= 3    // false

// 等号(重要!三个等号和两个等号)
5 == '5'    // true  (只比较值,不比较类型)
5 === '5'   // false (比较值和类型,推荐用这个)

5 != '5'    // false (只比较值)
5 !== '5'   // true  (比较值和类型,推荐用这个)

铁律:永远用三个 ===,不用两个 ==

js 复制代码
// 不用 == 的理由
0 == false      // true
'' == false     // true
null == undefined  // true
' \n ' == 0     // true(空格的字符串居然等于 0)

== 的隐式转换规则非常复杂,正常人记不住。=== 就不会有这些幺蛾子------值或类型不同就是 false

6.4 逻辑运算符

js 复制代码
// &&(与):两个都为 true 才为 true
true && true      // true
true && false     // false

// ||(或):一个为 true 就是 true
true || false     // true
false || false    // false

// !(非):取反
!true             // false
!false            // true
!0                // true(0 是 falsy)
!'hello'          // false('hello' 是 truthy)

短路求值(实用技巧):

js 复制代码
// &&:前面为 false,后面就不再执行
let isLoggedIn = false
isLoggedIn && console.log('登录成功')   // 不会执行,因为 isLoggedIn 是 false

// ||:前面为 true,后面就不再执行
let username = ''
let displayName = username || '匿名用户'   // displayName = '匿名用户'

6.5 三元运算符

js 复制代码
// 条件 ? 真 : 假
let price = 100
let label = price > 50 ? '贵' : '便宜'
console.log(label)   // '贵'

等同的 if/else:

js 复制代码
let label
if (price > 50) {
  label = '贵'
} else {
  label = '便宜'
}

三元运算符更适合"二选一赋值"的场景,写起来更简洁。


7. 字符串

7.1 字符串拼接

老的方式:

js 复制代码
let name = 'AirPods Pro'
let price = 1999

// 用 + 拼接
let desc = '商品:' + name + ',价格:¥' + price
console.log(desc)  // '商品:AirPods Pro,价格:¥1999'

7.2 模板字符串(强烈推荐)

用反引号(`````)+ ${} 插值:

js 复制代码
let name = 'AirPods Pro'
let price = 1999

let desc = `商品:${name},价格:¥${price}`
console.log(desc)  // '商品:AirPods Pro,价格:¥1999'

优势 1:不用来回 + 了

js 复制代码
// 以前
let msg = '用户 ' + user + ' 在 ' + time + ' 下单了 ' + product + ',金额 ¥' + amount

// 模板字符串
let msg = `用户 ${user} 在 ${time} 下单了 ${product},金额 ¥${amount}`

优势 2:可以换行

js 复制代码
// 模板字符串支持换行
let html = `
  <div class="product-card">
    <h3>${productName}</h3>
    <p>¥${price}</p>
  </div>
`

// 用引号不行------会报错
let html2 = '
  <div>
'    // ❌ 换行就报错

优势 3:可以写表达式

js 复制代码
let price = 99
let quantity = 3
let total = `总价:¥${price * quantity}`   // '总价:¥297'

7.3 常用方法

js 复制代码
let str = '  Hello JavaScript  '

str.length              // 20(包含空格)
str.toUpperCase()       // '  HELLO JAVASCRIPT  '
str.toLowerCase()       // '  hello javascript  '
str.trim()              // 'Hello JavaScript'(去首尾空格)
str.includes('Java')    // true(是否包含)
str.startsWith('Hell')  // false(前面有空格)
str.endsWith('pt  ')    // true
str.slice(2, 7)         // 'Hello'(截取索引 2 到 6)
str.indexOf('Java')     // 8(第几个位置)
str.replace('Java', 'Type')  // '  Hello TypeScript  '
str.split(' ')          // ['', '', 'Hello', 'JavaScript', '', '']

// 链式调用
let phone = '  138-1234-5678  '
let cleaned = phone.trim().replace(/-/g, '')   // '13812345678'

8. 流程控制:if / else / switch

8.1 if / else

js 复制代码
let stock = 0

if (stock > 100) {
  console.log('库存充足')
} else if (stock > 0) {
  console.log('库存紧张,仅剩 ' + stock + ' 件')
} else {
  console.log('暂时缺货')
}

if 的条件判断:任何值都可以作为条件,JS 会自动转成布尔:

js 复制代码
let name = ''
if (name) {
  console.log('有名字')   // 不会执行,空字符串是 falsy
}

let count = 0
if (count) {
  console.log('有数量')   // 不会执行,0 是 falsy
}

let arr = []
if (arr) {
  console.log('有数组')   // 会执行!空数组是 truthy!
}

注意 :空数组 [] 是 truthy,空对象 {} 也是 truthy。很多新手在这里翻车。

8.2 switch

js 复制代码
let status = 2

switch (status) {
  case 1:
    console.log('待付款')
    break
  case 2:
    console.log('已付款')
    break
  case 3:
    console.log('已发货')
    break
  case 4:
    console.log('已完成')
    break
  default:
    console.log('未知状态')
}

别忘了 break 忘记的话会"穿透"到下一个 case:

js 复制代码
let level = 'A'

switch (level) {
  case 'A':
    console.log('优秀')
    // 忘记 break ------ 继续往下走
  case 'B':
    console.log('良好')
    break
}

// 输出:
// '优秀'
// '良好'    ← 这个就是穿透,不是你想要的

8.3 if vs switch

js 复制代码
// if:适合范围判断(>、<、包含)
if (score >= 90) {
  console.log('优秀')
} else if (score >= 60) {
  console.log('及格')
} else {
  console.log('不及格')
}

// switch:适合精确匹配(===)
switch (paymentMethod) {
  case 'wechat':
    console.log('微信支付')
    break
  case 'alipay':
    console.log('支付宝')
    break
}

9. 循环:for / while

9.1 for 循环

js 复制代码
// 语法:for (初始化; 条件; 更新)
for (let i = 0; i < 5; i++) {
  console.log('第 ' + (i + 1) + ' 次循环')
}
// 输出:第 1 次循环  第 2 次循环  ...  第 5 次循环

执行顺序:

复制代码
第 1 步:let i = 0          → 只执行一次
第 2 步:i < 5 ?           → true 执行循环体,false 退出
第 3 步:执行循环体 { ... }
第 4 步:i++                → i 变成 1
第 5 步:回到第 2 步

遍历数组:

js 复制代码
let products = ['iPhone', 'iPad', 'MacBook']

for (let i = 0; i < products.length; i++) {
  console.log(products[i])
}
// iPhone
// iPad
// MacBook

9.2 while 循环

js 复制代码
// while:先判断再执行
let i = 0
while (i < 5) {
  console.log(i)
  i++
}

// do...while:先执行再判断(至少执行一次)
let j = 0
do {
  console.log(j)
  j++
} while (j < 5)

for vs while:

js 复制代码
// 知道要循环几次 → for
for (let i = 0; i < products.length; i++) { ... }

// 不知道循环几次,看条件 → while
let stock = 100
while (stock > 0) {
  sellOne()     // 卖出一件
  stock--
}

9.3 break 和 continue

js 复制代码
// break:跳出循环
for (let i = 0; i < 10; i++) {
  if (i === 5) {
    break      // 到 5 就停了
  }
  console.log(i)
}
// 输出:0 1 2 3 4

// continue:跳过本次,继续下一次
for (let i = 0; i < 5; i++) {
  if (i === 2) {
    continue   // 跳过 2
  }
  console.log(i)
}
// 输出:0 1 3 4

10. 练习

练习 1(初级):在控制台玩变量

打开 F12 控制台,依次输入:

js 复制代码
// 1. 声明商品名称和价格
let productName = '无线蓝牙耳机'
let price = 299

// 2. 计算打折后的价格(8折)
let discountPrice = price * 0.8
console.log(`原价:¥${price},折后价:¥${discountPrice}`)

// 3. 判断并输出
let stock = 5
if (stock > 0) {
  console.log(`${productName} 有货`)
} else {
  console.log(`${productName} 缺货`)
}

练习 2(初级:if / else + 三元运算)

商场促销规则:

  • 满 200 打 8 折
  • 满 100 打 9 折
  • 否则不打折
js 复制代码
let amount = 260
// 用 if/else 实现
// 试着再用三元实现

练习 3(中级:循环)

用 for 循环生成一个商品列表字符串:

js 复制代码
let products = [
  { name: 'iPhone', price: 7999 },
  { name: 'iPad', price: 3499 },
  { name: 'AirPods', price: 1999 }
]

// 用 for 循环生成格式化的字符串输出:
// 1. iPhone - ¥7999
// 2. iPad - ¥3499
// 3. AirPods - ¥1999

练习 4(中级:综合)

写一个函数,判断用户登录状态 + 购物车状态,输出提示:

js 复制代码
let isLoggedIn = true
let cartItems = 0

// 输出规则:
// - 未登录 → "请先登录"
// - 已登录 + 购物车为空 → "购物车是空的"
// - 已登录 + 有商品 → "您有 X 件商品在购物车"

11. 常见陷阱

陷阱 1:== 用了两个等号

js 复制代码
// 永远用 ===
'5' == 5    // true(隐式转换)
'5' === 5   // false

0 == false  // true
0 === false // false

陷阱 2:忘记 const 不能重新赋值

js 复制代码
const price = 99
price = 100   // ❌ TypeError

// 但如果 const 的是对象,可以改里面的属性
const product = { name: 'iPhone' }
product.name = 'iPad'   // ✅ 可以
product = {}            // ❌ 不可以

陷阱 3:浮点数计算不精确

js 复制代码
0.1 + 0.2   // 0.30000000000000004(不是 0.3!)

// 这不是 JS 的锅,所有编程语言都这样(二进制无法精确表示 0.1)
// 解决方案:金额相关用整数(分)或 toFixed
(0.1 + 0.2).toFixed(1)   // '0.3'

陷阱 4:NaN 不自等

js 复制代码
NaN === NaN   // false  ← NaN 不等于任何东西,包括自己

// 判断是不是 NaN
isNaN(NaN)          // true
Number.isNaN(NaN)   // true(推荐)

陷阱 5:for 循环里用了 const

js 复制代码
// ❌ 这样不行
for (const i = 0; i < 5; i++) {   // i++ 会报错,因为 const 不能变
  console.log(i)
}

// ✅ 用 let
for (let i = 0; i < 5; i++) {
  console.log(i)
}

附:今日速查

js 复制代码
// 变量
let name = '值'
const MAX = 100

// 类型
typeof x          // 查看类型
Number(s)         // 转数字
String(n)         // 转字符串
Boolean(x)        // 转布尔

// 比较(永远用三个等号)
===   !==

// 字符串
`模板 ${表达式}`
str.length
str.trim()
str.includes('x')

// if
if (...) { } else if (...) { } else { }

// 循环
for (let i = 0; i < n; i++) { }
while (条件) { }
break        // 跳出
continue     // 跳过本次

// falsy 值(6个)
false, 0, '', null, undefined, NaN
相关推荐
GISHUB1 小时前
Express + TypeScript + ESM 后端服务搭建教程
javascript·typescript·express
llilay1 小时前
企业级FastAPI后端模板搭建(二)整合路由Router
开发语言·python·fastapi
不会C语言的男孩1 小时前
C++ Primer Plus 第13章:类继承
开发语言·c++
我材不敲代码1 小时前
Python基础: 函数超全详解:定义、参数、返回值、作用域与递归
开发语言·python·算法
承渊政道1 小时前
Linux系统学习【进程控制:进程创建、终止与等待、进程程序替换、自主shell命令行解释器详解】
linux·服务器·c++·学习·ubuntu·bash·远程工作
志起计算机编程1 小时前
挖掘单节点Clickhouse极致性能上限
服务器·开发语言·python
Reisentyan1 小时前
[Pro]GoLang Learn Data Day 5
开发语言·后端·golang
zhangfeng11331 小时前
华为昇腾910A NPU 的模型加密方案 ASCEND-CC
开发语言·人工智能·神经网络·transformer
聆风吟º1 小时前
【Python编程日志】Python基础语法:常量 | 表达式 | 变量
开发语言·python·变量·常量·表达式