原型继承在复杂动画框架中用于统一定义可复用行为模板,如缓动逻辑、时间轴控制等,使动画实例共享方法、仅保存自身状态,从而节省内存、便于热更新、支持分层抽象与状态逻辑分离,并配合结构化数据实现高性能调度。

原型继承在复杂动画框架里,不是用来管理每一帧的动画实例,而是用来统一定义可复用的行为模板——比如缓动逻辑、时间轴控制、状态机切换这些“不变的骨架”,让成百上千个动画对象共享方法,不重复创建函数。
用 prototype 封装通用动画行为
把所有动画共有的方法(如 start()、pause()、update(delta)、easeOutCubic(t))写在基类原型上。每个动画实例只存自己的状态(this.duration、this.from、this.to、this.currentTime),不带函数副本。
- 避免每个动画实例都 new 一个完整函数对象,节省内存和 GC 压力
- 修改 TweenBase.prototype.update,所有实例立即生效,便于统一调试和热更新
- 用 Object.create(null) 创建精简原型链,跳过默认的 Object.prototype,加快属性查找
分层抽象:用原型链表达动画类型关系
不是靠 new 出来一堆对象拼树,而是按语义建模层级:基础补间(TweenBase)→ 数值动画(NumberTween)→ 贝塞尔路径动画(PathTween)→ UI 组件动画(ButtonFadeTween)。子类原型指向父类原型,但只继承方法,不共享状态。
- NumberTween.prototype = Object.create(TweenBase.prototype),再设 constructor
- 子类可重写 apply() 或 interpolate(),不影响父类其他子类
- 类型判断用 instanceof 或 isPrototypeOf(),而非字符串匹配
状态与逻辑彻底分离
动画运行时高频更新的是数值(位置、透明度、旋转角),这些必须放在实例上;而插值算法、事件派发、生命周期钩子这些稳定逻辑,全放在 prototype 上。
- 实例只含纯数据:{ x: 0, y: 0, alpha: 1, isPlaying: true, elapsed: 0 }
- prototype 提供标准接口:on('complete', cb)、seek(time)、reverse()
- 批量操作(如暂停全部动画)只需遍历实例数组调用 this.pause(),不用查原型链
配合数据结构做高性能调度
原型继承本身不提速,但它让动画系统能轻装上阵:把所有动画实例存在 Float32Array 或结构化数组中,用 ID 索引;每帧只对激活动画调用 instance.update(delta),而这个 update 方法来自共享原型,执行快、内联友好。
- 用位掩码标记状态(playing | paused | completed | reversed),单整数位运算替代布尔字段
- 时间轴统一由 AnimationTimeline 管理,它不依赖任何原型链,只负责分发 delta 和触发回调
- 渲染层完全解耦——动画系统只输出最终数值,由渲染器决定怎么画,不掺和 draw call 优化

















