Yeah, I've grokked it now. I did not appreciate the subtleties of
boxing w.r.t. typeof. My intuition was that a boxed numeric was
nevertheless a "number"; the fact that strings are apparently themselves
boxed and yield a typeof of "object" confused things further for me (I'd
never think of strings as primitives...certainly, they're not, at least
not in the way numbers can be).
Anyway, so carpet-bombing the methods I'm installing on JS native
prototypes with `(.valueOf this)` is the real fix, though it seems
error-prone and wasteful since this treatment should probably be applied
anywhere a value escapes from a prototype method.
Rhetorically, I'd wonder:
1. If there's something ClojureScript should be doing w.r.t. protocol
dispatch to make this less thorny, though I'm aware that any "solution"
would probably carry a performance penalty…
2. If this might not be an ideal context for some static analysis to
warn when a boxed value may be headed into a protocol method invocation…
Thanks all for the hints and help,
- Chas
On 12/17/2013 10:45 AM, Francis Avila wrote:
The behavior you are seeing is due to javascript auto-boxing the primitive types. number, string,
etc are not objects and have no properties to call. When the js runtime sees you look up a
"property" of a non-object type it boxes the value with the appropriate object (Number
for number, String for string, etc) before doing protocol lookup. The "this" value you
are seeing is the box, which is why its typeof is object.
You can retrieve the unboxed value from the box using this.valueOf()
On Tuesday, December 17, 2013 7:57:12 AM UTC-6, Chas Emerick wrote:
As much as I distrust goog.typeOf, this isn't its fault. It's really
quite bizarre: AFAICT, typeof (i.e. the JavaScript operator, not the
goog.typeOf function) returns "object" for any value named by `this`:
typeof 5
"number"
Number.prototype.foo = function () { return typeof this; };
[object Function]
(5).foo()
"object"
This is a whole new level of JavaScript wat for me. I've asked the SO
hordes for insight:
http://stackoverflow.com/questions/20636028/typeof-returns-object-for-this-number-elsewhere
Meanwhile, I've discovered that extending the protocol to both `number`
and `js/Number` does work under both execution contexts, a much more
palatable workaround. That's allowed me to move forward with my
current work.
Thanks,
- Chas
On Tue 17 Dec 2013 04:37:56 AM EST, Thomas Heller wrote:
FWIW I had some troubles with native types before, mine were related to IE
though. The culprit for your troubles is goog.typeOf (which is a basic wrapper
arrount js/typeof).
If you run this via phantomjs
-----
console.log("typeof", typeof(5));
Number.prototype.foo = function() {
console.log("typeof prototype", typeof(this));
};
(5).foo();
phantom.exit(0);
-----
You get
typeof number
typeof prototype object
Pretty sure the problem goes away cause in advanced compilation cause it gets
inlined and (.foo 5) is turned into (m 5) skipping the step with this. Just a
guess though.
HTH,
/thomas
--
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/clojurescript.