问题 从ClojureScript调用JavaScript对象属性作为构造函数


我正在使用一个JavaScript库,它将构造函数公开为全局对象的属性。

在JavaScript中,我可以像这样调用构造函数。

var thing = new Library.Thing();

如何在ClojureScript中调用构造函数?这些都不起作用。

; These all cause compiler errors
(new (.-Thing js/Library)) ; First arg to new must be a symbol
(new (.Thing js/Library))
(new .-Thing js/Library)
(new .Thing js/Library)
(new js/Library/Thing)     ; Invalid token: js/Library/Thing

; These all compile to different JS than I am looking for
((.-Thing js/Library).) ; Library.Thing.call(null, _SLASH_);
((.Thing js/Library).)  ; Library.Thing().call(null, _SLASH_);

如果我使用js *它可以正常工作,但这是作弊,对吧?

(js* "new Library.Thing()")

调用构造函数是另一个对象属性的正确方法是什么?


12200
2017-10-23 04:03


起源



答案:


如果你看看 http://himera.herokuapp.com/synonym.html 你可以找到在clojurescript中实例化objets的特定语法。

我在本文档中编写了这个js模拟库来进行测试:

function Person(name) {
this.name = name;
}

Person.prototype.greet = function() {
return "Hello, " + this.name;
};


var f={
"hola":"hola juan",

Person:Person

};

var person=new f.Person("Juan");
alert(person.greet());

然后从clojurescript你必须使用点语法(但前缀为“js /”你的js全局类型):

(let [Person (.-Person js/f)
        juan (Person. "Juan")
        ]
    (.log js/console  (.greet juan)))

我在这个答案中没有提到:你的cljsbuild编译的externs属性,因为我知道你直接在你的html头文档中包含你的js脚本库。所以,如果这条线适合你 (js* "new Library.Thing()") 这意味着js库可以从cljs-js编译中获得。
无论如何,我在js mock库中留下了一个“alert”来检查文件是否正确加载

我希望这个对你有用
胡安


11
2017-10-23 08:02



换句话说,如果我先将构造函数绑定到本地,我可以调用它。 (let [Thing (.-Thing js/Library)] (new Thing)) 工作得很好,就像 (let [Thing (.-Thing js/Library)] (Thing.))你对直接包含在文档中的脚本是正确的。 - Josh Headapohl
嗨Josh,你对本地构造函数绑定是正确的。点js构造函数“。”是一个非常奇怪的行为。只是意识到你可以使用这个“。”来调用正常的函数。 (defn -log [message] (.log js/console message) ) (-log. "Hello Josh") - tangrammer


答案:


如果你看看 http://himera.herokuapp.com/synonym.html 你可以找到在clojurescript中实例化objets的特定语法。

我在本文档中编写了这个js模拟库来进行测试:

function Person(name) {
this.name = name;
}

Person.prototype.greet = function() {
return "Hello, " + this.name;
};


var f={
"hola":"hola juan",

Person:Person

};

var person=new f.Person("Juan");
alert(person.greet());

然后从clojurescript你必须使用点语法(但前缀为“js /”你的js全局类型):

(let [Person (.-Person js/f)
        juan (Person. "Juan")
        ]
    (.log js/console  (.greet juan)))

我在这个答案中没有提到:你的cljsbuild编译的externs属性,因为我知道你直接在你的html头文档中包含你的js脚本库。所以,如果这条线适合你 (js* "new Library.Thing()") 这意味着js库可以从cljs-js编译中获得。
无论如何,我在js mock库中留下了一个“alert”来检查文件是否正确加载

我希望这个对你有用
胡安


11
2017-10-23 08:02



换句话说,如果我先将构造函数绑定到本地,我可以调用它。 (let [Thing (.-Thing js/Library)] (new Thing)) 工作得很好,就像 (let [Thing (.-Thing js/Library)] (Thing.))你对直接包含在文档中的脚本是正确的。 - Josh Headapohl
嗨Josh,你对本地构造函数绑定是正确的。点js构造函数“。”是一个非常奇怪的行为。只是意识到你可以使用这个“。”来调用正常的函数。 (defn -log [message] (.log js/console message) ) (-log. "Hello Josh") - tangrammer