38
loading...
This website collects cookies to deliver better user experience
Type coerion is changing type from X to Y - Me
console.log(Number('abc')) // NaN
console.log(Number({ x: 1, y: 2 })) // NaN
console.log(Number([1, 2, 3, 4])) // NaN
console.log(Number('5')) // 5
console.log(Number(true)) // 1
console.log(Number({}))
?let user = {
username: 'ahmedosama-st',
repos: [
{
id: 1,
title: 'php-mvc-project',
stars: 10,
},
{
id: 2,
title: 'filemarket',
stars: 5,
},
],
}
let userStars = Number(user) // returns NaN for sure.
user
object to be the sum of all it's repos' stars?valueOf
function in any object and it will be automatically invoked if you're trying to numerify the object.let user = {
username: 'ahmedosama-st',
repos: [
{
id: 1,
title: 'php-mvc-project',
stars: 10,
},
{
id: 2,
title: 'filemarket',
stars: 5,
},
],
valueOf() {
return this.repos
.map((repo) => repo.stars)
.reduce((x, y) => x + y)
},
}
console.log(Number(user)) // 15
let user = {
username: 'ahmedosama-st',
repos: [
{
id: 1,
title: 'php-mvc-project',
stars: 10,
},
{
id: 2,
title: 'filemarket',
stars: 5,
},
],
totalRepoStars() {
return this.repos
.map((repo) => repo.stars)
.reduce((x, y) => x + y)
},
}
console.log(Number(user)) // NaN as it should be
console.log(user.totalRepoStars) // 15
Falsy values |
---|
zeros / 0, -0 |
empty string / "", '' |
null |
NaN |
undefined |
false |
Boolean(new Boolean(false)) // ??
Boolean
means coerce the given input to a boolean type.[Object object]
like wtf? I know it's an object yo.let user = {
username: 'ahmedosama_st',
website: 'https://ahmedosama-st.github.io/codefolio/',
skills: [
{
skill_name: 'php',
years_of_experience: 5,
favourite_frameworks: ['laravel', 'symfony', 'lumen'],
},
{
skill_name: 'javascript',
years_of_experience: 2,
favourite_frameworks: [
'react.js',
'nest.js',
'vue.js',
],
},
],
toString() {
// return JSON.stringify(this, null, 2)
// but I'd use util as it has coloring
return require('util').inspect(this, false, null, true)
},
}
ToPrimitive
operation is meant to coerce objects to other types, you can control how it behaves to even coerce to another non-primitive type, but c'mon, what are you thinking?ToPrimtive
operation is invoked, and the desired type is passed as an argument called hint
, and the coercee -if that's a word- is passed as input
input
is an object, them some further steps will be done, otherwise return it untouched.hint
is number
the valueOf
operation will be triggered first if existed, otherwise it'll return NaN
, and by similarity, if you're coercing it into a string, if a custom implementation of toString
is provided, it'll be invoked, otherwise, it'll fall back to the default behaviour and return [Object object]
let user = {
username: 'ahmedosama-st',
posts: [
{
id: 1,
title: 'Exploring the V8 engine',
url: 'example.com',
},
],
[Symbol.toPrimitive](hint) {
if (hint == 'string') {
return require('util').inspect(
this,
false,
null,
true,
)
} else if (hint == 'number') {
return this.posts.length
}
},
}
console.log(String(user)) // {username: 'ahmedosama', posts: [...], ...}
console.log(Number(user)) // 1
Boolean(user)
it will not behave as you expect, it will fall back to the truthy/falsy table to check whether if this value if in the falsy table or not.ToPrimitive
is defined by a Symbol
as a function, or a special function if you will, so you can invoke it this way and pass manual type as a hint and handle it within the function's body, but once more, please don't do so, it's complete nonsense.let user = {
username: 'ahmedosama-st',
posts: [
{
id: 1,
title: 'Exploring the V8 engine',
url: 'example.com',
},
],
[Symbol.toPrimitive](hint) {
if (hint == 'array') {
return this.posts
}
},
}
// Note, that you have to call it yourself.
console.log(user[Symbol.toPrimitive]('array'))
posts
array, but once again, wtf are you thinking?Number('') // 0
0
Number(' \t\t\n') // 0
Number(null) // 0
null
represents the empty object or the absence of an object, zero isn't the right thing for that.Number(null) // returns 0, sooo...
0 == null // sorry, false..
null == '' // again, false
null >= 0 // true FFS!!!
null >= '' // true, and here is where you quit JS
null <= '' // true, and now you're quite certain JS is fucked up
Number(undefined) // NaN
Number([]) // 0
/* Intended */
Number([])
/* Goes through */
Number(String([]))
// or for simplification
let x = String([]) // ""
Number(x) // 0
Number([null]) // 0
Number([undefined]) // 0
Number([null])
Number(String([null]))
String([null])
returns? Yup, the empty string.String([1,2,3])
returns "1,2,3"
and if it happened that an array has either null
or undefined
it will be represented by empty spot like that String([1, 2, null, 4])
becomes "1,2,,4"
the position of null is empty and that's completely nonsense, and what's more nonsensical, that String([null])
becomes empty string, like not even a comma floating around so it becomes NaN.function sort(a, b) {
if (!isAcceptableType(a) || !isAcceptableType(b)) return
// Perform my algorithm if they're acceptable.
function isAcceptableType(value) {
return ['string', 'number'].includes(typeof value)
}
}