Under the hood of, JavaScript's Type Conversion

Under the hood of, JavaScript's Type Conversion

TLDR : This post discusses type conversion, wrapper objects, which seem to behave like primitive values but are actually objects. And later on the internals of the conversion rules followed by the language. Let's go through it carefully. Explicit Type Conversion JavaScript provides three functions for converting values explicitly.These return primitive values, not objects. 1. Number(value) 2. String(value) 3. Boolean(value) Enter fullscreen mode Exit fullscreen mode Example: Number("3") // 3 String(false) // "false" Boolean([]) // true Enter fullscreen mode Exit fullscreen mode Number() : Converts a value to a number. Number("42") // 42 Number(true) // 1 Number(false) // 0 Number(null) // 0 Number(undefined) // NaN Number("abc") // NaN Enter fullscreen mode Exit fullscreen mode String() : Converts a value to a string. String(42) // "42" String(true) // "true" String(null) // "null" String(undefined) // "undefined" Enter fullscreen mode Exit fullscreen mode Boolean() : Converts a value to a boolean. Boolean([]) // true Boolean({}) // true Boolean("0") // true Boolean("false") // true Enter fullscreen mode Exit fullscreen mode A special behaviour of boolean related to objects will be explained later. Comparison with Number & String wrapper new Number(5) === 5 //false new String(0) === String(0) //false // because left side is an object; right side is a primitive Enter fullscreen mode Exit fullscreen mode Comparison with Boolean wrapper new Boolean(true) new Number(10) new String("abc") // These return objects. typeof new Boolean(false) // object Enter fullscreen mode Exit fullscreen mode plaintext So if you do const isFalse = Boolean(0) // false if(isFalse) // false vs. const isFalse = new Boolean(0) // {false} if(isFalse) // true Enter fullscreen mode Exit fullscreen mode plaintext Why do the wrapper objects even exist? because in the early days, Js wanted the primitives to have methods. To fulfill this requirement, the language had wrappers. In modern JavaScript, primitives can't have methods. So, the engine optimizes this. Why Should you not use new String(), new Number() OR new Boolean()? const isFalsePrimitive = Boolean(0) ; const isFalseObject = new Boolean(0); if(isFalsePrimitive) //false if(isFalseObject) // true Enter fullscreen mode Exit fullscreen mode plaintext Special Behaviour of Boolean Because all objects are truthy, regardless of the value they wrap. if([]) //true ; arrays are also objects in Js if({}) //true Enter fullscreen mode Exit fullscreen mode plaintext So, try not to use it and avoid confusion. Now, Moving to the Kryptonite of all the confusion built around conversion. Explicit Conversions: Object to Primitive(Number, Boolean, String) TLDR: During type coercion/conversion, the Js Engine asks itself in heart, I need a primitive value, which primitive (string, number, bigint, symbol, boolean) should I use? The Js engine has 3 options to choose from, which are: 1. should I convert it to string? // uses .toString() 2. should I convert it to number? // uses .valueOf() 3. Either string or number is acceptable. //when it can't convert // return TypeError Enter fullscreen mode Exit fullscreen mode javascript Steps for conversion Before it is decided whether to convert to string first or not. The engine analyzes based on the "hint" given in the statement. For example: // 1. here the hint is '' to convert to string ''+10 //'10' // 2. here the hint is Number() Number('123') + 10 // 133 Second step is to analyze and see after using toString() OR valueOf() the result is a primitive or not. For example: // 1. Needs primitive type number >> use valueOf(), if // typeof result === number // then return result, else use toString() and return it Number({}) // final result NaN -->> converts to '[object Object]' because -->> valueOf() conversion return {} which is not a number; so toString() prevails and gives -->> '[object Object]' which is string(primitive) -->> Number('[object Object]') is NaN // here hint is + {} + '' Parser sees: {} // empty block +'' // Unary plus Number("") // gives numeric 0 For Boolean, the engine only checks if the typeof argument === object, if yes returns true. For Dates, the default preference is to return a String Number(Date()) // 1789546456464 milli seconds String(Date()) // Tue Jul 14... forced string conversion Console.log(Date()) // Tue Jul 14... default The Diagram Need Primitive │ ▼ Which Hint? ──────────────────────────── String? │ ▼ toString() │ Primitive? │ │ Yes No │ ▼ Return valueOf() │ Primitive? │ │ Yes No │ ▼ Return TypeError Enter fullscreen mode Exit fullscreen mode Next article will be based around the miscellaneous feaures of var vs let vs const keywords.

Original Source

Read the full article at Dev →

KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.