ClojureScript 重整在高级优化中为相同类型的代码命名不同

ClojureScript mangling names differently for the same kind of code in advanced optimizations

这是 Chrome 扩展的一段代码。

我是从 ClojureScript 开始的,所以这可能是一些微不足道的问题,虽然我已经找到了解决方案,但我仍然不明白为什么会出现这个问题。

这是磨我齿轮的代码片段:

(defn print-and-save-selection
  [info tab]
  (let [selection-text (.-selectionText info)]
    (println info) ;; => #js { bunch of properties, "selectionText" being one }
    (.get js/chrome.storage.sync
          (clj->js {:history nil :historyItems []})
          (fn [items]
            (println items)  ;; => #js {:history nil :historyItems #js []}
            (let [history-items (.-historyItems items)
                  updated-history-items (.concat history-items selection-text)]
              (println updated-history-items)  ;; => correct list in :whitespace mode
              ;; save stuff using other chrome.storage function

我正确设置了我的 externs,此代码在 :whitespace 优化下正常工作,但在 :advanced 下不能正常工作。对于后者,它给了我一个"Cannot read property 'concat' of undefined"。换句话说,(.-historyItems) 无法在 items 中找到合适的元素。如果我将其更改为 (aget items "historyItems"),即使在 :advanced 中,它也能正常工作。

我无法理解的是,为什么适用于 (.-selectionText info)(第三行)的功能不适用于 (.-historyItems items),当它们都访问 属性一个 JavaScript 对象。这可能与这段代码的嵌套程度有关?

为了完整性,生成的代码是这样的:

:没有aget的高级

var a = b.selectionText;
...
// a few nested returns and functions ...
    var h = g.Ab, c = h.concat(a);  // => error mentioned above

:高级aget

var a = b.selectionText;
...
// a few nested returns and functions ...
    var h = g.historyItems, c = h.concat(a);

确实是小事

原来selectionText 属性是在externs文件中定义的,而historyItems是我在chrome的存储中设置的。因此,相同风格的代码会导致不同的行为。

结论:真正重要的是外部文件中定义的内容。