[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-1411":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":23,"hasPages":23,"topics":25,"createdAt":10,"pushedAt":10,"updatedAt":34,"readmeContent":35,"aiSummary":36,"trendingCount":16,"starSnapshotCount":16,"syncStatus":17,"lastSyncTime":37,"discoverSource":38},1411,"wtfjs","denysdovhan\u002Fwtfjs","denysdovhan","🤪 A list of funny and tricky JavaScript examples","http:\u002F\u002Fbit.ly\u002Fwtfjavascript",null,"JavaScript",37629,2695,569,22,0,2,15,42,9,85.7,"Do What The F*ck You Want To Public License",false,"master",[26,27,28,29,30,31,32,33],"book","handbook","javascript","js","learning","notes","specification","wtf","2026-06-12 04:00:09","[![SWUbanner](https:\u002F\u002Fraw.githubusercontent.com\u002Fvshymanskyy\u002FStandWithUkraine\u002Fmain\u002Fbanner-direct-single.svg)](https:\u002F\u002Fstand-with-ukraine.pp.ua\u002F)\n\n# What the f\\*ck JavaScript?\n\n[![WTFPL 2.0][license-image]][license-url]\n[![NPM version][npm-image]][npm-url]\n[![Patreon][patreon-image]][patreon-url]\n[![Buy Me A Coffee][bmc-image]][bmc-url]\n\n> A list of funny and tricky JavaScript examples\n\nJavaScript is a great language. It has a simple syntax, large ecosystem and, what is most important, a great community.\n\nAt the same time, we all know that JavaScript is quite a funny language with tricky parts. Some of them can quickly turn our everyday job into hell, and some of them can make us laugh out loud.\n\nThe original idea for WTFJS belongs to [Brian Leroux](https:\u002F\u002Ftwitter.com\u002Fbrianleroux). This list is highly inspired by his talk [**“WTFJS”** at dotJS 2012](https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=et8xNAc2ic8):\n\n[![dotJS 2012 - Brian Leroux - WTFJS](https:\u002F\u002Fimg.youtube.com\u002Fvi\u002Fet8xNAc2ic8\u002F0.jpg)](https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=et8xNAc2ic8)\n\n# Node Packaged Manuscript\n\nYou can install this handbook using `npm`. Just run:\n\n```\n$ npm install -g wtfjs\n```\n\nYou should be able to run `wtfjs` at the command line now. This will open the manual in your selected `$PAGER`. Otherwise, you may continue reading on here.\n\nThe source is available here: \u003Chttps:\u002F\u002Fgithub.com\u002Fdenysdovhan\u002Fwtfjs>\n\n# Translations\n\nCurrently, there are these translations of **wtfjs**:\n\n- [中文](.\u002FREADME-zh-cn.md)\n- [हिंदी](.\u002FREADME-hi.md)\n- [Français](.\u002FREADME-fr-fr.md)\n- [Português do Brasil](.\u002FREADME-pt-br.md)\n- [Polski](.\u002FREADME-pl-pl.md)\n- [Italiano](.\u002FREADME-it-it.md)\n- [한국어](.\u002FREADME-kr.md)\n\n[**Help translating to your language**][tr-request]\n\n[tr-request]: https:\u002F\u002Fgithub.com\u002Fdenysdovhan\u002Fwtfjs\u002Fblob\u002Fmaster\u002FCONTRIBUTING.md#translations\n\n**Note:** Translations are maintained by their translators. They may not contain every example, and existing examples may be outdated.\n\n\u003C!-- prettier-ignore-start -->\n\u003C!-- START doctoc generated TOC please keep comment here to allow auto update -->\n\u003C!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n# Table of Contents\n\n- [💪🏻 Motivation](#-motivation)\n- [✍🏻 Notation](#-notation)\n- [👀 Examples](#-examples)\n  - [`[]` is equal `![]`](#-is-equal-)\n  - [`true` is not equal `![]`, but not equal `[]` too](#true-is-not-equal--but-not-equal--too)\n  - [true is false](#true-is-false)\n  - [baNaNa](#banana)\n  - [`NaN` is not a `NaN`](#nan-is-not-a-nan)\n  - [`Object.is()` and `===` weird cases](#objectis-and--weird-cases)\n  - [It's a fail](#its-a-fail)\n  - [`[]` is truthy, but not `true`](#-is-truthy-but-not-true)\n  - [`null` is falsy, but not `false`](#null-is-falsy-but-not-false)\n  - [`document.all` is an object, but it is undefined](#documentall-is-an-object-but-it-is-undefined)\n  - [Minimal value is greater than zero](#minimal-value-is-greater-than-zero)\n  - [function is not a function](#function-is-not-a-function)\n  - [Adding arrays](#adding-arrays)\n  - [Trailing commas in array](#trailing-commas-in-array)\n  - [Array equality is a monster](#array-equality-is-a-monster)\n  - [`undefined` and `Number`](#undefined-and-number)\n  - [`parseInt` is a bad guy](#parseint-is-a-bad-guy)\n  - [Math with `true` and `false`](#math-with-true-and-false)\n  - [HTML comments are valid in JavaScript](#html-comments-are-valid-in-javascript)\n  - [`NaN` is ~~not~~ a number](#nan-is-not-a-number)\n  - [`[]` and `null` are objects](#-and-null-are-objects)\n  - [Magically increasing numbers](#magically-increasing-numbers)\n  - [Precision of `0.1 + 0.2`](#precision-of-01--02)\n  - [Patching numbers](#patching-numbers)\n  - [Comparison of three numbers](#comparison-of-three-numbers)\n  - [Funny math](#funny-math)\n  - [Addition of RegExps](#addition-of-regexps)\n  - [Strings aren't instances of `String`](#strings-arent-instances-of-string)\n  - [Calling functions with backticks](#calling-functions-with-backticks)\n  - [Call call call](#call-call-call)\n  - [A `constructor` property](#a-constructor-property)\n  - [Object as a key of object's property](#object-as-a-key-of-objects-property)\n  - [Accessing prototypes with `__proto__`](#accessing-prototypes-with-__proto__)\n  - [`` `${{Object}}` ``](#-object-)\n  - [Destructuring with default values](#destructuring-with-default-values)\n  - [Dots and spreading](#dots-and-spreading)\n  - [Labels](#labels)\n  - [Nested labels](#nested-labels)\n  - [Insidious `try..catch`](#insidious-trycatch)\n  - [Is this multiple inheritance?](#is-this-multiple-inheritance)\n  - [A generator which yields itself](#a-generator-which-yields-itself)\n  - [A class of class](#a-class-of-class)\n  - [Non-coercible objects](#non-coercible-objects)\n  - [Tricky arrow functions](#tricky-arrow-functions)\n  - [Arrow functions can not be a constructor](#arrow-functions-can-not-be-a-constructor)\n  - [`arguments` and arrow functions](#arguments-and-arrow-functions)\n  - [Tricky return](#tricky-return)\n  - [Chaining assignments on object](#chaining-assignments-on-object)\n  - [Accessing object properties with arrays](#accessing-object-properties-with-arrays)\n  - [`Number.toFixed()` display different numbers](#numbertofixed-display-different-numbers)\n  - [`Math.max()` less than `Math.min()`](#mathmax-less-than-mathmin)\n  - [Comparing `null` to `0`](#comparing-null-to-0)\n  - [Same variable redeclaration](#same-variable-redeclaration)\n  - [Default behavior Array.prototype.sort()](#default-behavior-arrayprototypesort)\n  - [resolve() won't return Promise instance](#resolve-wont-return-promise-instance)\n  - [`{}{}` is undefined](#-is-undefined)\n  - [`arguments` binding](#arguments-binding)\n  - [An `alert` from hell](#an-alert-from-hell)\n  - [An infinite timeout](#an-infinite-timeout)\n  - [A `setTimeout` object](#a-settimeout-object)\n  - [Double dot](#double-dot)\n  - [Extra Newness](#extra-newness)\n  - [Why you should use semicolons](#why-you-should-use-semicolons)\n  - [Split a string by a space](#split-a-string-by-a-space)\n  - [A stringified string](#a-stringified-string)\n  - [Non-strict comparison of a number to `true`](#non-strict-comparison-of-a-number-to-true)\n- [📚 Other resources](#-other-resources)\n- [🤝 Supporting](#-supporting)\n- [🎓 License](#-license)\n\n\u003C!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\u003C!-- prettier-ignore-end -->\n\n# 💪🏻 Motivation\n\n> Just for fun\n>\n> &mdash; _[**“Just for Fun: The Story of an Accidental Revolutionary”**](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FJust_for_Fun), Linus Torvalds_\n\nThe primary goal of this list is to collect some crazy examples and explain how they work, if possible. Just because it's fun to learn something that we didn't know before.\n\nIf you are a beginner, you can use these notes to get a deeper dive into JavaScript. I hope these notes will motivate you to spend more time reading the specification.\n\nIf you are a professional developer, you can consider these examples as a great reference for all of the quirks and unexpected edges of our beloved JavaScript.\n\nIn any case, just read this. You're probably going to find something new.\n\n> **⚠️ Note:** If you enjoy reading this document, please, [consider supporting the author of this collection](#-supporting).\n\n# ✍🏻 Notation\n\n**`\u002F\u002F ->`** is used to show the result of an expression. For example:\n\n```js\n1 + 1; \u002F\u002F -> 2\n```\n\n**`\u002F\u002F >`** means the result of `console.log` or another output. For example:\n\n```js\nconsole.log(\"hello, world!\"); \u002F\u002F > hello, world!\n```\n\n**`\u002F\u002F`** is just a comment used for explanations. Example:\n\n```js\n\u002F\u002F Assigning a function to foo constant\nconst foo = function() {};\n```\n\n# 👀 Examples\n\n## `[]` is equal `![]`\n\nArray is equal not array:\n\n```js\n[] == ![]; \u002F\u002F -> true\n```\n\n### 💡 Explanation:\n\nThe abstract equality operator converts both sides to numbers to compare them, and both sides become the number `0` for different reasons. Arrays are truthy, so on the right, the opposite of a truthy value is `false`, which is then coerced to `0`. On the left, however, an empty array is coerced to a number without becoming a boolean first, and empty arrays are coerced to `0`, despite being truthy.\n\nHere is how this expression simplifies:\n\n```js\n+[] == +![];\n0 == +false;\n0 == 0;\ntrue;\n```\n\nSee also [`[]` is truthy, but not `true`](#-is-truthy-but-not-true).\n\n- [**12.5.9** Logical NOT Operator (`!`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-logical-not-operator)\n- [**7.2.15** Abstract Equality Comparison](https:\u002F\u002F262.ecma-international.org\u002F11.0\u002Findex.html#sec-abstract-equality-comparison)\n\n## `true` is not equal `![]`, but not equal `[]` too\n\nArray is not equal `true`, but not Array is not equal `true` too;\nArray is equal `false`, not Array is equal `false` too:\n\n```js\ntrue == []; \u002F\u002F -> false\ntrue == ![]; \u002F\u002F -> false\n\nfalse == []; \u002F\u002F -> true\nfalse == ![]; \u002F\u002F -> true\n```\n\n### 💡 Explanation:\n\n```js\ntrue == []; \u002F\u002F -> false\ntrue == ![]; \u002F\u002F -> false\n\n\u002F\u002F According to the specification\n\ntrue == []; \u002F\u002F -> false\n\ntoNumber(true); \u002F\u002F -> 1\ntoNumber([]); \u002F\u002F -> 0\n\n1 == 0; \u002F\u002F -> false\n\ntrue == ![]; \u002F\u002F -> false\n\n![]; \u002F\u002F -> false\n\ntrue == false; \u002F\u002F -> false\n```\n\n```js\nfalse == []; \u002F\u002F -> true\nfalse == ![]; \u002F\u002F -> true\n\n\u002F\u002F According to the specification\n\nfalse == []; \u002F\u002F -> true\n\ntoNumber(false); \u002F\u002F -> 0\ntoNumber([]); \u002F\u002F -> 0\n\n0 == 0; \u002F\u002F -> true\n\nfalse == ![]; \u002F\u002F -> true\n\n![]; \u002F\u002F -> false\n\nfalse == false; \u002F\u002F -> true\n```\n\n- [**7.2.15** Abstract Equality Comparison](https:\u002F\u002F262.ecma-international.org\u002F11.0\u002Findex.html#sec-abstract-equality-comparison)\n\n## true is false\n\n```js\n!!\"false\" == !!\"true\"; \u002F\u002F -> true\n!!\"false\" === !!\"true\"; \u002F\u002F -> true\n```\n\n### 💡 Explanation:\n\nConsider this step-by-step:\n\n```js\n\u002F\u002F true is 'truthy' and represented by value 1 (number), 'true' in string form is NaN.\ntrue == \"true\"; \u002F\u002F -> false\nfalse == \"false\"; \u002F\u002F -> false\n\n\u002F\u002F 'false' is not the empty string, so it's a truthy value\n!!\"false\"; \u002F\u002F -> true\n!!\"true\"; \u002F\u002F -> true\n```\n\n- [**7.2.15** Abstract Equality Comparison](https:\u002F\u002F262.ecma-international.org\u002F11.0\u002Findex.html#sec-abstract-equality-comparison)\n\n## baNaNa\n\n```js\n\"b\" + \"a\" + +\"a\" + \"a\"; \u002F\u002F -> 'baNaNa'\n```\n\nThis is an old-school joke in JavaScript, but remastered. Here's the original one:\n\n```js\n\"foo\" + +\"bar\"; \u002F\u002F -> 'fooNaN'\n```\n\n### 💡 Explanation:\n\nThe expression is evaluated as `'foo' + (+'bar')`, which converts `'bar'` to not a number.\n\n- [**12.8.3** The Addition Operator (`+`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-addition-operator-plus)\n- [12.5.6 Unary + Operator](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-unary-plus-operator)\n\n## `NaN` is not a `NaN`\n\n```js\nNaN === NaN; \u002F\u002F -> false\n```\n\n### 💡 Explanation:\n\nThe specification strictly defines the logic behind this behavior:\n\n> 1. If `Type(x)` is different from `Type(y)`, return **false**.\n> 2. If `Type(x)` is Number, then\n>    1. If `x` is **NaN**, return **false**.\n>    2. If `y` is **NaN**, return **false**.\n>    3. … … …\n>\n> &mdash; [**7.2.14** Strict Equality Comparison](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-strict-equality-comparison)\n\nFollowing the definition of `NaN` from the IEEE:\n\n> Four mutually exclusive relations are possible: less than, equal, greater than, and unordered. The last case arises when at least one operand is NaN. Every NaN shall compare unordered with everything, including itself.\n>\n> &mdash; [“What is the rationale for all comparisons returning false for IEEE754 NaN values?”](https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F1565164\u002F1573715#1573715) at StackOverflow\n\n## `Object.is()` and `===` weird cases\n\n`Object.is()` determines if two values have the same value or not. It works similar to the `===` operator but there are a few weird cases:\n\n```javascript\nObject.is(NaN, NaN); \u002F\u002F -> true\nNaN === NaN; \u002F\u002F -> false\n\nObject.is(-0, 0); \u002F\u002F -> false\n-0 === 0; \u002F\u002F -> true\n\nObject.is(NaN, 0 \u002F 0); \u002F\u002F -> true\nNaN === 0 \u002F 0; \u002F\u002F -> false\n```\n\n### 💡 Explanation:\n\nIn JavaScript lingo, `NaN` and `NaN` are the same value but they're not strictly equal. `NaN === NaN` being false is apparently due to historical reasons so it would probably be better to accept it as it is.\n\nSimilarly, `-0` and `0` are strictly equal, but they're not the same value.\n\nFor more details about `NaN === NaN`, see the above case.\n\n- [Here are the TC39 specs about Object.is](https:\u002F\u002Ftc39.es\u002Fecma262\u002F#sec-object.is)\n- [Equality comparisons and sameness](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FEquality_comparisons_and_sameness) on MDN\n\n## It's a fail\n\nYou would not believe, but …\n\n```js\n(![] + [])[+[]] +\n  (![] + [])[+!+[]] +\n  ([![]] + [][[]])[+!+[] + [+[]]] +\n  (![] + [])[!+[] + !+[]];\n\u002F\u002F -> 'fail'\n```\n\n### 💡 Explanation:\n\nBy breaking that mass of symbols into pieces, we notice that the following pattern occurs often:\n\n```js\n![] + []; \u002F\u002F -> 'false'\n![]; \u002F\u002F -> false\n```\n\nSo we try adding `[]` to `false`. But due to a number of internal function calls (`binary + Operator` -> `ToPrimitive` -> `[[DefaultValue]]`) we end up converting the right operand to a string:\n\n```js\n![] + [].toString(); \u002F\u002F 'false'\n```\n\nThinking of a string as an array we can access its first character via `[0]`:\n\n```js\n\"false\"[0]; \u002F\u002F -> 'f'\n```\n\nThe rest is obvious, but the `i` is tricky. The `i` in `fail` is grabbed by generating the string `'falseundefined'` and grabbing the element on index `['10']`.\n\nMore examples:\n\n```js\n+![]          \u002F\u002F -> 0\n+!![]         \u002F\u002F -> 1\n!![]          \u002F\u002F -> true\n![]           \u002F\u002F -> false\n[][[]]        \u002F\u002F -> undefined\n+!![] \u002F +![]  \u002F\u002F -> Infinity\n[] + {}       \u002F\u002F -> \"[object Object]\"\n+{}           \u002F\u002F -> NaN\n```\n\n- [Brainfuck beware: JavaScript is after you!](http:\u002F\u002Fpatriciopalladino.com\u002Fblog\u002F2012\u002F08\u002F09\u002Fnon-alphanumeric-javascript.html)\n- [Writing a sentence without using the Alphabet](https:\u002F\u002Fbluewings.github.io\u002Fen\u002Fwriting-a-sentence-without-using-the-alphabet\u002F#weird-javascript-generator) — generate any phrase using JavaScript\n\n## `[]` is truthy, but not `true`\n\nAn array is a truthy value, however, it's not equal to `true`.\n\n```js\n!![]       \u002F\u002F -> true\n[] == true \u002F\u002F -> false\n```\n\n### 💡 Explanation:\n\nHere are links to the corresponding sections in the ECMA-262 specification:\n\n- [**12.5.9** Logical NOT Operator (`!`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-logical-not-operator)\n- [**7.2.15** Abstract Equality Comparison](https:\u002F\u002F262.ecma-international.org\u002F11.0\u002Findex.html#sec-abstract-equality-comparison)\n\n## `null` is falsy, but not `false`\n\nDespite the fact that `null` is a falsy value, it's not equal to `false`.\n\n```js\n!!null; \u002F\u002F -> false\nnull == false; \u002F\u002F -> false\n```\n\nAt the same time, other falsy values, like `0` or `''` are equal to `false`.\n\n```js\n0 == false; \u002F\u002F -> true\n\"\" == false; \u002F\u002F -> true\n```\n\n### 💡 Explanation:\n\nThe explanation is the same as for previous example. Here's the corresponding link:\n\n- [**7.2.15** Abstract Equality Comparison](https:\u002F\u002F262.ecma-international.org\u002F11.0\u002Findex.html#sec-abstract-equality-comparison)\n\n## `document.all` is an object, but it is undefined\n\n> ⚠️ This is part of the Browser API and won't work in a Node.js environment ⚠️\n\nDespite the fact that `document.all` is an array-like object and it gives access to the DOM nodes in the page, it responds to the `typeof` function as `undefined`.\n\n```js\ndocument.all instanceof Object; \u002F\u002F -> true\ntypeof document.all; \u002F\u002F -> 'undefined'\n```\n\nAt the same time, `document.all` is not equal to `undefined`.\n\n```js\ndocument.all === undefined; \u002F\u002F -> false\ndocument.all === null; \u002F\u002F -> false\n```\n\nBut at the same time:\n\n```js\ndocument.all == null; \u002F\u002F -> true\n```\n\n### 💡 Explanation:\n\n> `document.all` used to be a way to access DOM elements, in particular with old versions of IE. While it has never been a standard it was broadly used in the old age JS code. When the standard progressed with new APIs (such as `document.getElementById`) this API call became obsolete and the standard committee had to decide what to do with it. Because of its broad use they decided to keep the API but introduce a willful violation of the JavaScript specification.\n> The reason why it responds to `false` when using the [Strict Equality Comparison](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-strict-equality-comparison) with `undefined` while `true` when using the [Abstract Equality Comparison](https:\u002F\u002F262.ecma-international.org\u002F11.0\u002Findex.html#sec-abstract-equality-comparison) is due to the willful violation of the specification that explicitly allows that.\n>\n> &mdash; [“Obsolete features - document.all”](https:\u002F\u002Fhtml.spec.whatwg.org\u002Fmultipage\u002Fobsolete.html#dom-document-all) at WhatWG - HTML spec\n> &mdash; [“Chapter 4 - ToBoolean - Falsy values”](https:\u002F\u002Fgithub.com\u002Fgetify\u002FYou-Dont-Know-JS\u002Fblob\u002F0d79079b61dad953bbfde817a5893a49f7e889fb\u002Ftypes%20%26%20grammar\u002Fch4.md#falsy-objects) at YDKJS - Types & Grammar\n\n## Minimal value is greater than zero\n\n`Number.MIN_VALUE` is the smallest number, which is greater than zero:\n\n```js\nNumber.MIN_VALUE > 0; \u002F\u002F -> true\n```\n\n### 💡 Explanation:\n\n> `Number.MIN_VALUE` is `5e-324`, i.e. the smallest positive number that can be represented within float precision, i.e. that's as close as you can get to zero. It defines the best resolution that floats can give you.\n>\n> Now the overall smallest value is `Number.NEGATIVE_INFINITY` although it's not really numeric in a strict sense.\n>\n> &mdash; [“Why is `0` less than `Number.MIN_VALUE` in JavaScript?”](https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F26614728\u002Fwhy-is-0-less-than-number-min-value-in-javascript) at StackOverflow\n\n- [**20.1.2.9** Number.MIN_VALUE](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-number.min_value)\n\n## function is not a function\n\n> ⚠️ A bug present in V8 v5.5 or lower (Node.js \u003C=7) ⚠️\n\nAll of you know about the annoying _undefined is not a function_, but what about this?\n\n```js\n\u002F\u002F Declare a class which extends null\nclass Foo extends null {}\n\u002F\u002F -> [Function: Foo]\n\nnew Foo() instanceof null;\n\u002F\u002F > TypeError: function is not a function\n\u002F\u002F >     at … … …\n```\n\n### 💡 Explanation:\n\nThis is not a part of the specification. It's just a bug that has now been fixed, so there shouldn't be a problem with it in the future.\n\n### Super constructor null of Foo is not a constructor\n\nIt's continuation of story with previous bug in modern environment (tested with Chrome 71 and Node.js v11.8.0).\n\n```js\nclass Foo extends null {}\nnew Foo() instanceof null;\n\u002F\u002F > TypeError: Super constructor null of Foo is not a constructor\n```\n\n### 💡 Explanation:\n\nThis is not a bug because:\n\n```js\nObject.getPrototypeOf(Foo.prototype); \u002F\u002F -> null\n```\n\nIf the class has no constructor the call from prototype chain. But in the parent has no constructor. Just in case, I’ll clarify that `null` is an object:\n\n```js\ntypeof null === \"object\";\n```\n\nTherefore, you can inherit from it (although in the world of the OOP for such terms would have beaten me). So you can't call the null constructor. If you change this code:\n\n```js\nclass Foo extends null {\n  constructor() {\n    console.log(\"something\");\n  }\n}\n```\n\nYou see the error:\n\n```\nReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor\n```\n\nAnd if you add `super`:\n\n```js\nclass Foo extends null {\n  constructor() {\n    console.log(111);\n    super();\n  }\n}\n```\n\nJS throws an error:\n\n```\nTypeError: Super constructor null of Foo is not a constructor\n```\n\n- [An explanation of this issue](https:\u002F\u002Fgithub.com\u002Fdenysdovhan\u002Fwtfjs\u002Fpull\u002F102#discussion_r259143582) by [@geekjob](https:\u002F\u002Fgithub.com\u002Fgeekjob)\n\n## Adding arrays\n\nWhat if you try to add two arrays?\n\n```js\n[1, 2, 3] + [4, 5, 6]; \u002F\u002F -> '1,2,34,5,6'\n```\n\n### 💡 Explanation:\n\nThe concatenation happens. Step-by-step, it looks like this:\n\n```js\n[1, 2, 3] +\n  [4, 5, 6][\n    \u002F\u002F call toString()\n    (1, 2, 3)\n  ].toString() +\n  [4, 5, 6].toString();\n\u002F\u002F concatenation\n\"1,2,3\" + \"4,5,6\";\n\u002F\u002F ->\n(\"1,2,34,5,6\");\n```\n\n## Trailing commas in array\n\nYou've created an array with 4 empty elements. Despite all, you'll get an array with three elements, because of trailing commas:\n\n```js\nlet a = [, , ,];\na.length; \u002F\u002F -> 3\na.toString(); \u002F\u002F -> ',,'\n```\n\n### 💡 Explanation:\n\n> **Trailing commas** (sometimes called \"final commas\") can be useful when adding new elements, parameters, or properties to JavaScript code. If you want to add a new property, you can simply add a new line without modifying the previously last line if that line already uses a trailing comma. This makes version-control diffs cleaner and editing code might be less troublesome.\n>\n> &mdash; [Trailing commas](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FTrailing_commas) at MDN\n\n## Array equality is a monster\n\nArray equality is a monster in JS, as you can see below:\n\n```js\n[] == ''   \u002F\u002F -> true\n[] == 0    \u002F\u002F -> true\n[''] == '' \u002F\u002F -> true\n[0] == 0   \u002F\u002F -> true\n[0] == ''  \u002F\u002F -> false\n[''] == 0  \u002F\u002F -> true\n\n[null] == ''      \u002F\u002F true\n[null] == 0       \u002F\u002F true\n[undefined] == '' \u002F\u002F true\n[undefined] == 0  \u002F\u002F true\n\n[[]] == 0  \u002F\u002F true\n[[]] == '' \u002F\u002F true\n\n[[[[[[]]]]]] == '' \u002F\u002F true\n[[[[[[]]]]]] == 0  \u002F\u002F true\n\n[[[[[[ null ]]]]]] == 0  \u002F\u002F true\n[[[[[[ null ]]]]]] == '' \u002F\u002F true\n\n[[[[[[ undefined ]]]]]] == 0  \u002F\u002F true\n[[[[[[ undefined ]]]]]] == '' \u002F\u002F true\n```\n\n### 💡 Explanation:\n\nYou should watch very carefully for the above examples! The behaviour is described in section [**7.2.15** Abstract Equality Comparison](https:\u002F\u002F262.ecma-international.org\u002F11.0\u002Findex.html#sec-abstract-equality-comparison) of the specification.\n\n## `undefined` and `Number`\n\nIf we don't pass any arguments into the `Number` constructor, we'll get `0`. The value `undefined` is assigned to formal arguments when there are no actual arguments, so you might expect that `Number` without arguments takes `undefined` as a value of its parameter. However, when we pass `undefined`, we will get `NaN`.\n\n```js\nNumber(); \u002F\u002F -> 0\nNumber(undefined); \u002F\u002F -> NaN\n```\n\n### 💡 Explanation:\n\nAccording to the specification:\n\n1. If no arguments were passed to this function's invocation, let `n` be `+0`.\n2. Else, let `n` be ? `ToNumber(value)`.\n3. In case of `undefined`, `ToNumber(undefined)` should return `NaN`.\n\nHere's the corresponding section:\n\n- [**20.1.1** The Number Constructor](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-number-constructor)\n- [**7.1.3** ToNumber(`argument`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-tonumber)\n\n## `parseInt` is a bad guy\n\n`parseInt` is famous by its quirks:\n\n```js\nparseInt(\"f*ck\"); \u002F\u002F -> NaN\nparseInt(\"f*ck\", 16); \u002F\u002F -> 15\n```\n\n**💡 Explanation:** This happens because `parseInt` will continue parsing character-by-character until it hits a character it doesn't know. The `f` in `'f*ck'` is the hexadecimal digit `15`.\n\nParsing `Infinity` to integer is something…\n\n```js\n\u002F\u002F\nparseInt(\"Infinity\", 10); \u002F\u002F -> NaN\n\u002F\u002F ...\nparseInt(\"Infinity\", 18); \u002F\u002F -> NaN...\nparseInt(\"Infinity\", 19); \u002F\u002F -> 18\n\u002F\u002F ...\nparseInt(\"Infinity\", 23); \u002F\u002F -> 18...\nparseInt(\"Infinity\", 24); \u002F\u002F -> 151176378\n\u002F\u002F ...\nparseInt(\"Infinity\", 29); \u002F\u002F -> 385849803\nparseInt(\"Infinity\", 30); \u002F\u002F -> 13693557269\n\u002F\u002F ...\nparseInt(\"Infinity\", 34); \u002F\u002F -> 28872273981\nparseInt(\"Infinity\", 35); \u002F\u002F -> 1201203301724\nparseInt(\"Infinity\", 36); \u002F\u002F -> 1461559270678...\nparseInt(\"Infinity\", 37); \u002F\u002F -> NaN\n```\n\nBe careful with parsing `null` too:\n\n```js\nparseInt(null, 24); \u002F\u002F -> 23\n```\n\n**💡 Explanation:**\n\n> It's converting `null` to the string `\"null\"` and trying to convert it. For radixes 0 through 23, there are no numerals it can convert, so it returns NaN. At 24, `\"n\"`, the 14th letter, is added to the numeral system. At 31, `\"u\"`, the 21st letter, is added and the entire string can be decoded. At 37 on there is no longer any valid numeral set that can be generated and `NaN` is returned.\n>\n> &mdash; [“parseInt(null, 24) === 23… wait, what?”](https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F6459758\u002Fparseintnull-24-23-wait-what) at StackOverflow\n\nDon't forget about octals:\n\n```js\nparseInt(\"06\"); \u002F\u002F 6\nparseInt(\"08\"); \u002F\u002F 8 if support ECMAScript 5\nparseInt(\"08\"); \u002F\u002F 0 if not support ECMAScript 5\n```\n\n**💡 Explanation:** If the input string begins with \"0\", radix is eight (octal) or 10 (decimal). Exactly which radix is chosen is implementation-dependent. ECMAScript 5 specifies that 10 (decimal) is used, but not all browsers support this yet. For this reason always specify a radix when using `parseInt`.\n\n`parseInt` always convert input to string:\n\n```js\nparseInt({ toString: () => 2, valueOf: () => 1 }); \u002F\u002F -> 2\nNumber({ toString: () => 2, valueOf: () => 1 }); \u002F\u002F -> 1\n```\n\nBe careful while parsing floating point values\n\n```js\nparseInt(0.000001); \u002F\u002F -> 0\nparseInt(0.0000001); \u002F\u002F -> 1\nparseInt(1 \u002F 1999999); \u002F\u002F -> 5\n```\n\n**💡 Explanation:** `ParseInt` takes a string argument and returns an integer of the specified radix. `ParseInt` also strips anything after and including the first non-digit in the string parameter. `0.000001` is converted to a string `\"0.000001\"` and the `parseInt` returns `0`. When `0.0000001` is converted to a string it is treated as `\"1e-7\"` and hence `parseInt` returns `1`. `1\u002F1999999` is interpreted as `5.00000250000125e-7` and `parseInt` returns `5`.\n\n## Math with `true` and `false`\n\nLet's do some math:\n\n```js\ntrue + true; \u002F\u002F -> 2\n(true + true) * (true + true) - true; \u002F\u002F -> 3\n```\n\nHmmm… 🤔\n\n### 💡 Explanation:\n\nWe can coerce values to numbers with the `Number` constructor. It's quite obvious that `true` will be coerced to `1`:\n\n```js\nNumber(true); \u002F\u002F -> 1\n```\n\nThe unary plus operator attempts to convert its value into a number. It can convert string representations of integers and floats, as well as the non-string values `true`, `false`, and `null`. If it cannot parse a particular value, it will evaluate to `NaN`. That means we can coerce `true` to `1` easier:\n\n```js\n+true; \u002F\u002F -> 1\n```\n\nWhen you're performing addition or multiplication, the `ToNumber` method is invoked. According to the specification, this method returns:\n\n> If `argument` is **true**, return **1**. If `argument` is **false**, return **+0**.\n\nThat's why we can add boolean values as regular numbers and get correct results.\n\nCorresponding sections:\n\n- [**12.5.6** Unary `+` Operator](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-unary-plus-operator)\n- [**12.8.3** The Addition Operator (`+`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-addition-operator-plus)\n- [**7.1.3** ToNumber(`argument`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-tonumber)\n\n## HTML comments are valid in JavaScript\n\nYou will be impressed, but `\u003C!--` (which is known as HTML comment) is a valid comment in JavaScript.\n\n```js\n\u002F\u002F valid comment\n\u003C!-- valid comment too\n```\n\n### 💡 Explanation:\n\nImpressed? HTML-like comments were intended to allow browsers that didn't understand the `\u003Cscript>` tag to degrade gracefully. These browsers, e.g. Netscape 1.x are no longer popular. So there is really no point in putting HTML comments in your script tags anymore.\n\nSince Node.js is based on the V8 engine, HTML-like comments are supported by the Node.js runtime too. Moreover, they're a part of the specification:\n\n- [**B.1.3** HTML-like Comments](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-html-like-comments)\n\n## `NaN` is ~~not~~ a number\n\nType of `NaN` is a `'number'`:\n\n```js\ntypeof NaN; \u002F\u002F -> 'number'\n```\n\n### 💡 Explanation:\n\nExplanations of how `typeof` and `instanceof` operators work:\n\n- [**12.5.5** The `typeof` Operator](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-typeof-operator)\n- [**12.10.4** Runtime Semantics: InstanceofOperator(`O`,`C`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-instanceofoperator)\n\n## `[]` and `null` are objects\n\n```js\ntypeof []; \u002F\u002F -> 'object'\ntypeof null; \u002F\u002F -> 'object'\n\n\u002F\u002F however\nnull instanceof Object; \u002F\u002F false\n```\n\n### 💡 Explanation:\n\nThe behavior of `typeof` operator is defined in this section of the specification:\n\n- [**13.5.3** The `typeof` Operator](https:\u002F\u002F262.ecma-international.org\u002F12.0\u002F#sec-typeof-operator)\n\nAccording to the specification, the `typeof` operator returns a string according to [Table 37: `typeof` Operator Results](https:\u002F\u002F262.ecma-international.org\u002F12.0\u002F#table-typeof-operator-results). For `null`, ordinary, standard exotic and non-standard exotic objects, which do not implement `[[Call]]`, it returns the string `\"object\"`.\n\nHowever, you can check the type of an object by using the `toString` method.\n\n```js\nObject.prototype.toString.call([]);\n\u002F\u002F -> '[object Array]'\n\nObject.prototype.toString.call(new Date());\n\u002F\u002F -> '[object Date]'\n\nObject.prototype.toString.call(null);\n\u002F\u002F -> '[object Null]'\n```\n\n## Magically increasing numbers\n\n```js\n999999999999999; \u002F\u002F -> 999999999999999\n9999999999999999; \u002F\u002F -> 10000000000000000\n\n10000000000000000; \u002F\u002F -> 10000000000000000\n10000000000000000 + 1; \u002F\u002F -> 10000000000000000\n10000000000000000 + 1.1; \u002F\u002F -> 10000000000000002\n```\n\n### 💡 Explanation:\n\nThis is caused by IEEE 754-2008 standard for Binary Floating-Point Arithmetic. At this scale, it rounds to the nearest even number. Read more:\n\n- [**6.1.6** The Number Type](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-ecmascript-language-types-number-type)\n- [IEEE 754](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FIEEE_754) on Wikipedia\n\n## Precision of `0.1 + 0.2`\n\nA well-known joke. An addition of `0.1` and `0.2` is deadly precise:\n\n```js\n0.1 + 0.2; \u002F\u002F -> 0.30000000000000004\n0.1 + 0.2 === 0.3; \u002F\u002F -> false\n```\n\n### 💡 Explanation:\n\nThe answer for the [”Is floating point math broken?”](https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F588004\u002Fis-floating-point-math-broken) question on StackOverflow:\n\n> The constants `0.2` and `0.3` in your program will also be approximations to their true values. It happens that the closest `double` to `0.2` is larger than the rational number `0.2` but that the closest `double` to `0.3` is smaller than the rational number `0.3`. The sum of `0.1` and `0.2` winds up being larger than the rational number `0.3` and hence disagreeing with the constant in your code.\n\nThis problem is so known that there is even a website called [0.30000000000000004.com](http:\u002F\u002F0.30000000000000004.com\u002F). It occurs in every language that uses floating-point math, not just JavaScript.\n\n## Patching numbers\n\nYou can add your own methods to wrapper objects like `Number` or `String`.\n\n```js\nNumber.prototype.isOne = function() {\n  return Number(this) === 1;\n};\n\n(1.0).isOne(); \u002F\u002F -> true\n(1).isOne(); \u002F\u002F -> true\n(2.0).isOne(); \u002F\u002F -> false\n(7).isOne(); \u002F\u002F -> false\n```\n\n### 💡 Explanation:\n\nObviously, you can extend the `Number` object like any other object in JavaScript. However, it's not recommended if the behavior of the defined method is not a part of the specification. Here is the list of `Number`'s properties:\n\n- [**20.1** Number Objects](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-number-objects)\n\n## Comparison of three numbers\n\n```js\n1 \u003C 2 \u003C 3; \u002F\u002F -> true\n3 > 2 > 1; \u002F\u002F -> false\n```\n\n### 💡 Explanation:\n\nWhy does this work that way? Well, the problem is in the first part of an expression. Here's how it works:\n\n```js\n1 \u003C 2 \u003C 3; \u002F\u002F 1 \u003C 2 -> true\ntrue \u003C 3; \u002F\u002F true -> 1\n1 \u003C 3; \u002F\u002F -> true\n\n3 > 2 > 1; \u002F\u002F 3 > 2 -> true\ntrue > 1; \u002F\u002F true -> 1\n1 > 1; \u002F\u002F -> false\n```\n\nWe can fix this with _Greater than or equal operator (`>=`)_:\n\n```js\n3 > 2 >= 1; \u002F\u002F true\n```\n\nRead more about Relational operators in the specification:\n\n- [**12.10** Relational Operators](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-relational-operators)\n\n## Funny math\n\nOften the results of arithmetic operations in JavaScript might be quite unexpected. Consider these examples:\n\n```js\n 3  - 1  \u002F\u002F -> 2\n 3  + 1  \u002F\u002F -> 4\n'3' - 1  \u002F\u002F -> 2\n'3' + 1  \u002F\u002F -> '31'\n\n'' + '' \u002F\u002F -> ''\n[] + [] \u002F\u002F -> ''\n{} + [] \u002F\u002F -> 0\n[] + {} \u002F\u002F -> '[object Object]'\n{} + {} \u002F\u002F -> '[object Object][object Object]'\n\n'222' - -'111' \u002F\u002F -> 333\n\n[4] * [4]       \u002F\u002F -> 16\n[] * []         \u002F\u002F -> 0\n[4, 4] * [4, 4] \u002F\u002F NaN\n```\n\n### 💡 Explanation:\n\nWhat's happening in the first four examples? Here's a small table to understand addition in JavaScript:\n\n```\nNumber  + Number  -> addition\nBoolean + Number  -> addition\nBoolean + Boolean -> addition\nNumber  + String  -> concatenation\nString  + Boolean -> concatenation\nString  + String  -> concatenation\n```\n\nWhat about other examples? A `ToPrimitive` and `ToString` methods are being implicitly called for `[]` and `{}` before addition. Read more about evaluation process in the specification:\n\n- [**12.8.3** The Addition Operator (`+`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-addition-operator-plus)\n- [**7.1.1** ToPrimitive(`input` [,`PreferredType`])](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-toprimitive)\n- [**7.1.12** ToString(`argument`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-tostring)\n\nNotably, `{} + []` here is the exception. The reason why it differs from `[] + {}` is that, without parenthesis, it is interpreted as a code block and then a unary +, converting `[]` into a number. It sees the following:\n\n```js\n{\n  \u002F\u002F a code block here\n}\n+[]; \u002F\u002F -> 0\n```\n\nTo get the same output as `[] + {}` we can wrap it in parenthesis.\n\n```js\n({} + []); \u002F\u002F -> [object Object]\n```\n\n## Addition of RegExps\n\nDid you know you can add numbers like this?\n\n```js\n\u002F\u002F Patch a toString method\nRegExp.prototype.toString =\n  function() {\n    return this.source;\n  } \u002F\n  7 \u002F\n  -\u002F5\u002F; \u002F\u002F -> 2\n```\n\n### 💡 Explanation:\n\n- [**21.2.5.10** get RegExp.prototype.source](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-get-regexp.prototype.source)\n\n## Strings aren't instances of `String`\n\n```js\n\"str\"; \u002F\u002F -> 'str'\ntypeof \"str\"; \u002F\u002F -> 'string'\n\"str\" instanceof String; \u002F\u002F -> false\n```\n\n### 💡 Explanation:\n\nThe `String` constructor returns a string:\n\n```js\ntypeof String(\"str\"); \u002F\u002F -> 'string'\nString(\"str\"); \u002F\u002F -> 'str'\nString(\"str\") == \"str\"; \u002F\u002F -> true\n```\n\nLet's try with a `new`:\n\n```js\nnew String(\"str\") == \"str\"; \u002F\u002F -> true\ntypeof new String(\"str\"); \u002F\u002F -> 'object'\n```\n\nObject? What's that?\n\n```js\nnew String(\"str\"); \u002F\u002F -> [String: 'str']\n```\n\nMore information about the String constructor in the specification:\n\n- [**21.1.1** The String Constructor](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-string-constructor)\n\n## Calling functions with backticks\n\nLet's declare a function which logs all params into the console:\n\n```js\nfunction f(...args) {\n  return args;\n}\n```\n\nNo doubt, you know you can call this function like this:\n\n```js\nf(1, 2, 3); \u002F\u002F -> [ 1, 2, 3 ]\n```\n\nBut did you know you can call any function with backticks?\n\n```js\nf`true is ${true}, false is ${false}, array is ${[1, 2, 3]}`;\n\u002F\u002F -> [ [ 'true is ', ', false is ', ', array is ', '' ],\n\u002F\u002F ->   true,\n\u002F\u002F ->   false,\n\u002F\u002F ->   [ 1, 2, 3 ] ]\n```\n\n### 💡 Explanation:\n\nWell, this is not magic at all if you're familiar with _Tagged template literals_. In the example above, `f` function is a tag for template literal. Tags before template literal allow you to parse template literals with a function. The first argument of a tag function contains an array of string values. The remaining arguments are related to the expressions. Example:\n\n```js\nfunction template(strings, ...keys) {\n  \u002F\u002F do something with strings and keys…\n}\n```\n\nThis is the [magic behind](http:\u002F\u002Fmxstbr.blog\u002F2016\u002F11\u002Fstyled-components-magic-explained\u002F) famous library called [💅 styled-components](https:\u002F\u002Fwww.styled-components.com\u002F), which is popular in the React community.\n\nLink to the specification:\n\n- [**12.3.7** Tagged Templates](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-tagged-templates)\n\n## Call call call\n\n> Found by [@cramforce](http:\u002F\u002Ftwitter.com\u002Fcramforce)\n\n```js\nconsole.log.call.call.call.call.call.apply(a => a, [1, 2]);\n```\n\n### 💡 Explanation:\n\nAttention, it could break your mind! Try to reproduce this code in your head: we're applying the `call` method using the `apply` method. Read more:\n\n- [**19.2.3.3** Function.prototype.call(`thisArg`, ...`args`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-function.prototype.call)\n- [**19.2.3.1 ** Function.prototype.apply(`thisArg`, `argArray`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-function.prototype.apply)\n\n## A `constructor` property\n\n```js\nconst c = \"constructor\";\nc[c][c]('console.log(\"WTF?\")')(); \u002F\u002F > WTF?\n```\n\n### 💡 Explanation:\n\nLet's consider this example step-by-step:\n\n```js\n\u002F\u002F Declare a new constant which is a string 'constructor'\nconst c = \"constructor\";\n\n\u002F\u002F c is a string\nc; \u002F\u002F -> 'constructor'\n\n\u002F\u002F Getting a constructor of string\nc[c]; \u002F\u002F -> [Function: String]\n\n\u002F\u002F Getting a constructor of constructor\nc[c][c]; \u002F\u002F -> [Function: Function]\n\n\u002F\u002F Call the Function constructor and pass\n\u002F\u002F the body of new function as an argument\nc[c][c]('console.log(\"WTF?\")'); \u002F\u002F -> [Function: anonymous]\n\n\u002F\u002F And then call this anonymous function\n\u002F\u002F The result is console-logging a string 'WTF?'\nc[c][c]('console.log(\"WTF?\")')(); \u002F\u002F > WTF?\n```\n\nAn `Object.prototype.constructor` returns a reference to the `Object` constructor function that created the instance object. In case with strings it is `String`, in case with numbers it is `Number` and so on.\n\n- [`Object.prototype.constructor`](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects\u002FObject\u002Fconstructor) at MDN\n- [**19.1.3.1** Object.prototype.constructor](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-object.prototype.constructor)\n\n## Object as a key of object's property\n\n```js\n{ [{}]: {} } \u002F\u002F -> { '[object Object]': {} }\n```\n\n### 💡 Explanation:\n\nWhy does this work so? Here we're using a _Computed property name_. When you pass an object between those brackets, it coerces object to a string, so we get the property key `'[object Object]'` and the value `{}`.\n\nWe can make \"brackets hell\" like this:\n\n```js\n({ [{}]: { [{}]: {} } }[{}][{}]); \u002F\u002F -> {}\n\n\u002F\u002F structure:\n\u002F\u002F {\n\u002F\u002F   '[object Object]': {\n\u002F\u002F     '[object Object]': {}\n\u002F\u002F   }\n\u002F\u002F }\n```\n\nRead more about object literals here:\n\n- [Object initializer](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FOperators\u002FObject_initializer) at MDN\n- [**12.2.6** Object Initializer](http:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F6.0\u002F#sec-object-initializer)\n\n## Accessing prototypes with `__proto__`\n\nAs we know, primitives don't have prototypes. However, if we try to get a value of `__proto__` for primitives, we would get this:\n\n```js\n(1).__proto__.__proto__.__proto__; \u002F\u002F -> null\n```\n\n### 💡 Explanation:\n\nThis happens because when something doesn't have a prototype, it will be wrapped into a wrapper object using the `ToObject` method. So, step-by-step:\n\n```js\n(1).__proto__; \u002F\u002F -> [Number: 0]\n(1).__proto__.__proto__; \u002F\u002F -> {}\n(1).__proto__.__proto__.__proto__; \u002F\u002F -> null\n```\n\nHere is more information about `__proto__`:\n\n- [**B.2.2.1** Object.prototype.**proto**](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-object.prototype.__proto__)\n- [**7.1.13** ToObject(`argument`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-toobject)\n\n## `` `${{Object}}` ``\n\nWhat is the result of the expression below?\n\n```js\n`${{ Object }}`;\n```\n\nThe answer is:\n\n```js\n\u002F\u002F -> '[object Object]'\n```\n\n### 💡 Explanation:\n\nWe defined an object with a property `Object` using _Shorthand property notation_:\n\n```js\n{\n  Object: Object;\n}\n```\n\nThen we've passed this object to the template literal, so the `toString` method calls for that object. That's why we get the string `'[object Object]'`.\n\n- [**12.2.9** Template Literals](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-template-literals)\n- [Object initializer](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FOperators\u002FObject_initializer) at MDN\n\n## Destructuring with default values\n\nConsider this example:\n\n```js\nlet x,\n  { x: y = 1 } = { x };\ny;\n```\n\nThe example above is a great task for an interview. What the value of `y`? The answer is:\n\n```js\n\u002F\u002F -> 1\n```\n\n### 💡 Explanation:\n\n```js\nlet x,\n  { x: y = 1 } = { x };\ny;\n\u002F\u002F  ↑       ↑           ↑    ↑\n\u002F\u002F  1       3           2    4\n```\n\nWith the example above:\n\n1. We declare `x` with no value, so it's `undefined`.\n2. Then we pack the value of `x` into the object property `x`.\n3. Then we extract the value of `x` using destructuring and want to assign it to `y`. If the value is not defined, then we're going to use `1` as the default value.\n4. Return the value of `y`.\n\n- [Object initializer](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FOperators\u002FObject_initializer) at MDN\n\n## Dots and spreading\n\nInteresting examples could be composed with spreading of arrays. Consider this:\n\n```js\n[...[...\"...\"]].length; \u002F\u002F -> 3\n```\n\n### 💡 Explanation:\n\nWhy `3`? When we use the [spread operator](http:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F6.0\u002F#sec-array-initializer), the `@@iterator` method is called, and the returned iterator is used to obtain the values to be iterated. The default iterator for string spreads a string into characters. After spreading, we pack these characters into an array. Then we spread this array again and pack it back to an array.\n\nA `'...'` string consists with three `.` characters, so the length of resulting array is `3`.\n\nNow, step-by-step:\n\n```js\n[...'...']             \u002F\u002F -> [ '.', '.', '.' ]\n[...[...'...']]        \u002F\u002F -> [ '.', '.', '.' ]\n[...[...'...']].length \u002F\u002F -> 3\n```\n\nObviously, we can spread and wrap the elements of an array as many times as we want:\n\n```js\n[...'...']                 \u002F\u002F -> [ '.', '.', '.' ]\n[...[...'...']]            \u002F\u002F -> [ '.', '.', '.' ]\n[...[...[...'...']]]       \u002F\u002F -> [ '.', '.', '.' ]\n[...[...[...[...'...']]]]  \u002F\u002F -> [ '.', '.', '.' ]\n\u002F\u002F and so on …\n```\n\n## Labels\n\nNot many programmers know about labels in JavaScript. They are kind of interesting:\n\n```js\nfoo: {\n  console.log(\"first\");\n  break foo;\n  console.log(\"second\");\n}\n\n\u002F\u002F > first\n\u002F\u002F -> undefined\n```\n\n### 💡 Explanation:\n\nThe labeled statement is used with `break` or `continue` statements. You can use a label to identify a loop, and then use the `break` or `continue` statements to indicate whether a program should interrupt the loop or continue its execution.\n\nIn the example above, we identify a label `foo`. After that `console.log('first');` executes and then we interrupt the execution.\n\nRead more about labels in JavaScript:\n\n- [**13.13** Labelled Statements](https:\u002F\u002Ftc39.github.io\u002Fecma262\u002F#sec-labelled-statements)\n- [Labeled statements](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStatements\u002Flabel) at MDN\n\n## Nested labels\n\n```js\na: b: c: d: e: f: g: 1, 2, 3, 4, 5; \u002F\u002F -> 5\n```\n\n### 💡 Explanation:\n\nSimilar to previous examples, follow these links:\n\n- [**12.16** Comma Operator (`,`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-comma-operator)\n- [**13.13** Labelled Statements](https:\u002F\u002Ftc39.github.io\u002Fecma262\u002F#sec-labelled-statements)\n- [Labeled statements](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStatements\u002Flabel) at MDN\n\n## Insidious `try..catch`\n\nWhat will this expression return? `2` or `3`?\n\n```js\n(() => {\n  try {\n    return 2;\n  } finally {\n    return 3;\n  }\n})();\n```\n\nThe answer is `3`. Surprised?\n\n### 💡 Explanation:\n\n- [**13.15** The `try` Statement](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-try-statement)\n\n## Is this multiple inheritance?\n\nTake a look at the example below:\n\n```js\nnew class F extends (String, Array) {}(); \u002F\u002F -> F []\n```\n\nIs this a multiple inheritance? Nope.\n\n### 💡 Explanation:\n\nThe interesting part is the value of the `extends` clause (`(String, Array)`). The grouping operator always returns its last argument, so `(String, Array)` is actually just `Array`. That means we've just created a class which extends `Array`.\n\n- [**14.5** Class Definitions](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-class-definitions)\n- [**12.16** Comma Operator (`,`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-comma-operator)\n\n## A generator which yields itself\n\nConsider this example of a generator which yields itself:\n\n```js\n(function* f() {\n  yield f;\n})().next();\n\u002F\u002F -> { value: [GeneratorFunction: f], done: false }\n```\n\nAs you can see, the returned value is an object with its `value` equal to `f`. In that case, we can do something like this:\n\n```js\n(function* f() {\n  yield f;\n})()\n  .next()\n  .value()\n  .next()(\n    \u002F\u002F -> { value: [GeneratorFunction: f], done: false }\n\n    \u002F\u002F and again\n    function* f() {\n      yield f;\n    }\n  )()\n  .next()\n  .value()\n  .next()\n  .value()\n  .next()(\n    \u002F\u002F -> { value: [GeneratorFunction: f], done: false }\n\n    \u002F\u002F and again\n    function* f() {\n      yield f;\n    }\n  )()\n  .next()\n  .value()\n  .next()\n  .value()\n  .next()\n  .value()\n  .next();\n\u002F\u002F -> { value: [GeneratorFunction: f], done: false }\n\n\u002F\u002F and so on\n\u002F\u002F …\n```\n\n### 💡 Explanation:\n\nTo understand why this works that way, read these sections of the specification:\n\n- [**25** Control Abstraction Objects](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-control-abstraction-objects)\n- [**25.3** Generator Objects](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-generator-objects)\n\n## A class of class\n\nConsider this obfuscated syntax playing:\n\n```js\ntypeof new class {\n  class() {}\n}(); \u002F\u002F -> 'object'\n```\n\nIt seems like we're declaring a class inside of class. Should be an error, however, we get the string `'object'`.\n\n### 💡 Explanation:\n\nSince ECMAScript 5 era, _keywords_ are allowed as _property names_. So think about it as this simple object example:\n\n```js\nconst foo = {\n  class: function() {}\n};\n```\n\nAnd ES6 standardized shorthand method definitions. Also, classes can be anonymous. So if we drop `: function` part, we're going to get:\n\n```js\nclass {\n  class() {}\n}\n```\n\nThe result of a default class is always a simple object. And its typeof should return `'object'`.\n\nRead more here:\n\n- [**14.3** Method Definitions](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-method-definitions)\n- [**14.5** Class Definitions](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-class-definitions)\n\n## Non-coercible objects\n\nWith well-known symbols, there's a way to get rid of type coercion. Take a look:\n\n```js\nfunction nonCoercible(val) {\n  if (val == null) {\n    throw TypeError(\"nonCoercible should not be called with null or undefined\");\n  }\n\n  const res = Object(val);\n\n  res[Symbol.toPrimitive] = () => {\n    throw TypeError(\"Trying to coerce non-coercible object\");\n  };\n\n  return res;\n}\n```\n\nNow we can use this like this:\n\n```js\n\u002F\u002F objects\nconst foo = nonCoercible({ foo: \"foo\" });\n\nfoo * 10; \u002F\u002F -> TypeError: Trying to coerce non-coercible object\nfoo + \"evil\"; \u002F\u002F -> TypeError: Trying to coerce non-coercible object\n\n\u002F\u002F strings\nconst bar = nonCoercible(\"bar\");\n\nbar + \"1\"; \u002F\u002F -> TypeError: Trying to coerce non-coercible object\nbar.toString() + 1; \u002F\u002F -> bar1\nbar === \"bar\"; \u002F\u002F -> false\nbar.toString() === \"bar\"; \u002F\u002F -> true\nbar == \"bar\"; \u002F\u002F -> TypeError: Trying to coerce non-coercible object\n\n\u002F\u002F numbers\nconst baz = nonCoercible(1);\n\nbaz == 1; \u002F\u002F -> TypeError: Trying to coerce non-coercible object\nbaz === 1; \u002F\u002F -> false\nbaz.valueOf() === 1; \u002F\u002F -> true\n```\n\n### 💡 Explanation:\n\n- [A gist by Sergey Rubanov](https:\u002F\u002Fgist.github.com\u002Fchicoxyzzy\u002F5dd24608e886adf5444499896dff1197)\n- [**6.1.5.1** Well-Known Symbols](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-well-known-symbols)\n\n## Tricky arrow functions\n\nConsider the example below:\n\n```js\nlet f = () => 10;\nf(); \u002F\u002F -> 10\n```\n\nOkay, fine, but what about this:\n\n```js\nlet f = () => {};\nf(); \u002F\u002F -> undefined\n```\n\n### 💡 Explanation:\n\nYou might expect `{}` instead of `undefined`. This is because the curly braces are part of the syntax of the arrow functions, so `f` will return undefined. It is however possible to return the `{}` object directly from an arrow function, by enclosing the return value with brackets.\n\n```js\nlet f = () => ({});\nf(); \u002F\u002F -> {}\n```\n\n## Arrow functions can not be a constructor\n\nConsider the example below:\n\n```js\nlet f = function() {\n  this.a = 1;\n};\nnew f(); \u002F\u002F -> f { 'a': 1 }\n```\n\nNow, try do to the same with an arrow function:\n\n```js\nlet f = () => {\n  this.a = 1;\n};\nnew f(); \u002F\u002F -> TypeError: f is not a constructor\n```\n\n### 💡 Explanation:\n\nArrow functions cannot be used as constructors and will throw an error when used with `new`. Because they have a lexical `this`, and do not have a `prototype` property, so it would not make much sense.\n\n## `arguments` and arrow functions\n\nConsider the example below:\n\n```js\nlet f = function() {\n  return arguments;\n};\nf(\"a\"); \u002F\u002F -> { '0': 'a' }\n```\n\nNow, try do to the same with an arrow function:\n\n```js\nlet f = () => arguments;\nf(\"a\"); \u002F\u002F -> Uncaught ReferenceError: arguments is not defined\n```\n\n### 💡 Explanation:\n\nArrow functions are a lightweight version of regular functions with a focus on being short and lexical `this`. At the same time arrow functions do not provide a binding for the `arguments` object. As a valid alternative use the `rest parameters` to achieve the same result:\n\n```js\nlet f = (...args) => args;\nf(\"a\");\n```\n\n- [Arrow functions](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FFunctions\u002FArrow_functions) at MDN.\n\n## Tricky return\n\n`return` statement is also tricky. Consider this:\n\n\u003C!-- prettier-ignore-start -->\n```js\n(function() {\n  return\n  {\n    b: 10;\n  }\n})(); \u002F\u002F -> undefined\n```\n\u003C!-- prettier-ignore-end -->\n\n### 💡 Explanation:\n\n`return` and the returned expression must be in the same line:\n\n```js\n(function() {\n  return {\n    b: 10\n  };\n})(); \u002F\u002F -> { b: 10 }\n```\n\nThis is because of a concept called Automatic Semicolon Insertion, which automagically inserts semicolons after most newlines. In the first example, there is a semicolon inserted between the `return` statement and the object literal, so the function returns `undefined` and the object literal is never evaluated.\n\n- [**11.9.1** Rules of Automatic Semicolon Insertion](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-rules-of-automatic-semicolon-insertion)\n- [**13.10** The `return` Statement](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-return-statement)\n\n## Chaining assignments on object\n\n```js\nvar foo = { n: 1 };\nvar bar = foo;\n\nfoo.x = foo = { n: 2 };\n\nfoo.x; \u002F\u002F -> undefined\nfoo; \u002F\u002F -> {n: 2}\nbar; \u002F\u002F -> {n: 1, x: {n: 2}}\n```\n\nFrom right to left, `{n: 2}` is assigned to foo, and the result of this assignment `{n: 2}` is assigned to foo.x, that's why bar is `{n: 1, x: {n: 2}}` as bar is a reference to foo. But why foo.x is undefined while bar.x is not ?\n\n### 💡 Explanation:\n\nFoo and bar references the same object `{n: 1}`, and lvalues are resolved before assignations. `foo = {n: 2}` is creating a new object, and so foo is updated to reference that new object. The trick here is foo in `foo.x = ...` as a lvalue was resolved beforehand and still reference the old `foo = {n: 1}` object and update it by adding the x value. After that chain assignments, bar still reference the old foo object, but foo reference the new `{n: 2}` object, where x is not existing.\n\nIt's equivalent to:\n\n```js\nvar foo = { n: 1 };\nvar bar = foo;\n\nfoo = { n: 2 }; \u002F\u002F -> {n: 2}\nbar.x = foo; \u002F\u002F -> {n: 1, x: {n: 2}}\n\u002F\u002F bar.x point to the address of the new foo object\n\u002F\u002F it's not equivalent to: bar.x = {n: 2}\n```\n\n## Accessing object properties with arrays\n\n```js\nvar obj = { property: 1 };\nvar array = [\"property\"];\n\nobj[array]; \u002F\u002F -> 1\n\n\u002F\u002F this also works with nested arrays\nvar nestedArray = [[[[[[[[[[\"property\"]]]]]]]]]];\nobj[nestedArray]; \u002F\u002F -> 1\n```\n\nWhat about pseudo-multidimensional arrays?\n\n```js\nvar map = {};\nvar x = 1;\nvar y = 2;\nvar z = 3;\n\nmap[[x, y, z]] = true;\nmap[[x + 10, y, z]] = true;\n\nmap[\"1,2,3\"]; \u002F\u002F -> true\nmap[\"11,2,3\"]; \u002F\u002F -> true\n```\n\n### 💡 Explanation:\n\nThe brackets `[]` operator converts the passed expression using `toString`. Converting a one-element array to a string is akin to converting the contained element to the string:\n\n```js\n[\"property\"].toString(); \u002F\u002F -> 'property'\n```\n\n## `Number.toFixed()` display different numbers\n\n`Number.toFixed()` can behave a bit strange in different browsers. Check out this example:\n\n```js\n(0.7875).toFixed(3);\n\u002F\u002F Firefox: -> 0.787\n\u002F\u002F Chrome: -> 0.787\n\u002F\u002F IE11: -> 0.788\n(0.7876).toFixed(3);\n\u002F\u002F Firefox: -> 0.788\n\u002F\u002F Chrome: -> 0.788\n\u002F\u002F IE11: -> 0.788\n```\n\n### 💡 Explanation:\n\nWhile your first instinct may be that IE11 is correct and Firefox\u002FChrome are wrong, the reality is that Firefox\u002FChrome are more directly obeying standards for numbers (IEEE-754 Floating Point), while IE11 is minutely disobeying them in (what is probably) an effort to give clearer results.\n\nYou can see why this occurs with a few quick tests:\n\n```js\n\u002F\u002F Confirm the odd result of rounding a 5 down\n(0.7875).toFixed(3); \u002F\u002F -> 0.787\n\u002F\u002F It looks like it's just a 5 when you expand to the\n\u002F\u002F limits of 64-bit (double-precision) float accuracy\n(0.7875).toFixed(14); \u002F\u002F -> 0.78750000000000\n\u002F\u002F But what if you go beyond the limit?\n(0.7875).toFixed(20); \u002F\u002F -> 0.78749999999999997780\n```\n\nFloating point numbers are not stored as a list of decimal digits internally, but through a more complicated methodology that produces tiny inaccuracies that are usually rounded away by toString and similar calls, but are actually present internally.\n\nIn this case, that \"5\" on the end was actually an extremely tiny fraction below a true 5. Rounding it at any reasonable length will render it as a 5... but it is actually not a 5 internally.\n\nIE11, however, will report the value input with only zeros appended to the end even in the toFixed(20) case, as it seems to be forcibly rounding the value to reduce the troubles from hardware limits.\n\nSee for reference `NOTE 2` on the ECMA-262 definition for `toFixed`.\n\n- [**20.1.3.3** Number.prototype.toFixed (`fractionDigits`)](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F\u002F#sec-number.prototype.tofixed)\n\n## `Math.max()` less than `Math.min()`\n\nI find this example hilarious:\n\n```js\nMath.min() > Math.max(); \u002F\u002F -> true\nMath.min() \u003C Math.max(); \u002F\u002F -> false\n```\n\n### 💡 Explanation:\n\nThis is a simple one. Let's consider each part of this expression separately:\n\n```js\nMath.min(); \u002F\u002F -> Infinity\nMath.max(); \u002F\u002F -> -Infinity\nInfinity > -Infinity; \u002F\u002F -> true\n```\n\nWhy so? Well, `Math.max()` is not the same thing as `Number.MAX_VALUE`. It does not return the largest possible number.\n\n`Math.max` takes arguments, tries to convert the to numbers, compares each one and then returns the largest remaining. If no arguments are given, the result is −∞. If any value is `NaN`, the result is `NaN`.\n\nThe opposite is happening for `Math.min`. `Math.min` returns ∞, if no arguments are given.\n\n- [**15.8.2.11** Math.max](https:\u002F\u002F262.ecma-international.org\u002F5.1\u002F#sec-15.8.2.11)\n- [**15.8.2.11** Math.min](https:\u002F\u002F262.ecma-international.org\u002F5.1\u002F#sec-15.8.2.12)\n- [Why is `Math.max()` less than `Math.min()`?](https:\u002F\u002Fcharlieharvey.org.uk\u002Fpage\u002Fwhy_math_max_is_less_than_math_min) by Charlie Harvey\n\n## Comparing `null` to `0`\n\nThe following expressions seem to introduce a contradiction:\n\n```js\nnull == 0; \u002F\u002F -> false\nnull > 0; \u002F\u002F -> false\nnull >= 0; \u002F\u002F -> true\n```\n\nHow can `null` be neither equal to nor greater than `0`, if `null >= 0` is actually `true`? (This also works with less than in the same way.)\n\n### 💡 Explanation:\n\nThe way these three expressions are evaluated are all different and are responsible for producing this unexpected behavior.\n\nFirst, the abstract equality comparison `null == 0`. Normally, if this operator can't compare the values on either side properly, it converts both to numbers and compares the numbers. Then, you might expect the following behavior:\n\n```js\n\u002F\u002F This is not what happens\n(null == 0 + null) == +0;\n0 == 0;\ntrue;\n```\n\nHowever, according to a close reading of the spec, the number conversion doesn't actually happen on a side that is `null` or `undefined`. Therefore, if you have `null` on one side of the equal sign, the other side must be `null` or `undefined` for the expression to return `true`. Since this is not the case, `false` is returned.\n\nNext, the relational comparison `null > 0`. The algorithm here, unlike that of the abstract equality operator, _will_ convert `null` to a number. Therefore, we get this behavior:\n\n```js\nnull > 0\n+null = +0\n0 > 0\nfalse\n```\n\nFinally, the relational comparison `null >= 0`. You could argue that this expression should be the result of `null > 0 || null == 0`; if this were the case, then the above results would mean that this would also be `false`. However, the `>=` operator in fact works in a very different way, which is basically to take the opposite of the `\u003C` operator. Because our example with the greater than operator above also holds for the less than operator, that means this expression is actually evaluated like so:\n\n```js\nnull >= 0;\n!(null \u003C 0);\n!(+null \u003C +0);\n!(0 \u003C 0);\n!false;\ntrue;\n```\n\n- [**7.2.12** Abstract Relational Comparison](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-abstract-relational-comparison)\n- [**7.2.15** Abstract Equality Comparison](https:\u002F\u002F262.ecma-international.org\u002F11.0\u002Findex.html#sec-abstract-equality-comparison)\n- [An in-depth explanation](https:\u002F\u002Fblog.campvanilla.com\u002Fjavascript-the-curious-case-of-null-0-7b131644e274)\n\n## Same variable redeclaration\n\nJS allows to redeclare variables:\n\n```js\na;\na;\n\u002F\u002F This is also valid\na, a;\n```\n\nWorks also in strict mode:\n\n```js\nvar a, a, a;\nvar a;\nvar a;\n```\n\n### 💡 Explanation:\n\nAll definitions are merged into one definition.\n\n- [**13.3.2** Variable Statement](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-variable-statement)\n\n## Default behavior Array.prototype.sort()\n\nImagine that you need to sort an array of numbers.\n\n```js\n[10, 1, 3].sort(); \u002F\u002F -> [ 1, 10, 3 ]\n```\n\n### 💡 Explanation:\n\nThe default sort order is built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.\n\n- [**22.1.3.25** Array.prototype.sort ( comparefn )](https:\u002F\u002Fwww.ecma-international.org\u002Fecma-262\u002F#sec-array.prototype.sort)\n\n### Hint\n\nPass `compareFn` if you try to sort anything but string.\n\n```js\n[10, 1, 3].sort((a, b) => a - b); \u002F\u002F -> [ 1, 3, 10 ]\n```\n\n## resolve() won't return Promise instance\n\n```js\nconst theObject = {\n  a: 7\n};\nconst thePromise = new Promise((resolve, reject) => {\n  resolve(theObject);\n}); \u002F\u002F Promise instance object\n\nthePromise.then(value => {\n  console.log(value === theObject); \u002F\u002F > true\n  console.log(value); \u002F\u002F > { a: 7 }\n});\n```\n\nThe `value` which is resolved from `thePromise` is exactly `theObject`.\n\nHow about input another `Promise` into the `resolve` function?\n\n```js\nconst theObject = new Promise((resolve, reject) => {\n  resolve(7);\n}); \u002F\u002F Promise instance object\nconst thePromise = new Promise((resolve, reject) => {\n  resolve(theObject);\n}); \u002F\u002F Promise instance object\n\nthePromise.then(value => {\n  console.log(value === theObject); \u002F\u002F > false\n  console.log(value); \u002F\u002F > 7\n});\n```\n\n### 💡 Explanation:\n\n> This function flattens nested layers of promise-like objects (e.g. a promise that resolves to a promise that resolves to something) into a single layer.\n\n- [Promise.resolve() on MDN](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects\u002FPromise\u002Fresolve)\n\nThe specification is [ECMAScript 25.6.1.3.2 Promise Resolve Functions](https:\u002F\u002Ftc39.es\u002Fecma262\u002F#sec-promise-resolve-functions). But it is not quite human-friendly.\n\n## `{}{}` is undefined\n\nWrite them in the console. They will return the value defined in the last object.\n\n```js\n{}{}; \u002F\u002F -> undefined\n{}{}{}; \u002F\u002F -> undefined\n{}{}{}{}; \u002F\u002F -> undefined\n{foo: 'bar'}{}; \u002F\u002F -> 'bar'\n{}{foo: 'bar'}; \u002F\u002F -> 'bar'\n{}{foo: 'bar'}{}; \u002F\u002F -> 'bar'\n{a: 'b'}{c:' d'}{}; \u002F\u002F -> 'd'\n{a: 'b', c: 'd'}{}; \u002F\u002F > SyntaxError: Unexpected token ':'\n({}{}); \u002F\u002F > SyntaxError: Unexpected token '{'\n```\n\n### 💡 Explanation:\n\nWhen inspecting each `{}`, they returns undefined. If you inspect `{foo: 'bar'}{}`, you will find `{foo: 'bar'}` is `'bar'`.\n\nThere are two meanings for `{}`: an object or a block. For example, the `{}` in `() => {}` means block. So we need to use `() => ({})` to return an object.\n\nLet's use `{foo: 'bar'}` as a block. Write this snippet in your console:\n\n```js\nif (true) {\n  foo: \"bar\";\n} \u002F\u002F -> 'bar'\n```\n\nSurprisingly, it behaviors the same! You can guess here that `{foo: 'bar'}{}` is a block.\n\n## `arguments` binding\n\nConsider this function:\n\n```js\nfunction a(x) {\n  arguments[0] = \"hello\";\n  console.log(x);\n}\n\na(); \u002F\u002F > undefined\na(1); \u002F\u002F > \"hello\"\n```\n\n### 💡 Explanation:\n\n`arguments` is an Array-like object that contains the values of the arguments passed to that function. When no arguments are passed, then there's no `x` to override.\n\n- [The arguments object](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FFunctions\u002Farguments) on MDN\n\n## An `alert` from hell\n\nThis on is literally from hell:\n\n```js\n[666][\"\\155\\141\\160\"][\"\\143\\157\\156\\163\\164\\162\\165\\143\\164\\157\\162\"](\n  \"\\141\\154\\145\\162\\164(666)\"\n)(666); \u002F\u002F alert(666)\n```\n\n### 💡 Explanation:\n\nThis one is based on octal escape sequences and multiple strings.\n\nAny character with a character code lower than 256 (i.e. any character in the extended ASCII range) can be escaped using its octal-encoded character code, prefixed with `\\`. An example above is basically and `alert` ecoded by octal escape sequances.\n\n- [Martin Kleppe tweet about it](https:\u002F\u002Ftwitter.com\u002Faemkei\u002Fstatus\u002F897172907222237185)\n- [JavaScript character escape sequences](https:\u002F\u002Fmathiasbynens.be\u002Fnotes\u002Fjavascript-escapes#octal)\n- [Multi-Line JavaScript Strings](https:\u002F\u002Fdavidwalsh.name\u002Fmultiline-javascript-strings)\n\n## An infinite timeout\n\nGuess what would happen if we set an infinite timeout?\n\n```js\nsetTimeout(() => console.log(\"called\"), Infinity); \u002F\u002F -> \u003CtimeoutId>\n\u002F\u002F > 'called'\n```\n\nIt will executed immediately instead of infinity delay.\n\n### 💡 Explanation:\n\nUsually, runtime stores the delay as a 32-bit signed integer internally. This causes an integer overflow, resulting in the timeout being executed immediately.\n\nFor example, in Node.js we will get this warning:\n\n```\n(node:1731) TimeoutOverflowWarning: Infinity does not fit into a 32-bit signed integer.\nTimeout duration was set to 1.\n(Use `node --trace-warnings ...` to show where the warning was created)\n```\n\n- [WindowOrWorkerGlobalScope.setTimeout()](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FWindowOrWorkerGlobalScope\u002FsetTimeout) on MDN\n- [Node.js Documentation on Timers](https:\u002F\u002Fnodejs.org\u002Fapi\u002Ftimers.html#timers_settimeout_callback_delay_args)\n- [Timers](https:\u002F\u002Fwww.w3.org\u002FTR\u002F2011\u002FWD-html5-20110525\u002Ftimers.html) on W3C\n\n## A `setTimeout` object\n\nGuess what would happen if we set an callback that's not a function to `setTimeout`?\n\n```js\nsetTimeout(123, 100); \u002F\u002F -> \u003CtimeoutId>\n\u002F\u002F > 'called'\n```\n\nThis is fine.\n\n```js\nsetTimeout('{a: 1}', 100); \u002F\u002F -> \u003CtimeoutId>\n\u002F\u002F > 'called'\n```\n\nThis is also fine.\n\n```js\nsetTimeout({a: 1}, 100); \u002F\u002F -> \u003CtimeoutId>\n\u002F\u002F > 'Uncaught SyntaxError: Unexpected identifier               setTimeout (async) (anonymous) @ VM__:1'\n```\n\nThis throws an **SyntaxError**.\n\nNote that this can easily happen if your function returns an object and you call it here instead of passing it! What if the content - policy is set to `self`?\n\n```js\nsetTimeout(123, 100); \u002F\u002F -> \u003CtimeoutId>\n\u002F\u002F > console.error(\"[Report Only] Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"script-src 'report-sample' 'self' \")\n```\n\nThe console refuses to run it at all!\n\n### 💡 Explanation:\n\n`WindowOrWorkerGlobalScope.setTimeout()` can be called with `code` as first argument, which will be passed on to `eval`, which is bad. Eval will coerce her input to String, and evaluate what is produced, so Objects becomes `'[object Object]'` which has hmmm ... an `'Unexpected identifier'`!\n\n- [eval()](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects\u002Feval) on MDN (don't use this)\n- [WindowOrWorkerGlobalScope.setTimeout()](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FWindowOrWorkerGlobalScope\u002FsetTimeout) on MDN\n- [Content Security Policy](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FHTTP\u002FHeaders\u002FContent-Security-Policy)\n- [Timers](https:\u002F\u002Fwww.w3.org\u002FTR\u002F2011\u002FWD-html5-20110525\u002Ftimers.html) on W3C\n\n## Double dot\n\nLet's try to coerce a number to a string:\n\n```js\n27.toString() \u002F\u002F > Uncaught SyntaxError: Invalid or unexpected token\n```\n\nMaybe we should try with two dots?\n\n```js\n27..toString(); \u002F\u002F -> '27'\n```\n\nBut why doesn't first example work?\n\n### 💡 Explanation:\n\nIt's just a language grammar limitation.\n\nThe `.` character presents an ambiguity. It can be understood to be the member operator, or a decimal, depending on its placement.\n\nThe specification's interpretation of the `.` character in that particular position is that it will be a decimal. This is defined by the numeric literal syntax of ECMAScript.\n\nYou must always use parenthesis or an addition dot to make such expression valid.\n\n```js\n(27).toString(); \u002F\u002F -> '27'\n\u002F\u002F or\n27..toString(); \u002F\u002F -> '27'\n```\n\n- [Usage of toString in JavaScript](https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F6853865\u002Fusage-of-tostring-in-javascript\u002F6853910#6853910) on StackOverflow\n- [Why does 10..toString() work, but 10.toString() does not?](https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F13149282\u002Fwhy-does-10-tostring-work-but-10-tostring-does-not\u002F13149301#13149301)\n\n## Extra Newness\n\nI present this as an oddity for your amusement.\n\n```js\nclass Foo extends Function {\n  constructor(val) {\n    super();\n    this.prototype.val = val;\n  }\n}\n\nnew new Foo(\":D\")().val; \u002F\u002F -> ':D'\n```\n\n### 💡 Explanation:\n\nConstructors in JavaScript are just functions with some special treatment. By extending Function using the class syntax you create a class that, when instantiated, is now a function, which you can then additionally instantiate.\n\nWhile not exhaustively tested, I believe the last statement can be analyzed thus:\n\n```js\nnew new Foo(\":D\")().val(new newFooInstance()).val;\nveryNewFooInstance.val;\n\u002F\u002F -> ':D'\n```\n\nAs a tiny addendum, doing `new Function('return \"bar\";')` of co","WTFJS 是一个收集了有趣且棘手的 JavaScript 代码示例的项目。它通过一系列令人惊讶和困惑的代码片段展示了 JavaScript 的一些不为人知的特性和行为，帮助开发者更好地理解这门语言的复杂性。项目支持多种语言版本，并可以通过 npm 安装后在命令行中查看手册。适合于对 JavaScript 有一定基础并希望深入了解其内部机制或寻找编程乐趣的开发者使用。","2026-06-11 02:43:33","top_all"]