Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Boolean.prototype.toString() unexpected results

Working through Mozilla's Javascript Reference using my browser console. Looking at Boolean objects. I've come across an unexpected behaviour with the following method:

Boolean.prototype.toString() Returns a string of either "true" or "false" depending upon the value of the object. Overrides the Object.prototype.toString() method

If I instantiate a boolean true or false they both return the same "false" from this method:

var t = Boolean(true);
var f = Boolean(false);

Boolean.prototype.toString(t);
> "false"
Boolean.prototype.toString(f);
> "false"

I understand I can more reliably query the object with:

Boolean.prototype.constructor(t);
> true
Boolean.prototype.constructor(f);
> false

So what I'm asking is: can anyone explain, preferably with examples, why Boolean.prototype.toString(true) returns false?

Is there a inheritance issue, or is it a bug? Am I not getting something? I've tested this with Boolean Object wrappers, Boolean literals and expressions. I've reproduced this behavior on three browsers on Mac, is this a platform issue? Any help understanding this behaviour would be gratefully received.

like image 638
Tony Cronin Avatar asked Mar 20 '23 03:03

Tony Cronin


1 Answers

Whatever's on Boolean.prototype gets passed along to all booleans. That means that true.toString === Boolean.prototype.toString, and doing true.toString() is like doing Boolean.prototype.toString.call(true).

When you call Boolean.prototype.toString directly, this === Boolean.prototype. Looking at the spec, we can see that it attempts to do a conversion in case you get a Boolean object (remember, Boolean.prototype is quite literally the prototype of every boolean - it's a boolean object):

  1. Else if Type(B) is Object and the value of the [[Class]] internal property of B is "Boolean", then let b be the value of the [[PrimitiveValue]] internal property of B.

[[PrimitiveValue]] is essentially a valueOf call:

Boolean.prototype.valueOf(); //false

And Boolean.prototype is defined in the spec (15.6.4) to be the Boolean object false.

In summation, what happened here is that instead of trying to call toString on the variable you intended, you instead called it on Boolean.prototype, which produces the same result every time.

Solution: Don't do that. Call toString on the variables: t.toString(), f.toString()

N.B. You don't need Boolean(true) or the likes; just true will do.

like image 62
Zirak Avatar answered Apr 25 '23 22:04

Zirak