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.

Reply via email to