Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling JavaScript object property as a constructor from ClojureScript

I am using a JavaScript library that exposes a constructor as a property of a global object.

In JavaScript, I can call the constructor like this.

var thing = new Library.Thing();

How do I call the constructor in ClojureScript? None of these work.

; 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_);

It works fine if I use js* but that's cheating, right?

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

What is the proper way to call a constructor function that is a property of another object?

like image 348
Josh Headapohl Avatar asked Oct 23 '13 04:10

Josh Headapohl


People also ask

How do you call a constructor in JavaScript?

A constructor is a special function that creates and initializes an object instance of a class. In JavaScript, a constructor gets called when an object is created using the new keyword. The purpose of a constructor is to create a new object and set values for any existing object properties.

What is constructor property in JavaScript?

The constructor property returns a reference to the Object constructor function that created the instance object. Note that the value of this property is a reference to the function itself, not a string containing the function's name. The value is only read-only for primitive values such as 1 , true , and "test" .

Can you call a method in a constructor JavaScript?

Yes, it is possible, when your constructor function executes, the this value has already the [[Prototype]] internal property pointing to the ValidateFields.

What is object constructor in JavaScript?

The Object constructor turns the input into an object. Its behavior depends on the input's type. If the value is null or undefined , it will create and return an empty object. Otherwise, it will return an object of a Type that corresponds to the given value. If the value is an object already, it will return the value.


1 Answers

If you look at http://himera.herokuapp.com/synonym.html you can find the specific syntax to instantiate objets in clojurescript.

I wrote this js mock library based in this documentation to make a test:

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());

Then from clojurescript you have to use the dot syntax (but prefixing with "js/" your js global type):

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

I don't mention in this answer the :externs property of your cljsbuild compilation beacuse I understand that you are including your js script library directly in your html head document. So, if this line works for you (js* "new Library.Thing()") it'll mean that the js library is available from the cljs-js-compiled.
Anyway, I left an "alert" in the js mock library to check that the file is correctly loaded

I hope it works for you
Juan

like image 200
tangrammer Avatar answered Oct 07 '22 17:10

tangrammer