什么是ClojureScript模拟设置一个对象值,该值在JavaScript中不存在?

时间:2016-04-26 12:59:37

标签: javascript clojurescript

我使用该模式看到了很多代码:

if (typeof a.b === 'undefined') {
  a.b = null;

现在我将其翻译为:

(if (not (exists (.-b a)))
  (aset a b nil)

但我觉得我应该这样做:

(if (not (exists (.-b a)))
  (aset a b (clj->js {}))

(因为编译器可能在前一种情况下完全消除该步骤)。

这是否恰当 - 或者我是否丢失了一些关键数据?

我的问题是:在JavaScript中设置一个不存在的对象值的ClojureScript模拟是什么?

1 个答案:

答案 0 :(得分:1)

首先,如果尝试模仿某些JavaScript,我建议使用:repl-verbose选项,因为它可以很容易地在REPL上尝试变体并立即看到生成的JavaScript。

如果您想完全模仿您的代码,那么set!就可以解决问题:

(when (not (exists? (.-b js/a)))
  (set! (.-b js/a) nil))

产生

((!(typeof a.b !== 'undefined'))?a.b = null:null)

但是(也许这与编译器行为引起的关注相同),为避免在Closure优化期间重命名(请参阅this SO),agetaset可用于基于字符串的索引:

(when (not (exists? (aget js/a "b")))
  (aset js/a "b" nil))

((!(typeof (a["b"]) !== 'undefined'))?(a["b"] = null):null)