cljs.core_Var 实现 IWithMeta,这与 Clojure 中的 vars 不同,Clojure 中的 vars 没有不可变元数据。with-meta 不应在 vars 上支持,而只应支持 alter-meta!。
与 Clojure 不同,ClojureScript 不使用 alter-meta! 的动态分派。cljs.core/alter-meta! 的实现会愉快地修改具有 "meta" 字段的对象的元数据,即使它不是 ref/var/Whatever 身份。这意味着如果您想在自定义类型上具有元数据,您必须有一个 "meta" 字段,而不是实现获取/更改元数据的方法。这不太理想,但对我没有立即问题。
我关心 IWithMeta 的原因是我需要在值和引用类型之间区分元数据处理。理想情况下,还会有一个 IAlterMeta 协议,但是 (satisfies? IMeta x) 且 (not (satisfies? IWithMeta x))) 就足够了。在 JVM 上,可以使用 IMeta 和 IObj 做同样的事情。