(window.webpackJsonp=window.webpackJsonp||[]).push([[43],{93:function(e,n,a){"use strict";a.r(n),a.d(n,"frontMatter",(function(){return c})),a.d(n,"metadata",(function(){return s})),a.d(n,"rightToc",(function(){return i})),a.d(n,"default",(function(){return b}));var t=a(2),r=a(6),l=(a(0),a(131)),c={title:"JavaScript"},s={unversionedId:"cheatsheets/javascript",id:"cheatsheets/javascript",isDocsHomePage:!1,title:"JavaScript",description:"Basic structures",source:"@site/docs\\cheatsheets\\javascript.md",slug:"/cheatsheets/javascript",permalink:"/docs/cheatsheets/javascript",version:"current",sidebar:"docs",previous:{title:"Data Structures",permalink:"/docs/cheatsheets/datastruct"},next:{title:"TypeScript",permalink:"/docs/cheatsheets/typescript"}},i=[{value:"Basic structures",id:"basic-structures",children:[{value:"Hoisting",id:"hoisting",children:[]},{value:"Assignment",id:"assignment",children:[]},{value:"THIS reference",id:"this-reference",children:[]},{value:"Arguments",id:"arguments",children:[]},{value:"Six falsy values",id:"six-falsy-values",children:[]},{value:"Six primitive values (+ Object)",id:"six-primitive-values--object",children:[]},{value:"For loops",id:"for-loops",children:[]},{value:"Destructuring assignment",id:"destructuring-assignment",children:[]},{value:"Template strings",id:"template-strings",children:[]},{value:"Rest and Spread operators",id:"rest-and-spread-operators",children:[]},{value:"Arrow functions",id:"arrow-functions",children:[]},{value:"Array operations",id:"array-operations",children:[]},{value:"Maps",id:"maps",children:[]},{value:"Sets",id:"sets",children:[]},{value:"Classes",id:"classes",children:[]},{value:"Promises",id:"promises",children:[]},{value:"Async/await",id:"asyncawait",children:[]}]},{value:"Advanced structures",id:"advanced-structures",children:[{value:"Curried functions",id:"curried-functions",children:[]},{value:"Iterators",id:"iterators",children:[]}]},{value:"Generators",id:"generators",children:[{value:"Tagged template literals",id:"tagged-template-literals",children:[]},{value:"Enhanced object properties",id:"enhanced-object-properties",children:[]},{value:"Readonly properties",id:"readonly-properties",children:[]},{value:"Getters and setters",id:"getters-and-setters",children:[]},{value:"Proxies",id:"proxies",children:[]},{value:"Modules",id:"modules",children:[]}]},{value:"Tips and tricks",id:"tips-and-tricks",children:[{value:"Creating own trim function",id:"creating-own-trim-function",children:[]},{value:"Transforming arguments object into an array",id:"transforming-arguments-object-into-an-array",children:[]},{value:"Closures inside loops",id:"closures-inside-loops",children:[]},{value:"Remove duplicities from an array",id:"remove-duplicities-from-an-array",children:[]},{value:"Get the last item in an array",id:"get-the-last-item-in-an-array",children:[]},{value:"Assigning operator in a constructor",id:"assigning-operator-in-a-constructor",children:[]},{value:"Freezing properties of an object",id:"freezing-properties-of-an-object",children:[]},{value:"Deep cloning and comparing",id:"deep-cloning-and-comparing",children:[]}]},{value:"Weird parts of JavaScript",id:"weird-parts-of-javascript",children:[]}],o={rightToc:i};function b(e){var n=e.components,a=Object(r.a)(e,["components"]);return Object(l.b)("wrapper",Object(t.a)({},o,a,{components:n,mdxType:"MDXLayout"}),Object(l.b)("h2",{id:"basic-structures"},"Basic structures"),Object(l.b)("h3",{id:"hoisting"},"Hoisting"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"JS moves ",Object(l.b)("inlineCode",{parentName:"li"},"var")," declarations all the way up to the top of the scope"),Object(l.b)("li",{parentName:"ul"},"solution: use ",Object(l.b)("inlineCode",{parentName:"li"},"let")," instead of ",Object(l.b)("inlineCode",{parentName:"li"},"var"))),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"\nif (mojo) {\n var dojo = 1\n}\n\n// becomes\nvar dojo\nif (mojo) {\n dojo = 1\n}\n\n")),Object(l.b)("h3",{id:"assignment"},"Assignment"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"let person = {\n name: 'Kunio Otani'\n}\n\n// assign copies the values from one ore more source to a target object\n// returns the target object\nObject.assign(person, {\n age: 42,\n nationality: 'JP'\n})\n\n// expression, returns the right side of the operator\nperson.age = 42\nperson.nationality = 'JP'\n\n")),Object(l.b)("h3",{id:"this-reference"},"THIS reference"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),'foo(); // "this" in foo refers to the global object\ntest.foo(); // "this" in foo refers to test \nnew foo(); // "this" in foo will refer to a newly created object \nfoo.apply(bar, [1, 2, 3]); // "this" in foo is set to bar\nfoo.call(bar, 1, 2, 3); // "this" in foo is set to bar\nfoo = () => { ... } // "this" is set to the surrounding scope\n')),Object(l.b)("h3",{id:"arguments"},"Arguments"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"every function scope can access a special variable ",Object(l.b)("inlineCode",{parentName:"li"},"arguments")," which holds a list of all function arguments"),Object(l.b)("li",{parentName:"ul"},"arrow functions, however, have only access to the arguments of the nearest non-arrow parent function")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function foo(a, b, c) {\n console.log(arguments[0]) // will print a\n}\n")),Object(l.b)("h3",{id:"six-falsy-values"},"Six falsy values"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"any other values is true"),Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"false"),", ",Object(l.b)("inlineCode",{parentName:"li"},"0"),", ",Object(l.b)("inlineCode",{parentName:"li"},"''"),", ",Object(l.b)("inlineCode",{parentName:"li"},"null"),", ",Object(l.b)("inlineCode",{parentName:"li"},"undefined"),", ",Object(l.b)("inlineCode",{parentName:"li"},"NaN"))),Object(l.b)("h3",{id:"six-primitive-values--object"},"Six primitive values (+ Object)"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"Boolean, Null, Undefined, Number, String, Symbol")),Object(l.b)("h3",{id:"for-loops"},"For loops"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"for-in - works for any object, not only arrays. ",Object(l.b)("strong",{parentName:"li"},"The order is undefined"))),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"for(let key in activeUsers) {\n console.log(activeUsers[key])\n}\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"for-of - works only for objects that have ",Object(l.b)("inlineCode",{parentName:"li"},"[Symbol.iterator]"))),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"for(let user of activeUsers) {\n console.log(user)\n}\n")),Object(l.b)("h3",{id:"destructuring-assignment"},"Destructuring assignment"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"array destructuring - allows to extract multiple array elements")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"let [ name1, name2 ] = names\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"ignoring second element")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"let [ name,, name3 ] = names\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"setting default values")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"let [ a = 1, b = 2, c = 3 ] = names\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"object destructuring - allows to extract attributes")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"// assign properties - bad way\nlet user = buildUser('Sam', 'Williams')\nlet first = user.first\nlet last = user.last\n// assign properties - good way\nlet { first, last, fullName } = buildUser('Sam', 'Williams')\nlet { fullName } = buildUser('Sam', 'Williams') // we need only fullName\n")),Object(l.b)("h3",{id:"template-strings"},"Template strings"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"let fullName = `${first} ${last}` // ` backtick must be used!!!\n")),Object(l.b)("h3",{id:"rest-and-spread-operators"},"Rest and Spread operators"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"denoted with three ellipses or periods"),Object(l.b)("li",{parentName:"ul"},"rest is used to represent an infinite number of arguments"),Object(l.b)("li",{parentName:"ul"},"spread is used to allow an iterable object to be expanded"),Object(l.b)("li",{parentName:"ul"},"rest destructuring")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function fn(num1, num2, ...args) { } /// args always goes last\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"destructured rest")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function fn(...[n1, n2, n3]) {}\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"spread operator")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function myFunction(n1, n2, n3) { ... }\n \nconst values = [ 1, 2, 3 ]\n \nmyFunction(...values)\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"object destructuring")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"const { firstNamne, lastName } = obj\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"destructuring into a new variable")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"const { firstName: first, lastName } = obj\nconsole.log(first)\n")),Object(l.b)("h3",{id:"arrow-functions"},"Arrow functions"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"anonymous, not bound to an identifier"),Object(l.b)("li",{parentName:"ul"},"are callable but not constructable (you can't use ",Object(l.b)("inlineCode",{parentName:"li"},"new")," operator)")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"// old way\nTagComponent.prototype.render = function(){\n getRequest(this.urlPath, function(data) {\n // this points to getRequest() scope\n displayTags(this.targetElement, ... tags) \n })\n}\n\n// a regular function\nconst fn1 = function(a, b) { return a + b }\n\n// arrow function\nconst fn2 = (a, b) => { return a + b }\n\n// arrow function without return keyword\nconst fn3 = (num1, num2) => num1 + num2\n")),Object(l.b)("h3",{id:"array-operations"},"Array operations"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"mutating arrays")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"const mutatingAdd = [1, 2, 3]\nmutatingAdd.push(4) // [1, 2, 3, 4]\nmutatingAdd.unshift(0) // [0, 1, 2, 3, 4]\n\n// Immutable operations over arrays \nconst arr1 = [1, 2]\nconst arr2 = [3, 4]\n\nconst arr3 = arr1.concat(arr2) // [1, 2, 3, 4]\nconst arr3 = [...arr1, ...arr2]// [1, 2, 3, 4]\nconst arr4_altern = [0, ...arr1] //[0, 1, 2]\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"remove strings from an array")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"const arr = [0, 1, 2]\nconst tailArr = arr.splice(-1) // [2]\nconsole.log(arr) // [0, 1]\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"slice and update")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"const numbers = [0, 1, 2, 3, 4]\nconst lessThanThree = numbers.slice(0, 3) // [0, 1, 2]\nconst moreThanTwo = numbers.splice(2, numbers.length) // [2, 3, 4] \n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"other functions")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"concat, entries, fill, filter, find, flat, flatMap, forEach, join, \nincludes, keys, map, push, pop, reduce, reverse, shift, slice, \nsort, splice, unshift, values\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"sorting arrays")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"// sorting function: \n// if < 0, then a < b if == 0, then a == b if > 0, then b > a\nnums.sort((a,b) => {\n return a-b // ascending \n})\n\nnums.sort((a,b) => {\n return b-a // descending \n})\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"generating a sequence")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"const indices = Array.from(Array(10).keys())\nconsole.log(indices) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n")),Object(l.b)("h3",{id:"maps"},"Maps"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"when using objects as maps, their keys are always converted to strings"),Object(l.b)("li",{parentName:"ul"},"Maps can't be serialized into JSON, yet they can be iterated via for-of loop")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"let totalReplies = new Map()\ntotalReplies.set(user1, 5) \ntotalReplies.set(user2, 42)\nlet has = totalReplies.has(user1)\ntotalReplies.delete(user1)\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"WeakMap")," - only objects can be passed as keys, aren't iterable, better with memory")),Object(l.b)("h3",{id:"sets"},"Sets"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"let tags = new Set()\ntags.add('JavaScript')\ntags.add({version : '2015'})\n\nlet [first] = tags // first item\n")),Object(l.b)("h3",{id:"classes"},"Classes"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"old way (ES5)")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function SponsorWidget(name, description, url){\n this.name = name\n this.description = description\n this.url = url\n}\n\nSponsor.prototype.render = function(){\n \n}\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"new way (ES6+), ",Object(l.b)("inlineCode",{parentName:"li"},"class")," is only a sugar syntax")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"class SponsorWidget {\n myVar = 12\n myOtherVar\n \n constructor(name description, url){\n this.name = name\n this.description = description\n this.url = url\n }\n \n render(){ \n let link = this._buildLink(this.url)\n }\n \n _buildLink(url) { // underscore is a convention for private method\n \n }\n}\n\nclass SponsorWidget extends Widget {\n constructor(name, description, url) {\n super()\n }\n \n render() {\n super.render() // parent version\n let parsedName = this.parse(this.name)\n let css = this._buildCss()\n }\n}\n")),Object(l.b)("h3",{id:"promises"},"Promises"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"three states - pending, fulfilled, rejected"),Object(l.b)("li",{parentName:"ul"},"handlers - ",Object(l.b)("inlineCode",{parentName:"li"},"then()"),", ",Object(l.b)("inlineCode",{parentName:"li"},"catch()"),", ",Object(l.b)("inlineCode",{parentName:"li"},"finally()")),Object(l.b)("li",{parentName:"ul"},"when ",Object(l.b)("inlineCode",{parentName:"li"},"Promise.then()")," is called, it returns a new promise in the pending state"),Object(l.b)("li",{parentName:"ul"},"when ",Object(l.b)("inlineCode",{parentName:"li"},"Promise.catch()")," is called, it internally calls ",Object(l.b)("inlineCode",{parentName:"li"},"Promise.then(undefined, rejectHandler)"))),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"const myPromise = new Promise((resolve, reject) => {\n reject(new Error())\n})\n\nconst myPromise = new Promise((resolve, reject) => {\n setTimeout(() => { resolve('Done!')}) // also works\n})\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"error handling")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"myPromise.then(() => {}, error => console.log(error))\n\nPromise.resolve('Resolve').then(console.log) // prints Resolve\nPromise.reject('Reject').catch(console.log) // prints Reject\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"combined promises")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"await Promise.all([\n resolveAfter1Second(),\n resolveAfter2Seconds(),\n])\n")),Object(l.b)("h3",{id:"asyncawait"},"Async/await"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"async")," function returns a promise - all async functions can have ",Object(l.b)("inlineCode",{parentName:"li"},"then()")," and ",Object(l.b)("inlineCode",{parentName:"li"},"catch()")," handlers"),Object(l.b)("li",{parentName:"ul"},"if we don't return a promise, JS will do it automagically!")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"async function example1() {\n return 'Hello' // JS will wrap this into a promise\n}\n \nasync function example2() {\n return Promise.resolve('World')\n}\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},Object(l.b)("inlineCode",{parentName:"li"},"await")," can be used only within an ",Object(l.b)("inlineCode",{parentName:"li"},"async")," function"),Object(l.b)("li",{parentName:"ul"},"error rejection")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"try {\n const value1 = await Promise.reject('Error')\n} catch(err) {\n \n}\n")),Object(l.b)("h2",{id:"advanced-structures"},"Advanced structures"),Object(l.b)("h3",{id:"curried-functions"},"Curried functions"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"multiple arrow functions, can be used to wrap event handlers with additional parameters")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"const three = a => b => c => a + b + c\nthree(1)(2)(3)\n\n// equivalent:\nconst three = (a) => {\n return (b) => {\n return (c) => {\n return a + b + c\n }\n }\n}\n")),Object(l.b)("h3",{id:"iterators"},"Iterators"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"we have to define a function that takes a collection in as the parameter and returns an object which ",Object(l.b)("strong",{parentName:"li"},"must")," have property ",Object(l.b)("inlineCode",{parentName:"li"},"next")),Object(l.b)("li",{parentName:"ul"},"when ",Object(l.b)("inlineCode",{parentName:"li"},"next")," is called, the iterator steps to the next value in the collection and returns an object with the value and the done status of the iteration")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function createIterator(array){\n let currIdx = 0\n return {\n next() {\n return currIdx < array.lenth ? {\n value: array[currIdx++], done: false,\n } : { done: true }\n },\n }\n}\n")),Object(l.b)("h2",{id:"generators"},"Generators"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"provide an iterative way to build a collection of data"),Object(l.b)("li",{parentName:"ul"},"can be used for asynchronous processing also")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function *nameList(){\n yield 'Sam' // { done : false, value: 'Sam' }\n yield 'Tyler' // { done : false, value: 'Tyler' }\n}\n\nfor(let name of nameList()) {...} // usage\nlet names = [...nameList()]\n")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function *gen() {\n let i = 0\n while(true) {\n yield i++ \n }\n}\n")),Object(l.b)("h3",{id:"tagged-template-literals"},"Tagged template literals"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"can be parsed with tag functions and can return a manipulated string")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function tagFunction(strings, param) {\n return strings[0] + param\n}\n \nconst tagged = tagFunction`We have ${num} param`\n")),Object(l.b)("h3",{id:"enhanced-object-properties"},"Enhanced object properties"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"ES6 added 3 ways to simplify the creation of object literals"),Object(l.b)("li",{parentName:"ul"},"object properties")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function getPersonES6(name, age, height) {\n return {\n name,\n age,\n height \n }\n}\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"function declaration")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function getPersonES5(name, age, height) {\n return {\n getAge: function() { return age }\n }\n}\n \nfunction getPersonES6(name, age, height) {\n return {\n getAge() { return age }\n }\n}\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"computed properties")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"const personES5 = {\n lastName: 'Smith'\n}\npersonES5[varName] = 'John'\n \nconst personES6 = {\n lastName: 'Smith',\n [varName]: 'John',\n}\n")),Object(l.b)("h3",{id:"readonly-properties"},"Readonly properties"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"var a = {}\nObject.defineProperty(a, 'mojo', {\n value: 15,\n writable: false\n})\n")),Object(l.b)("h3",{id:"getters-and-setters"},"Getters and setters"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function Foobar () {\n var _foo // true private property\n \n Object.defineProperty(obj, 'foo', {\n get: function () { return _foo },\n set: function (value) { _foo = value }\n })\n}\n")),Object(l.b)("h3",{id:"proxies"},"Proxies"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"function Foo() {\n return new Proxy(this, {\n get: function (object, property) {\n if (Reflect.has(object, property)) {\n return Reflect.get(object, property)\n } else {\n return function methodMissing() {\n console.log(`You called ${property} but it doesn't exist!`)\n }\n }\n }\n })\n}\n")),Object(l.b)("h3",{id:"modules"},"Modules"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"old way (ES5)")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"// anonymous namespaces \n(function () {\n // a self contained namespace \n window.foo = function() {\n // exposed closure \n }\n})() // execute immediately\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"new way (ES6+)",Object(l.b)("ul",{parentName:"li"},Object(l.b)("li",{parentName:"ul"},"we can use ",Object(l.b)("inlineCode",{parentName:"li"},"require")," or ",Object(l.b)("inlineCode",{parentName:"li"},"import"))))),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"// flas-message.js\nexport default function(message){\n alert(message)\n}\n\n// app.js\nimport flashMessage from './flash-message'\nflashMessage('Hello')\n")),Object(l.b)("h2",{id:"tips-and-tricks"},"Tips and tricks"),Object(l.b)("h3",{id:"creating-own-trim-function"},"Creating own trim function"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"String.prototype.trim = function(){return this.replace(/^s+|s+$/g, '')} \n")),Object(l.b)("h3",{id:"transforming-arguments-object-into-an-array"},"Transforming arguments object into an array"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"var argArray = Array.prototype.slice.call(arguments)\n")),Object(l.b)("h3",{id:"closures-inside-loops"},"Closures inside loops"),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"wrong")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"var funcs = []\nfor (var i = 0; i < 3; i++) {\n funcs[i] = function() {\n console.log('i value is' + i) // i value is 3, always!\n }\n}\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"good")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"for (var i = 0; i < 3; i++) {\n funcs[i] = (function(value) {\n console.log('i value is ' + i) // 0, 1, 2\n })(i)\n}\n")),Object(l.b)("ul",null,Object(l.b)("li",{parentName:"ul"},"even better")),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"for (let i = 0; i < 3; i++) {\n funcs[i] = () => {\n console.log('i value is ' + i) // 0, 1, 2\n }\n} \n")),Object(l.b)("h3",{id:"remove-duplicities-from-an-array"},"Remove duplicities from an array"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"const arr = [...new Set([1, 2, 3, 3])] // [1, 2, 3]\n")),Object(l.b)("h3",{id:"get-the-last-item-in-an-array"},"Get the last item in an array"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\nconsole.log(array.slice(-1)) // Result: [9]\n")),Object(l.b)("h3",{id:"assigning-operator-in-a-constructor"},"Assigning operator in a constructor"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"\nclass Polygon {\n constructor(options) { // many attributes\n Object.assign(this, options)\n }\n}\n")),Object(l.b)("h3",{id:"freezing-properties-of-an-object"},"Freezing properties of an object"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"\nconst obj = { foo1: 'bar1', foo2: { value: 'bar2' } };\n\nObject.freeze( obj );\n\nobj.foo = 'foo'; // doesn't change the property, doesn't throw Error\nobj.foo2.value = 'bar3'; // does change the value - it's nested!\n\n")),Object(l.b)("h3",{id:"deep-cloning-and-comparing"},"Deep cloning and comparing"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"JSON.stringify(myObj1) === JSON.stringify(myObj2) \n")),Object(l.b)("h2",{id:"weird-parts-of-javascript"},"Weird parts of JavaScript"),Object(l.b)("pre",null,Object(l.b)("code",Object(t.a)({parentName:"pre"},{className:"language-javascript"}),"false.toString() // false \nfunction Foo() { } \nFoo.bar = 1 \n\n2.toString() // SyntaxError, dot here means a floating point literal \n(2).toString() // OK \n2 .toString() // OK\n2..toString() // OK\n\nvar foo = {} // new object, derives from Object.prototype \n\n// property access \nvar foo = { name : 'kitten' }\nfoo.name // OK \nfoo['name'] // OK \nvar get = 'name'\nfoo[get] // OK \nfoo.1234 // ERROR \nfoo['1234'] // OK\n\n// delete is the only way how to remove a property\n// undefined or null only removes the VALUE \nvar obj = { bar: 1 }\nobj.bar = undefined // removes value \ndelete obj.bar // removes key\n\n// you can't delete global variables declared by var!\nvar mojo = 12\n// use assignment to a global property instead, \n// if you need to create a global variable\nglobal.mojo = 12\n\n// arrays \nnew Array(3) // [undefined, undefined, undefined], \nnew Array('3') // ['3']\n\n\n// equality operator \n'' == '0' // false \n0 == '' // true \n0 == '0' // true\nfalse == 'false' // false \nfalse == '0' // true \nfalse == undefined // false \nfalse == null // false \nnull == undefined // true \n{ } === {} // false \nnew String('foo') === 'foo' // false \n10 == '10' // true \n10 == '+10' // true \n10 == '010' // true \nisNan(null) == false // true, null converts to 0\nnew Number(10) === 10 // false, object !== number \n\n// typeof operator \n'foo' // string \nnew String('foo') // object \ntrue // boolean \n[1, 2, 3] // object \nnew Function() // function \n\n// casting \n'' + 10 === '10' // true \n!!'foo' // true \n!!true // true\n\n// boolean evaluation\nnew Boolean() // false\nnew Boolean(0) // false (for any falsy parameter)\n// but careful, (new Boolean(anything) === true/false) -> always FALSE\nnew Boolean(true) // true (for any truthy parameter)\n\n\n// why is this comma recommended? Because it prevents any previous code from \n// executing your code as the arguments to that function\n;(async () => { ... }\n\n")))}b.isMDXComponent=!0}}]);