01 · NOTES / WebGIS 开发
第 09 节 · 类体系全景
2026 年 9 月 1 日
第 09 节 · 类体系全景
📌 版本信息:Leaflet 1.9.4(2026-08-29 核对) 📚 本地教材:
resources/05-leaflet/Leaflet/src/(源码目录,本节的地图) | Leaflet API 参考 🎯 阶段二开篇——把散落在阶段一的 API 挂回"类树"上,读源码不再迷路。
一、这一节的目标
- 掌握 Leaflet 的类树主干:Map / Layer 家族 / Control 家族 / CRS 家族
- 理解
L.Class.extend的继承机制与 options 合并模式 - 会带着源码目录找实现("这个方法的源码在哪"的能力)
二、类树主干(背下这张图)
L.Map ← 地图本体(你唯一的"应用对象")
├── panes / _layers 内部:渲染分区与图层注册表
L.Evented ← 事件基类(Map/Layer/Control 全继承它!)
├── L.Layer ← 所有图层的抽象基类
│ ├── L.TileLayer 瓦片底图(GridLayer 子类)
│ ├── L.GeoJSON ← L.FeatureGroup 子类(数据进出的门户)
│ ├── L.FeatureGroup ← L.LayerGroup + 交互/样式
│ ├── L.LayerGroup 纯分组
│ ├── L.Path 矢量基类(SVG/Canvas 渲染的公共逻辑)
│ │ ├── Polyline / Polygon / Rectangle / Circle / CircleMarker
│ ├── L.Marker 标记(图标 + 交互,非 Path 体系)
│ └── L.ImageOverlay / VideoOverlay / WMS
L.Control ← 控件基类(zoom/scale/layers/attribution…)
L.CRS ← 坐标系基类(EPSG3857/4326/Simple)
L.Icon / L.DivIcon ← 图标
L.LatLng / L.LatLngBounds ← 基础值对象(不可变)
L.Bounds / L.Point ← 像素坐标值对象
三个阅读收益:
- Evented 是万物之祖:所以
map.on / layer.on / marker.off全套事件 API 通用——查事件 API 只查 Evented 一节 - GeoJSON 是 FeatureGroup 的子类:所以第 05/07 节的 Group 能力(fitBounds/clearLayers/addData)它全有——API 参考不用重复看
- Path 是矢量公共父类:
setStyle/getBounds/bindTooltip定义在此——Polyline/Polygon/Circle 通用
三、L.Class.extend:继承与 options 模式
Leaflet 没用 ES class,用自己实现的 L.Class(比 ES class 早十年,且提供独有的 options 合并机制):
// 自定义"图层"的标准写法(第 07 节 Control.extend 同款机制)
const NeonMarker = L.Marker.extend({
options: { // 与父类 options 深合并(覆盖同名项)
pulse: true, // 自己的新选项
},
initialize(latlng, options) { // 构造器(new 时调用)
L.Marker.prototype.initialize.call(this, latlng, options); // 调父类构造
if (this.options.pulse) { /* 附加逻辑 */ }
},
blink() { console.log('眨眼'); }, // 新方法(挂在原型上,实例共享)
});
new NeonMarker([30.59, 114.31]).addTo(map).blink();
读懂三个模式:①options 深合并(子类只写差异项);②initialize 是构造器名(不是 constructor);③L.XXX.prototype.method.call(this) 手动调父类——ES5 风格继承,源码里遍地都是。
四、源码目录导航(resources/05-leaflet/Leaflet/src/)
src/
├── map/ Map.js(本体,2000+ 行)+ handler(交互:拖拽/滚轮/双击缩放…)
├── layer/ layer.js(Layer 基类)→ marker/ vector/ tile/(三大分支各一文件夹)
│ └── vector/ Path._project/_update —— 渲染器原理的入口(第 11 节)
├── geometry/ Point/Bounds/LatLngTransformation(纯数学,无 DOM)
├── geo/ CRS/投影/LatLng(模块 04 的代码落地)
├── control/ Control.js 与各内置控件
├── core/ Class.js(继承机制)/ Util / Events
└── dom/ DOM 封装(跨浏览器兼容层)
查源码的标准姿势:API 文档里看到某方法 → 全局搜方法名(如 invalidateSize)→ 读实现 + 附近注释。Leaflet 源码注释密度高、风格干净,是前端开源库中最好的读物之一。
五、自测题
- Leaflet 万物之祖(事件来源)是哪个类?
- GeoJSON 类的父类链?这带来什么 API 复用?
- Path 基类覆盖哪些具体图层?意味着什么 API 通用?
- L.Class 的 options 合并机制对子类意味着什么?
- 想看"拖拽地图"的实现,去 src 哪个目录?
参考答案
L.Evented——Map/Layer/Control 都继承它(on/off/once/fire 全套)。- GeoJSON → FeatureGroup → LayerGroup → Layer → Evented;Group 全套 API(fitBounds/clearLayers/addData/控件注册)直接可用。
- Polyline/Polygon/Rectangle/Circle/CircleMarker;setStyle/bindTooltip/getBounds 等一份定义多处复用。
- 子类只声明差异项,与父类 options 深合并——子类 options 精简且默认值自动继承。
src/map/handler/(Dragging.js 等交互处理器都在这)。
六、下一步
类树在手 → 第 10 节:CRS 详解,把"坐标系"落到 Leaflet 的代码结构。