这篇讲 JavaScript 的基础语法:输出、输入、变量、数据类型、运算符和控制流。内容不多,但都是后面写代码的基础,建议你边看边动手运行示例代码。
在开始之前先说一个你会经常看到的词:ES6。JavaScript 的正式名称叫 ECMAScript,ES6 就是它在 2015 年发布的第 6 个大版本。这个版本加了很多好用的新语法,比如 let/const、箭头函数、class、模板字符串等等。现在这些语法已经是标准写法了,所有主流浏览器和 Node.js 都支持。后面教程中提到「ES6 引入的」,你知道它就是指这次更新就行。
输出
JavaScript 最常用的输出方式是 console.log(),它会在控制台打印内容,并且自动换行:
console.log() 每次调用都会自动换行。如果你不想换行,可以用 process.stdout.write():
日常用 console.log() 就够了,process.stdout.write() 在需要精确控制输出格式时才用。
输入处理
在算法题中,经常需要从标准输入读取数据。JavaScript 用 readline 模块来逐行读取输入,这是最常用的方式:
这段代码看起来有点长,我来拆解一下核心逻辑:
readline.createInterface()创建一个读取器,绑定到标准输入process.stdinrl.on("line", ...)每读到一行就把它存进lines数组rl.on("close", ...)输入全部读完后,在这个回调函数里处理数据
这个模板你先记住就行,后面做算法题时会反复用到。核心思路就是先把所有输入收集起来,等输入结束后再统一处理。
下面是一个更实用的模板,读取两个数并求和:
这里用 line.trim() 去掉行首行尾的空白,split(" ") 按空格拆分成数组,parseInt() 把字符串转成整数。这些都是处理输入时的常用操作。
变量
JavaScript 有三种声明变量的方式:let、const 和 var。
简单记:能用 const 就用 const,需要修改的值才用 let。
你可能还会在一些代码里看到 var。它是 JavaScript 早期声明变量的方式,功能和 let 类似,但有一些容易踩坑的行为(比如变量提升、没有块级作用域),所以现在不推荐使用了,了解一下就行:
// var 的写法(不推荐,了解即可)
var oldWay = "旧写法";后面写代码时,统一用 let 和 const 就好。
数据类型
JavaScript 有几种基本数据类型:
| 类型 | 说明 | 示例 |
|---|---|---|
number | 数字(整数和小数统一) | 42、3.14、-10 |
string | 字符串 | "hello"、'world' |
boolean | 布尔值 | true、false |
null | 空值(主动赋的) | null |
undefined | 未定义(变量声明了但没赋值) | undefined |
有一个值得注意的点:JavaScript 的 number 类型不区分整数和浮点数,42 和 42.0 是完全一样的。这让数字处理变得简单,但也有个小坑:0.1 + 0.2 的结果不是 0.3(浮点精度问题),这在所有编程语言里都存在。
用 typeof 运算符可以检查一个值的类型:
typeof null 返回 "object" 是一个历史遗留问题,知道就行,不用深究。
类型转换
不同类型的值之间经常需要互相转换,JavaScript 提供了几个常用的转换函数:
Number() 会严格转换整个字符串,如果字符串里有非数字字符就返回 NaN(Not a Number)。而 parseInt() 和 parseFloat() 更宽松,它们从字符串开头开始解析,遇到非数字字符就停止。
还有一种你会经常碰到的情况:字符串拼接时的隐式转换。
这里的关键:+ 号遇到字符串就变成拼接,其他算术运算符会自动把字符串转成数字。这是一个常见的坑,写代码时要注意。
运算符
算术运算符
注意一个重要的点:JavaScript 的除法 / 默认就是数学除法,17 / 5 得到 3.4,不会自动截断成整数。想要整数除法的效果,就用 Math.floor() 向下取整。
比较运算符
JavaScript 有两套相等运算符:===(严格相等)和 ==(宽松相等)。永远用 === 和 !==,忘掉 == 和 !=。宽松相等会做各种你意想不到的类型转换,是 bug 的温床。
逻辑运算符
位运算
位运算直接操作数字的二进制位,在处理二进制相关问题时非常高效。详细的位运算原理可以参考 常用的位操作,这里了解一下基本用法就行:
控制流
if / else if / else
三元运算符 条件 ? 值1 : 值2 适合简单的条件赋值,逻辑复杂时还是老老实实用 if-else 更清晰。
for 循环
经典的 for (let i = 0; i < n; i++) 你会用得最多,后面写算法题基本离不开它。for...of 在遍历数组和字符串时写起来更简洁,也很常用。
while 循环
while 循环在条件满足时重复执行,适合不确定循环次数的场景。do...while 保证循环体至少执行一次,用得比较少。
break 和 continue
break 是"我不玩了,直接出去",continue 是"这一轮跳过,下一轮继续"。
switch
switch 适合一个变量需要和多个固定值比较的场景:
注意每个 case 后面都要写 break,否则会"穿透"到下一个 case 继续执行。default 是所有 case 都不匹配时的兜底。实际写代码时,大多数情况用 if-else 就够了,switch 用得不算多。
异常处理
JavaScript 用 throw 抛出错误,用 try-catch-finally 接住。
throw 后面可以跟任何值(数字、字符串都行),但推荐抛 Error 或其子类,这样 stack 和 message 属性都在,调试时能看到堆栈。
常见的内置错误类型有 TypeError(对 null/undefined 取属性、调用不是函数的值,都会抛这个)、RangeError(值越界)、SyntaxError(语法错)、ReferenceError(引用了未定义的变量)。业务代码里如果要抛自定义错误,继承 Error 即可。
catch 后面的 (e) 不关心错误时可以省略,直接写 catch {} 即可,这是较新的语法,现代 Node 和浏览器都支持。finally 在 try 和 catch 之后都会执行,常用来关闭连接、释放锁、恢复状态。
写服务端代码时,建议在边界层(HTTP 请求入口、事件监听、定时任务)加一层 try-catch,这样某个小错误不会把整个 Node 进程直接干崩。
小结
这篇涵盖了 JavaScript 的基础语法:console.log() 输出、readline 读取输入、let/const 声明变量、基本数据类型和类型转换、运算符、以及 if/for/while 等控制流。
有几个关键点再强调一下:
- 比较用
===,不要用== - 除法
/默认产生小数,想要整数用Math.floor() +号遇到字符串就变成拼接,注意类型转换
下一篇我们来讲讲 JavaScript 的 模块与导入 机制,看看 require 是怎么回事,哪些功能需要导入、哪些直接就能用。