// crreate a whole random number between [0,20) function wholeRandomNumber(){ return Math.floor(Math.random() * 20) } console.log(wholeRandomNumber()) // random numbers within a range [min, max] function randomRange(min, max){ return Math.floor(Math.random()*(max-min + 1)) + min } console.log(randomRange(1,2)) // parseInt // return integer from a string. It will returrn NaN if string cannot be converted to a number function convertToIntegerr(str){ return parseInt(str) } console.log("parseInt: "+ convertToIntegerr("55")) console.log("parseInt: "+ convertToIntegerr("ABC")) // parseInt also takes in a radix. So it can convert a binary/octal string to base 10 integer. // Radix is the base, like 2 for binary. Default is base 10 function convertToIntegerradix(str, base){ return parseInt(str, base) } console.log("parseInt: "+ convertToIntegerradix("10001", 2)) console.log("parseInt: "+ convertToIntegerradix("a0", 16)) // Object.freeze // use this to make objects read-only // note that using const makes simple variables (that contain datatypes other than object, array, dict) read-only // objects, arrays can be mutated even after being declared const. To make these read-only, use Object.freeze function freezeObj(){ "use strict" const MATH_CONSTANTS = { PI: 3.14 } Object.freeze(MATH_CONSTANTS) try { MATH_CONSTANTS.PI = 99 } catch( ex ){ console.log(ex) } return MATH_CONSTANTS.PI } console.log("freeze object: " + freezeObj()) // anonymous function // below are all equivalent functions const todaysDate = function(){ return new Date() } const todaysDateArrow = () => { return new Date() } // if the function has just one line, do this const todaysDateArrowOneLiner = () => new Date() // Arrow funtions work very well with Higher Order Functions like map, filter and reduce // i.e. whenever one function takes another function as an arguement, // its a good candidate for arrow function // example: iterate over an array and filter all positive integers and square them and return their sum myArr = [1,-2, 1.5, 3.4, 5] const sum = arr => arr.filter(num=> Number.isInteger(num) && num > 0) .map(x => x**2) .reduce((acc, currVal)=>acc+currVal, 0) console.log("arrow higher order sum: " + sum(myArr)) // rest operator allows you to create a function with variable number of aguments // rest opeartor is ... // ...args what this does is that rest operator creates an array and calls it args const secondSum = (...args) => args.filter(num=> Number.isInteger(num) && num > 0) .map(x => x**2) .reduce((acc, currVal)=>acc+currVal, 0) console.log("arrow higher order sum using rest operator: " + secondSum(1,2,3)) // spread operator looks exactly like rest operator. three dots. // but it expands an already existing array. So, it takes an array and spreads it out // into its individual parts // you can only use spread operator in an arguement to a function or in an array literal const myArray = [1,2,3] console.log("arrow higher order sum using rest and spread operator: " + secondSum(...myArray)) myArrayCopy = [...myArray] // Destructuring // its a way to neatly assign values taken from an object, to variables var voxel = {x:3.6, y:7.4, z:6.4} // we wish to get values contained inside voxel object // old way var a = voxel.x var b = voxel.y var c = voxel.z // using destructuring. we are creating three variables a, b and c and // assigning them values in x, y and z properties of the object const {x:a1, y:b1, z:c1} = voxel // a = 3.6, b = 7.4 and c = 6.4 const {x, y, z} = voxel console.log(`shortcut destructuring: x:${x} y:${y} z:${z}`) // nested destructuring. We will destructure nested objects const myNestedObj = { entry1: { first:"entry1-first", second:"entry1-second" }, entry2: { first:"entry2-first", second:"entry2-second" } } const { entry1: { first: entry1First}} = myNestedObj console.log(`nested destructuring: entry1First:${entry1First}`) // use destructuring assignment to assign variables from arrays // the difference between destructuring from an array to destructuring from an object // is that in case of array, we cannot specify what object to pick. It just goes in // accordance to the order. const [a2, b2] = [1,2,3,4] // only first two elements will be destructured. rest are omitted. console.log(`a1:${a2} b1:${b2} array destructuring`) // use destruturing assignment with rest operator const source = [1,2,3,4,5,6,7] // I want to omit first two and capture the rest in an array const [,,...myarr1] = source console.log(`destruturing with rest operator: myarr1:${myarr1}`) // use destructuring objects to pass in function arguments const myobj = { min: "min-val", max: "max-val", letter: "letter-val", better: "better-val" } const myFunc = ({ min, max }) => { console.log(`destructured objects in function args: min:${min} max:${max}`) } myFunc(myobj) // write consise object literal declarations using simple fields // say that we have a function that creates an object and // the object literal has key, value pairs like so: // long way const createPerson_longWay = (name, age, gender) => { return { name: name, age: age, gender: gender } } // short way const createPerson_shortWay = (name, age, gender) => ({name, age, gender}) console.log(createPerson_longWay('Ting_name long way', 20, 'ting_gender long way')) console.log(createPerson_shortWay('Ting_name short way', 20, 'ting_gender short way')) // write consise declarative functions // explanation: an object can contain a function // long way to put a function within an object const bicycle_long_way = { gear: 2, setGear: function(newGear){ "use strict" this.gear = newGear } } bicycle_long_way.setGear(3) console.log(`bicycle long way: ${ bicycle_long_way.gear }`) // short way to put a function within an object const bicycle_short_way = { gear: 2, setGear(newGear){ "use strict" this.gear = newGear } } bicycle_short_way.setGear(3) console.log(`bicycle short way: ${ bicycle_short_way.gear }`) // use class syntax to define a constructor function // ES6 provides syntactic sugar to help create objects using class keyword // older way to create an object var SpaceShuttle_old = function(targetPlanet){ this.targetPlanet = targetPlanet } // here the above function is essentially a constructor function that creates an // object via new keyword as shown below var zeus = new SpaceShuttle_old('Jupiter') console.log(`old way without class: ${zeus.targetPlanet}`) // class syntax replaces the constructor function creation class SpaceShuttle { constructor(targetPlanet){ this.targetPlanet = targetPlanet } } var new_zeus = new SpaceShuttle('Jupiter new') console.log(`new way with class: ${new_zeus.targetPlanet}`) // use getters and setters to control access to an object // getters and setters, although implemented as function, act like properties // when accessed class Book{ constructor(name){ this._name = name } get name(){ return this._name } set name(updatedName){ this._name = updatedName } } var book = new Book('Godzilla') console.log(`constructed book name: ${book.name}`) book.name = 'updated Godzilla' console.log(`updated book name: ${book.name}`) // difference between import and require // require was the old way of importing functions/variables from another file // import and export are new ES6 syntax to import/export only certain parts of an external file
No Comments
You can leave the first : )