JavaScript 是一门动态类型语言。变量本身不固定为某一种类型,值有自己的类型。理解值、函数和执行环境之间的关系,比记住大量零散语法更有帮助。

值与变量

常见的原始值包括字符串、数字、布尔值、nullundefined、大整数和符号。对象、数组和函数属于对象一侧的值。原始值本身不可变;对象则可以在保持同一引用的情况下修改其属性。

const 声明的绑定不能重新赋值,但如果绑定的是对象,对象内部的属性仍可能改变。需要重新赋值时使用 let。尽量缩小变量的作用范围,可以减少不同逻辑之间的意外影响。

const profile = { name: "轻风", notes: 1 };
profile.notes += 1; // 可以修改对象属性

let activeTopic = "HTML";
activeTopic = "CSS"; // let 允许重新赋值

函数封装一段行为

函数可以接收参数并返回结果。将计算写成输入与输出清楚的小函数,通常更容易测试和复用。函数没有显式执行 return 时,调用结果是 undefined

function formatTitle(topic) {
  return `学习笔记:${topic}`;
}

const title = formatTitle("JavaScript");

函数能够访问定义位置外层作用域中的变量,这种词法作用域关系由代码的书写位置决定。闭包指函数与其能够访问的词法环境的组合,它让函数在外层执行结束后仍可能使用其中的变量。

比较与条件判断

严格相等运算符 === 不会先进行隐式类型转换,通常更容易预测。条件表达式会把值转换成布尔含义,其中 false0、空字符串、nullundefinedNaN 等会被判断为假;空数组和空对象则会被判断为真。

异步任务不是立即得到结果

网络请求、计时器和用户操作可能在稍后才产生结果。Promise 表示一次异步操作最终完成或失败的状态,async 函数总是返回 Promise,await 可以在该函数内部等待 Promise 落定,再继续执行后续语句。

async function loadData() {
  const response = await fetch("/data.json");
  if (!response.ok) throw new Error("请求失败");
  return response.json();
}

fetch 在收到 HTTP 错误状态时通常不会自动拒绝 Promise,因此示例主动检查了 response.ok。网络失败、数据格式错误等情况仍需要在调用处进行错误处理。

学习时关注可观察的行为

阅读代码时,可以依次确认输入是什么、哪些值会变化、函数返回什么,以及异常由谁处理。面对异步代码,还要区分任务开始与结果可用的时刻。把这些关系画清楚,许多看似复杂的语法会回到少数稳定的基本概念。