WARNING: Extending an existing JavaScript type - use a different symbol name instead of js/Function
I'm trying to create a function that is polymorphic based on the input type (could be a function, map or vector) and I thought protocols were the best way to do that. Should I instead create a multimethod that dispatches on (type arg)?
Thanks!
-Scott
--
Note that posts from new members are moderated - please be patient with your first post.
---
You received this message because you are subscribed to the Google Groups "ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojurescrip...@googlegroups.com.
To post to this group, send email to clojur...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.
(extend-protocol Foo
js/Function
(foo [arg]
(println arg)))
You can extend "function" (and "object", "number", "string", "array", and "boolean") instead of js/Function (or js/Object, etc). This will implement the protocol from the "outside" (doing type checks on its argument) instead of assigning a new member to the global's prototype. E.g.:
(extend-protocol Foo
function
(foo [this] (println this)))
I'm not sure if you also need to extend IFn: I think "function" means only native js functions and not clojurescript objects implementing IFn. (Test with a multi-arity cljs function to verify.)
You can also extend the "default" type, which means everything will implement the protocol that doesn't have a more specific implementation.
I don't know where these magic protocol type names are documented.
Thanks again!
-Scott
Just added some documentation to the `extend-type` doc:
https://github.com/cljsinfo/cljs-api-docs/blob/catalog/refs/cljs.core_extend-type.md
Francis,
Do you have an ide yhy the implementation of `extend-type` for:
1. js types modifies the js type itself
2. while for cljs types it modifies the protocol (from the outside)?
Not sure why though
Number.prototype.whatAmI = function() { return typeof(this); };
var x = 1;
x.whatAmI();
"object"
typeof(x)
"number"
Fun times debugging that ...
Cheers,
/thomas
> The point I wanted to make is 'this' without 'new' will refer to the object the function is defined on be it 'window' or whatever object.
>
That is incorrect. "this" is the actual number, not window. new or not. Behavior is probably different for other types. ;)
Number.prototype.addFive = function() { return this + 5 };
var x = 1;
x.addFive(); => 6
var x = new Number(3)
x.addFive(); => 8
Anyways, we agree that JS is full of WTF. Let's enjoy our sweet sweet CLJS world. :)
Cheers,
/thomas
Cheers,
/thomas
Take the equivalent from Java:
class MyClass {
}
MyClass x = new MyClass();
Class y = MyClass.class;
or JS:
var MyClass = function() { /* ctor */ };
var inst = new MyClass()
inst != MyClass
inst.prototype == MyClass
inst is an instance of MyClass (prototype) but not equal to MyClass.
What is going on with Numbers is related to boxing, so there is a perfectly fine explanation but that doesn't make it less confusing when you first encounter it.
Enough of this, back to topic. Don't extend Native types. ;)
/thomas
/thomas