第二章|函数、作用域与调用方式
第一章学会了计算与控制,本章把规则封装为函数。重点不是函数写得多短,而是调用者提供什么、结果怎样返回、函数内部的名字和 this 从哪里来。
两条需要分开的线
text
函数定义 → 参数与返回 → 函数作为值 → 高阶函数
│
├── 定义位置 → 作用域链 → 闭包
└── 调用方式 → 普通函数 this → bind / new词法变量查找沿定义位置,普通函数接收者通常由调用方式决定。把这两条线分开,本章多数难点就可以逐步推导。
阅读顺序
- 函数基础:声明、表达式、箭头、默认参数、rest、解构参数、返回值和按值传递。
- 作用域与闭包:词法查找、块级作用域、提升、TDZ、闭包及循环绑定。
- this 与调用契约:方法取出、call/apply/bind、箭头、new 与不同环境的差异。
- 递归与高阶函数:回调、纯函数、递归终点、柯里化、部分应用及组合的输入输出关系。
这里会使用最小对象与数组语法展示函数保存和传递,例子旁会解释用到的操作;完整数据容器放到第三章。异步回调、错误传播和模块规则会在后续章节继续,本章不把回调默认当作异步。
两张图一起画,别合成一张
调用轨迹图记录“谁先执行、返回到哪”,作用域图记录“函数中的名字属于哪个环境”。total(double(3), 4)适合画第一张;读写两个函数共享page、另一次工厂调用独立,适合画第二张。普通函数this再单独标在调用箭头上,箭头函数则连接到外层绑定。
当读者能用这三处标记解释默认参数何时求值、闭包为何看见更新、bind为何保存接收者、new为何另建对象,函数就不再是一组互相冲突的口诀。本章练习会要求解释中间步骤,答案也保留推导,避免只对最后一个数字。
检查理解
能解释函数为什么打印了内容却返回 undefined;能独立推导闭包多次调用和多实例的差异;能说明对象方法传出去后怎样保留接收者;能为递归指出终点与缩小问题的步骤。验证自己写的函数时,改变参数再调用,并创建第二个实例检查状态是否独立;只复现正文的一次输出还不够。