Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Boolean primitive not call prototype toString()?

Say I have this code:

Boolean.prototype.toString = function toString() {
  return this.valueOf() ? '1' : '0';
};

var object = {
  true: 'true',
  false: 'false',
  1: '1',
  0: '0'
};

// "true" - this doesn't work
console.log('primitive', object[true]);
// "1" - but these do
console.log('primitive.toString()', object[true.toString()]);
console.log('instance', object[new Boolean(true)]);

Why doesn't the primitive use the class's toString definition? Object keys are either strings or symbols, they cannot just be raw booleans. This is why I'm confused.

like image 338
Patrick Roberts Avatar asked Jun 06 '16 13:06

Patrick Roberts


People also ask

What does toString () do in JavaScript?

toString . For user-defined Function objects, the toString method returns a string containing the source text segment which was used to define the function. JavaScript calls the toString method automatically when a Function is to be represented as a text value, e.g. when a function is concatenated with a string.

How many parameters are required in the toString () method in JavaScript?

Parameters. An integer in the range 2 through 36 specifying the base to use for representing numeric values.

How do I Stringify a Boolean?

To convert a Boolean value to string value in JavaScript, use the toString() method. This method returns a string of either "true" or "false" depending upon the value of the object.


2 Answers

Because the specifications says so. http://www.ecma-international.org/ecma-262/6.0/index.html#sec-tostring In this table the String values of primitives are defined. Only for Objects ToPrimitive is used.


The table tells us thatToString for an Object o is ToString( ToPrimitive(o, "string"))

The Specification tells us that if ToPrimitive is called with an Object we have to follow these steps:

1. If PreferredType was not passed, let hint be "default".
2. Else if PreferredType is hint String, let hint be "string".
3. Else PreferredType is hint Number, let hint be "number".
4. Let exoticToPrim be GetMethod(input, @@toPrimitive).
5. ReturnIfAbrupt(exoticToPrim).
6. If exoticToPrim is not undefined, then
  a. Let result be Call(exoticToPrim, input, «hint»).
  b. ReturnIfAbrupt(result).
  c. If Type(result) is not Object, return result.
  d. Throw a TypeError exception.
7. If hint is "default", let hint be "number".
8. Return OrdinaryToPrimitive(input,hint).

@@toPrimitive beeing set is a special case so we now have to look at OrdinaryToPrimitive

1. Assert: Type(O) is Object
2. Assert: Type(hint) is String and its value is either "string" or "number".
3. If hint is "string", then
  a. Let methodNames be «"toString", "valueOf"».
4. Else,
  a. Let methodNames be «"valueOf", "toString"».
5. For each name in methodNames in List order, do
  a. Let method be Get(O, name).
  b. ReturnIfAbrupt(method).
  c. If IsCallable(method) is true, then
    i. Let result be Call(method, O).
    ii. ReturnIfAbrupt(result).
    iii. If Type(result) is not Object, return result.
6. Throw a TypeError exception.

So this means that the return value of ToPrimitive(o, "string") is o.toString() and toString(o.toString()) is the same as o.toString().

like image 62
Till Arnold Avatar answered Sep 28 '22 23:09

Till Arnold


  • "true" is a boolean.
  • A "Boolean" instance is an object, not a boolean.
  • So the instance is not obliged to use the prototype.
  • "Boolean" object is just an abstraction in js for using boolean type.

Boolean.prototype.toString=function toString(){
  return this?'1':'0';
};

var object = {
  'true':'true',
  'false':'false',
  '1':'1',
  '0':'0'
};

console.log('primitive', object[true]);
console.log('instance', object[new Boolean(true)]);
console.log('bool type:', typeof(true));
console.log('Boolean type:', typeof(new Boolean(true)));
like image 29
David Diez Avatar answered Sep 28 '22 23:09

David Diez