{
"$type": "site.standard.document",
"content": "Every single programming language is designed to be intuitive and Javascript is no exception, but it does have some crazy quirks that make it stand out, one of which is its weird behavior with types and I am pretty sure you have seen the memes.\r\n\r\n<img alt=\"javascript meme\" src=\"https://thepracticaldev.s3.amazonaws.com/i/a2k7x6ghilt6hp5mhgd7.png\" height=\"400\" width=\"400\"/>\r\n\r\nThis can be traumatizing the first time you see it but it does not have to be, so I want to shed a little light on it and help you avoid running into such.\r\n\r\n## How Javascript types work\r\n\r\nJavascript is a very very loosely typed language, this is not bad at all but in some situations, it can cause very bad head scratching. One of these moments occurred when I first saw this a few years back.\r\n\r\n```js\r\ntrue + true === 2 // => true\r\n\r\ntrue !== 1 // => true\r\n```\r\n\r\nAt first glance, it looks very *wrong* but don't fret there is nothing wrong here, that is just how javascript works. Javascript handles types in a very different way, it has only 6 primitive types and all the code you write is represented by one of them.\r\n\r\n- `boolean`\r\n\r\n- `number`\r\n\r\n- `string`\r\n\r\n- `object`\r\n\r\n- `function`\r\n\r\n- `undefined`\r\n\r\nThis alone is not enough to cause such strange behavior but the way they are handled does, javascript always converts types to best fit what they are being used for, this is called **Type Coercion** and sometimes it changes value types to those not intended by the developer, this is why `true + true === 2`.\r\n\r\nThe binary `+` operator is primarily meant to add numbers but when it is faced with boolean values it's forced to convert them to numbers thus `true` becomes `1` which makes `true + true` become `1 + 1` and the expression is turned into\r\n\r\n```js\r\n1 + 1 === 2 // => true\r\n```\r\n\r\nBut the second expression `true !== 1` seems to defeat what I just explained above but it really makes perfect sense too. The `!==` operator performs a strict comparison so it checks both value and type but since `true` is a boolean and `1` is a number they are not strictly equal thus the expression is true.\r\n\r\n## Truthy and Falsy\r\n\r\nEvery value in javascript has its own boolean value (truthy/falsy), these values are used in operations where a boolean is expected but not given, you have most likely used this feature before but never knew what was going under the hood. \r\n\r\nExample:\r\n\r\n```js\r\nconst array = [];\r\n\r\nif(array){\r\n console.log('Truthy!');\r\n}\r\n```\r\n\r\nIn the code above, `array` is not a boolean but because the value is \"truthy\", the if block will be executed.\r\n\r\n#### Falsy vs `false`\r\n\r\nFalsy values are values with an inherent boolean `false`, the following are falsy values.\r\n\r\n- 0\r\n- '' or \"\"\r\n- null\r\n- undefined\r\n- NaN\r\n\r\nExample:\r\n\r\n```js\r\nconst zero = 0;\r\nconst emptyString = \"\";\r\n\r\nif(!zero){\r\n console.log(\"0 is falsy\");\r\n}\r\n\r\nif(!emptyString){\r\n console.log(\"An empty string is falsy\")\r\n}\r\n\r\nconsole.log(NaN || 1); // => 1\r\nconsole.log(null || 1); // => 1\r\nconsole.log(undefined || 1); // => 1\r\n```\r\n\r\nNote that the value `false` is falsy but falsy values are not `false` and the right way to differentiate them is by using **strict comparison** operators.\r\n\r\nExample:\r\n\r\n```js\r\n0 == false // => true\r\n0 === false // => false\r\n```\r\n\r\n#### Truthy vs `true`\r\n\r\nEvery value that is not `falsy` is considered `truthy`, these include\r\n\r\n- strings\r\n\r\n- arrays\r\n\r\n- objects\r\n\r\n- functions\r\n\r\nExample: \r\n\r\n```js\r\nfunction somethingIsWrong(){\r\n console.log(\"Something went horribly wrong\")\r\n}\r\n\r\nfunction callback(){\r\n console.log(\"Hello From Callback\");\r\n}\r\n\r\nconst string = \"Hello world!\"\r\nconst array = [1,2,3];\r\nconst object = {};\r\n\r\nif(string){\r\n console.log(string) // => \"Hello world!\"\r\n const functionToCall = callback || somethingIsWrong\r\n functionToCall() // => \"Hello From Callback\"\r\n console.log(array || \"That was not meant to happen\")\r\n console.log(object || \"This is strange\")\r\n}\r\n```\r\n\r\n## Type coercion\r\n\r\nType coercion is the process of converting one type to another and every value in javascript can be coerced.\r\n\r\nThere two types of coercion:\r\n\r\n- implicit: This is done automatically when the need arises e.g\r\n\r\n\r\n```js\r\n\"0\" + 5 == \"05\" // => true\r\n```\r\n\r\nThe above example shows implicit coercion in its most recognizable form, the `+` operator is not only used to add numbers but strings too so when it is told to add a number to a string it has to convert the number to a string first, which changes `5` to `\"5\"` and the expression becomes.\r\n\r\n```js\r\n\"0\" + \"5\" == \"05\" // => true\r\n```\r\n\r\n- explicit: This is when a developer converts types by writing the appropriate code to do so e.g\r\n\r\n```js\r\n\"0\" + String(5) == \"05\"\r\n```\r\n\r\n## Type conversions\r\n\r\nWhen a value is coerced, it undergoes one of three conversions.\r\n\r\n- ToString: This is triggered implicitly by the `+` operator and explicitly by calling the `String` function e.g\r\n\r\n```js\r\nconst height = 5.8;\r\nconsole.log(\"Hello I am \" + height + \"ft tall\") // => \"Hello I am 5.8ft tall\"\r\n```\r\n\r\nThe `+` operator implicitly converts the floating point number to a string before concatenating them.\r\n\r\n```js\r\nconst height = 5.8;\r\nconsole.log(\"Hello I am \" + String(height) + \"ft tall\") // => \"Hello I am 5.8ft tall\"\r\n```\r\n\r\nHere we use the `String` function to explicitly convert the floating point number to a string.\r\n\r\n- ToBoolean: This is triggered implicitly by either their context or by logical operators (`!`, `||` and `&&`) and explicitly by the `Boolean` function.\r\n\r\n```js\r\nif(3){\r\n console.log(\"Implicitly by context\")\r\n}\r\n\r\nif(Boolean(1)){\r\n console.log(\"Explicitly by the 'Boolean' function\")\r\n}\r\n\r\nconsole.log(!0) // => true\r\n\r\nconsole.log(0 || \"Hello\") // => \"Hello\"\r\n\r\nconsole.log(4 && 5) // => true\r\n```\r\n\r\nNote that the `||` operator does not return the truthy value of `\"Hello\"` but the actual string itself\r\n\r\n- ToNumber: Numeric conversion is very tricky because it is triggered by a lot of operators `> < <= >= | & ^ ~ - + * / % != ==`. Note, that binary `+` does not trigger numeric conversion and `==` does not trigger numeric conversion when both operands are strings.\r\n\r\nThere is a lot more on coercion that I can't explain here, so here is a link to [an excellent post](https://medium.freecodecamp.org/js-type-coercion-explained-27ba3d9a2839) on javascript type coercion.\r\n\r\n## Avoiding this behavior\r\n\r\nThe best way to avoid this behavior is by type checking and an easy way to do this in vanilla javascript is by using a strict equality operator `===` when comparing values or checking a variable's type with the `typeof` keyword.\r\n\r\nExample:\r\n\r\n**without type checking**\r\n```js\r\nconst number = 21;\r\nconst string = \"21\"\r\n\r\nfunction add100(number){\r\n console.log(100 + number)\r\n}\r\n\r\nadd100(number) // => 121\r\nadd100(string) // => \"10021\"\r\n```\r\n\r\n**with type checking**\r\n```js\r\nconst number = 21;\r\nconst string = \"21\"\r\n\r\nfunction add100(number){\r\n if(typeof number == \"number\"){\r\n console.log(100 + number)\r\n } else {\r\n console.log(\"Need a number, not a \"+typeof number);\r\n }\r\n}\r\n\r\nadd100(number) // => 121\r\nadd100(string) // => \"Need a number, not a string\"\r\n```\r\n\r\nUnfortunately, the examples above can not help you with checking classes, for that you need to use the keyword `instanceof`.\r\n\r\n```js\r\nclass ImportantClass {\r\n constructor(){\r\n this.importantValue = 1;\r\n }\r\n\r\n doImportantStuff(){\r\n console.log(this.importantValue);\r\n }\r\n}\r\n\r\nfunction useImportantClass(value){\r\n if(value instanceof ImportantClass){\r\n value.doImportantStuff();\r\n } else {\r\n console.log(\"Value needs to be of type ImportantClass, not \"+typeof value)\r\n }\r\n}\r\n\r\nconst value = new ImportantStuff();\r\n\r\nuseImportantClass(value); // => 1\r\nuseImportantClass(\"Not important\"); // => Value needs to be of type ImportantClass, not string\r\n```\r\n\r\nBut by far the easiest way to avoid this is by using Typescript. If you haven't heard of it, [Typescript](https://www.typescriptlang.org/) is a typed superset of javascript that compiles to normal javascript. In short, Typescript and its compiler help you write code that is very deterministic and I encourage you to click the link if you want to know more because the site explains more than I can.\r\n\r\n## Thanks for reading!!!\r\n\r\n_Consider giving me a follow on [Twitter](https://twitter.com/neutrino2211)_",
"description": "Explaining some weird behavior in javascript and how to avoid it",
"path": "/posts/avoiding-weird-javascript-behaviour-true-true-2-but-true-1-pn9",
"publishedAt": "2019-03-11T19:15:38.000Z",
"site": "https://blog.mainasara.dev",
"tags": [
"javascript",
"nodejs"
],
"textContent": "Every single programming language is designed to be intuitive and Javascript is no exception, but it does have some crazy quirks that make it stand out, one of which is its weird behavior with types and I am pretty sure you have seen the memes.\r\n\r\n<img alt=\"javascript meme\" src=\"https://thepracticaldev.s3.amazonaws.com/i/a2k7x6ghilt6hp5mhgd7.png\" height=\"400\" width=\"400\"/>\r\n\r\nThis can be traumatizing the first time you see it but it does not have to be, so I want to shed a little light on it and help you avoid running into such.\r\n\r\n## How Javascript types work\r\n\r\nJavascript is a very very loosely typed language, this is not bad at all but in some situations, it can cause very bad head scratching. One of these moments occurred when I first saw this a few years back.\r\n\r\n```js\r\ntrue + true === 2 // => true\r\n\r\ntrue !== 1 // => true\r\n```\r\n\r\nAt first glance, it looks very *wrong* but don't fret there is nothing wrong here, that is just how javascript works. Javascript handles types in a very different way, it has only 6 primitive types and all the code you write is represented by one of them.\r\n\r\n- `boolean`\r\n\r\n- `number`\r\n\r\n- `string`\r\n\r\n- `object`\r\n\r\n- `function`\r\n\r\n- `undefined`\r\n\r\nThis alone is not enough to cause such strange behavior but the way they are handled does, javascript always converts types to best fit what they are being used for, this is called **Type Coercion** and sometimes it changes value types to those not intended by the developer, this is why `true + true === 2`.\r\n\r\nThe binary `+` operator is primarily meant to add numbers but when it is faced with boolean values it's forced to convert them to numbers thus `true` becomes `1` which makes `true + true` become `1 + 1` and the expression is turned into\r\n\r\n```js\r\n1 + 1 === 2 // => true\r\n```\r\n\r\nBut the second expression `true !== 1` seems to defeat what I just explained above but it really makes perfect sense too. The `!==` operator performs a strict comparison so it checks both value and type but since `true` is a boolean and `1` is a number they are not strictly equal thus the expression is true.\r\n\r\n## Truthy and Falsy\r\n\r\nEvery value in javascript has its own boolean value (truthy/falsy), these values are used in operations where a boolean is expected but not given, you have most likely used this feature before but never knew what was going under the hood. \r\n\r\nExample:\r\n\r\n```js\r\nconst array = [];\r\n\r\nif(array){\r\n console.log('Truthy!');\r\n}\r\n```\r\n\r\nIn the code above, `array` is not a boolean but because the value is \"truthy\", the if block will be executed.\r\n\r\n#### Falsy vs `false`\r\n\r\nFalsy values are values with an inherent boolean `false`, the following are falsy values.\r\n\r\n- 0\r\n- '' or \"\"\r\n- null\r\n- undefined\r\n- NaN\r\n\r\nExample:\r\n\r\n```js\r\nconst zero = 0;\r\nconst emptyString = \"\";\r\n\r\nif(!zero){\r\n console.log(\"0 is falsy\");\r\n}\r\n\r\nif(!emptyString){\r\n console.log(\"An empty string is falsy\")\r\n}\r\n\r\nconsole.log(NaN || 1); // => 1\r\nconsole.log(null || 1); // => 1\r\nconsole.log(undefined || 1); // => 1\r\n```\r\n\r\nNote that the value `false` is falsy but falsy values are not `false` and the right way to differentiate them is by using **strict comparison** operators.\r\n\r\nExample:\r\n\r\n```js\r\n0 == false // => true\r\n0 === false // => false\r\n```\r\n\r\n#### Truthy vs `true`\r\n\r\nEvery value that is not `falsy` is considered `truthy`, these include\r\n\r\n- strings\r\n\r\n- arrays\r\n\r\n- objects\r\n\r\n- functions\r\n\r\nExample: \r\n\r\n```js\r\nfunction somethingIsWrong(){\r\n console.log(\"Something went horribly wrong\")\r\n}\r\n\r\nfunction callback(){\r\n console.log(\"Hello From Callback\");\r\n}\r\n\r\nconst string = \"Hello world!\"\r\nconst array = [1,2,3];\r\nconst object = {};\r\n\r\nif(string){\r\n console.log(string) // => \"Hello world!\"\r\n const functionToCall = callback || somethingIsWrong\r\n functionToCall() // => \"Hello From Callback\"\r\n console.log(array || \"That was not meant to happen\")\r\n console.log(object || \"This is strange\")\r\n}\r\n```\r\n\r\n## Type coercion\r\n\r\nType coercion is the process of converting one type to another and every value in javascript can be coerced.\r\n\r\nThere two types of coercion:\r\n\r\n- implicit: This is done automatically when the need arises e.g\r\n\r\n\r\n```js\r\n\"0\" + 5 == \"05\" // => true\r\n```\r\n\r\nThe above example shows implicit coercion in its most recognizable form, the `+` operator is not only used to add numbers but strings too so when it is told to add a number to a string it has to convert the number to a string first, which changes `5` to `\"5\"` and the expression becomes.\r\n\r\n```js\r\n\"0\" + \"5\" == \"05\" // => true\r\n```\r\n\r\n- explicit: This is when a developer converts types by writing the appropriate code to do so e.g\r\n\r\n```js\r\n\"0\" + String(5) == \"05\"\r\n```\r\n\r\n## Type conversions\r\n\r\nWhen a value is coerced, it undergoes one of three conversions.\r\n\r\n- ToString: This is triggered implicitly by the `+` operator and explicitly by calling the `String` function e.g\r\n\r\n```js\r\nconst height = 5.8;\r\nconsole.log(\"Hello I am \" + height + \"ft tall\") // => \"Hello I am 5.8ft tall\"\r\n```\r\n\r\nThe `+` operator implicitly converts the floating point number to a string before concatenating them.\r\n\r\n```js\r\nconst height = 5.8;\r\nconsole.log(\"Hello I am \" + String(height) + \"ft tall\") // => \"Hello I am 5.8ft tall\"\r\n```\r\n\r\nHere we use the `String` function to explicitly convert the floating point number to a string.\r\n\r\n- ToBoolean: This is triggered implicitly by either their context or by logical operators (`!`, `||` and `&&`) and explicitly by the `Boolean` function.\r\n\r\n```js\r\nif(3){\r\n console.log(\"Implicitly by context\")\r\n}\r\n\r\nif(Boolean(1)){\r\n console.log(\"Explicitly by the 'Boolean' function\")\r\n}\r\n\r\nconsole.log(!0) // => true\r\n\r\nconsole.log(0 || \"Hello\") // => \"Hello\"\r\n\r\nconsole.log(4 && 5) // => true\r\n```\r\n\r\nNote that the `||` operator does not return the truthy value of `\"Hello\"` but the actual string itself\r\n\r\n- ToNumber: Numeric conversion is very tricky because it is triggered by a lot of operators `> < <= >= | & ^ ~ - + * / % != ==`. Note, that binary `+` does not trigger numeric conversion and `==` does not trigger numeric conversion when both operands are strings.\r\n\r\nThere is a lot more on coercion that I can't explain here, so here is a link to [an excellent post](https://medium.freecodecamp.org/js-type-coercion-explained-27ba3d9a2839) on javascript type coercion.\r\n\r\n## Avoiding this behavior\r\n\r\nThe best way to avoid this behavior is by type checking and an easy way to do this in vanilla javascript is by using a strict equality operator `===` when comparing values or checking a variable's type with the `typeof` keyword.\r\n\r\nExample:\r\n\r\n**without type checking**\r\n```js\r\nconst number = 21;\r\nconst string = \"21\"\r\n\r\nfunction add100(number){\r\n console.log(100 + number)\r\n}\r\n\r\nadd100(number) // => 121\r\nadd100(string) // => \"10021\"\r\n```\r\n\r\n**with type checking**\r\n```js\r\nconst number = 21;\r\nconst string = \"21\"\r\n\r\nfunction add100(number){\r\n if(typeof number == \"number\"){\r\n console.log(100 + number)\r\n } else {\r\n console.log(\"Need a number, not a \"+typeof number);\r\n }\r\n}\r\n\r\nadd100(number) // => 121\r\nadd100(string) // => \"Need a number, not a string\"\r\n```\r\n\r\nUnfortunately, the examples above can not help you with checking classes, for that you need to use the keyword `instanceof`.\r\n\r\n```js\r\nclass ImportantClass {\r\n constructor(){\r\n this.importantValue = 1;\r\n }\r\n\r\n doImportantStuff(){\r\n console.log(this.importantValue);\r\n }\r\n}\r\n\r\nfunction useImportantClass(value){\r\n if(value instanceof ImportantClass){\r\n value.doImportantStuff();\r\n } else {\r\n console.log(\"Value needs to be of type ImportantClass, not \"+typeof value)\r\n }\r\n}\r\n\r\nconst value = new ImportantStuff();\r\n\r\nuseImportantClass(value); // => 1\r\nuseImportantClass(\"Not important\"); // => Value needs to be of type ImportantClass, not string\r\n```\r\n\r\nBut by far the easiest way to avoid this is by using Typescript. If you haven't heard of it, [Typescript](https://www.typescriptlang.org/) is a typed superset of javascript that compiles to normal javascript. In short, Typescript and its compiler help you write code that is very deterministic and I encourage you to click the link if you want to know more because the site explains more than I can.\r\n\r\n## Thanks for reading!!!\r\n\r\n_Consider giving me a follow on [Twitter](https://twitter.com/neutrino2211)_",
"title": "Avoiding Weird Javascript Behaviour (true + true === 2 but true !== 1)"
}