ClojureScript:JS 对象中的数据共享
ClojureScript: Data-Sharing in JS-Objects
我对使用 clj->js
命令转换 ClojureScript 中的列表后的共享实例有疑问。
我有以下代码:
(def list '(1 (5 6 7) 3 4 5))
(def jslist1 (clj->js (pop list)))
(def jslist2 (clj->js (pop list)))
(.log js/console "js:")
(.log js/console (= (get jslist1 0) (get jslist2 0)))
(def cljlist1 (pop list))
(def cljlist2 (pop list))
(.log js/console "clj:")
(.log js/console (= (get cljlist1 0) (get cljlist2 0)))
如果我运行这段代码,我得到控制台输出:
js:
false
clj:
true
我本以为 JS 对象也引用了 (5 6 7)
数组的同一个实例。相反,它似乎创造了一个新的。有谁知道,为什么这与 clj 列表的行为不同?
我假设在 Clojure 世界中这两个列表是相等的,因为这两个变量持有对内存中同一对象的引用。弹出 returns 对同一对象的引用。
在 Javascript 世界中,这两个列表变成数组,即对象,并按照 Javascript 的规则进行比较。两个对象,即使它们包含相同的值,也不相等,因为它们是两个不同的引用,内存中的两个不同位。
如果您查看 clj->js
的源代码,您将看到适用于集合的代码:
(coll? x) (let [arr (array)]
(doseq [x (map clj->js x)]
(.push arr x))
arr)
创建了一个 new JS array
并将集合的全部内容复制到 JS 数组 - 每次 clj->js
被调用。
推测该数组是防御副本,以防止原始 ClojureScript 列表及其内容被修改。
我对使用 clj->js
命令转换 ClojureScript 中的列表后的共享实例有疑问。
我有以下代码:
(def list '(1 (5 6 7) 3 4 5))
(def jslist1 (clj->js (pop list)))
(def jslist2 (clj->js (pop list)))
(.log js/console "js:")
(.log js/console (= (get jslist1 0) (get jslist2 0)))
(def cljlist1 (pop list))
(def cljlist2 (pop list))
(.log js/console "clj:")
(.log js/console (= (get cljlist1 0) (get cljlist2 0)))
如果我运行这段代码,我得到控制台输出:
js:
false
clj:
true
我本以为 JS 对象也引用了 (5 6 7)
数组的同一个实例。相反,它似乎创造了一个新的。有谁知道,为什么这与 clj 列表的行为不同?
我假设在 Clojure 世界中这两个列表是相等的,因为这两个变量持有对内存中同一对象的引用。弹出 returns 对同一对象的引用。
在 Javascript 世界中,这两个列表变成数组,即对象,并按照 Javascript 的规则进行比较。两个对象,即使它们包含相同的值,也不相等,因为它们是两个不同的引用,内存中的两个不同位。
如果您查看 clj->js
的源代码,您将看到适用于集合的代码:
(coll? x) (let [arr (array)]
(doseq [x (map clj->js x)]
(.push arr x))
arr)
创建了一个 new JS array
并将集合的全部内容复制到 JS 数组 - 每次 clj->js
被调用。
推测该数组是防御副本,以防止原始 ClojureScript 列表及其内容被修改。