6

In JavaScript, primitive types (number, string, etc.) are not objects. So, they don't have a [[prototype]] so can't use methods available in the [[prototype]] of some Objects.

Whereas Number, String are wrapper objects and can be used to create variables with the new keyword and we can use methods available in the prototype of the Number Object on those variables (created with the new keyword).

But in the given code, I created a primitive type variable and am able to use methods like toFixed() which resides in the Number Object.

This is confusing to me. Please elaborate on this.

let a = 6.678; //primitive type

a= a.toFixed(1); // toFixed() resides in prototype of Number Object

console.log(a); // 6.7
Boann
  • 48,794
  • 16
  • 117
  • 146
BitandDust
  • 63
  • 5

3 Answers3

4

This has to do with something with a concept called "Autoboxing", Javascript sees that you're trying to access a property on the primitive type and hence for a very brief moment at runtime, it converts the primitive value to its corresponding Wrapper object and proceeds with the property call, it then converts the value back to primitive type in most of the cases.

let a = 6.678; //primitive type

a= a.toFixed(1); // JS converts a to "Number Object" and then the function is called

console.log(a); // 6.7

Here's a very good answer to it Does javascript autobox?

Sudhanshu Kumar
  • 1,926
  • 1
  • 9
  • 21
1

This is how the JavaScript engine works more or less. You're correct that the variable you've assigned to a is a primitive of Number type, but when you access a method on this primitive value, JS will create a special wrapper object (it will do this for each primitive type, i.e. strings) and gives it access to those methods.

The value will no longer be an object after you've accessed the method.

You can read more about it here: https://javascript.info/primitives-methods#a-primitive-as-an-object

@ashu's answer below includes the technical term which I wasn't actually aware of - so TIL! Apparently, this is called "Autoboxing"!

Sherman Hui
  • 938
  • 3
  • 10
  • 22
0

We are able to perform toFixed() operation due to thisNumberValue abstract operation, which checks Type(value) is Number return the value else if Type(value) is Object and value has a [[NumberData]] internal slot, then let n be value and assign Type[n] is Number. Return the value else Throws a TypeError exception.

According to ECMAScript® 2020 Language Specification

Number.prototype.toFixed ( fractionDigits )

toFixed returns a String containing this Number value represented in decimal fixed-point notation with fractionDigits digits after the decimal point. If fractionDigits is undefined, 0 is assumed.

The following steps are performed when perform toFixed() operation:

  1. Let x be ? thisNumberValue(this value).

NOTE The abstract operation thisNumberValue(value) performs the following steps:

  • If Type(value) is Number, return value.

  • If Type(value) is Object and value has a [[NumberData]] internal slot, then

    • Let n be value.[[NumberData]].
    • Assert: Type(n) is Number.
    • Return n.
  • Throw a TypeError exception.

  1. Let f be ? ToInteger(fractionDigits).

    NOTE The abstract operation ToInteger converts argument to an integral numeric value. This abstract operation functions as follows:
  • Let number be ? ToNumber(argument). (Note ToNumber is also an abstract operation)
  • If number is NaN, return +0.
  • If number is +0, -0, +∞, or -∞, return number.
  • Return the number value that is the same sign as number and whose magnitude is floor(abs(number)).
  1. Assert: If fractionDigits is undefined, then f is 0.
Apratim
  • 204
  • 2
  • 9