# [JavaScript] :::info :bulb: Hello all, this is an informal learning space for JS. The learning materials come from codecademy, which is a great learning source, and I welcome everyone to pick up programming skills on it! ::: ## Data Type (Primitive data type) * Number * BigInt * String * concatenation, e.g., 'word1'+"word2" * Boolean * Null * Undefined * Symbol * Object ## Property * The [prototype] is a property available with all JavaScript objects. * The prototype property allows you to add new properties and methods to strings. ## Method : action we perform * e.g., console.log (console is an object, .log() is a method) ## JS built-in objects * e.g., Math.random() ## Interpolation * e.g., console.log(`I own a pet ${myPet}.`); ## short-circuit evaluation ```javascript let tool = 'marker' let stationary = tool || "pen" ``` ## function expression * function declaration: ```function getScore()``` * function expression: ``` const totalScore = function(score, subject)``` * Arrow functions : ``` const totalScore = (score, subject)=>{}``` * concise arrow functions: ``` const totalScore = score => score*10``` * higher order function: function is first-class object ## Ternary operator `isNightTime ? console.log('Turn on the lights!') ` ## Array each content item inside an array is `element` ## Advanced Objects * arrow function defined in an object inherently binds an defined `this` value. ```javascript const goat = { dietType: 'herbivore', makeSound() { console.log('baaa'); }, diet: () => { console.log(this.dietType); } }; goat.diet(); // Prints undefined ``` In the code snippet above, the value of this is the global object, or an object that exists in the global scope, which doesn’t have a `dietType` property and therefore returns `undefined`. ## Getters and Setters :::success * Getters are methods that get and return the internal properties of an object. * Setter methods reassign values of existing properties within an object. source: [Setters](https://www.codecademy.com/courses/introduction-to-javascript/lessons/advanced-objects/exercises/setters) ::: * robot there is a getter method for numOfSensors but no setter method. * Add a setter method named numOfSensors using the set keyword. Provide a parameter of num. ```javascript const robot = { _model: '1E78V2', _energyLevel: 100, _numOfSensors: 15, get numOfSensors(){ if(typeof this._numOfSensors === 'number'){ return this._numOfSensors; } else { return 'Sensors are currently down.' } }, set numOfSensors(num){ if(typeof num === 'number' && num >=0){ this._numOfSensors = num; }else { console.log('Pass in a number that is greater than or equal to 0'); }; } }; robot.numOfSensors = 100; //Use the numOfSensors setter method on robot to assign _numOfSensors to 100. console.log(robot.numOfSensors); ``` :star: _energyLevel代表privacy。 place an underscore _ before the name of a property to mean that the property should not be altered. ## Factory Function create many instances of an object quickly 此Function目的,就是用來大量製造object ```javascript const monsterFactory = (name, age, energySource, catchPhrase) => { return { name: name, age: age, energySource: energySource, scare() { console.log(catchPhrase); } } }; const ghost = monsterFactory('Ghouly', 251, 'ectoplasm', 'BOO!'); ghost.scare(); // 'BOO!' ``` ## Class & inheritance ```javascript class Cat extends Animal { constructor(name, usesLitter) { super(name); this._usesLitter = usesLitter; } } ``` * `extends` makes the methods of animal class available in the cat class * must always call the `super` method before you can use the this keyword ## Static Mehtods * static methods are called directly from the class, but not from an instance of the class. * If you call static methods by class instance, there will be `TypeError` ```javascript class HospitalEmployee { constructor(name) { this._name = name; this._remainingVacationDays = 20; } get name() { return this._name; } get remainingVacationDays() { return this._remainingVacationDays; } // create a static method static generatePassword(){ return Math.floor(Math.random()*10000) } } console.log(HospitalEmployee.generatePassword()) //generate a random number ``` ## Promise * automatically call `executor` function, then it starts an asynchronous operation. * `executor` function usually refer to two parameters, `resolve()` and `reject()` * .then: higher-order function— it takes two callback functions as arguments. We refer to these callbacks as handlers. When the promise settles, the appropriate handler will be invoked with that settled value. * The success callback is sometimes called the “success handler function” or the onFulfilled function. The failure callback is sometimes called the “failure handler function” or the onRejected function. ### Promise.all() * To maximize efficiency we should use concurrency, multiple asynchronous operations happening together. With promises, we can do this with the function `Promise.all()`. ## Async await * Javascript uses event-loop instead of stopping the execution while it waits. * Three ways to write async actions ```javascript const fs = require('fs'); const promisifiedReadfile = require('./promisifiedReadfile'); // Here we use fs.readfile() and callback functions: fs.readFile('./file.txt', 'utf-8', (err, data) => { if (err) throw err; let firstSentence = data; fs.readFile('./file2.txt', 'utf-8', (err, data) => { if (err) throw err; let secondSentence = data; console.log(firstSentence, secondSentence); }); }); // Here we use native promises with our "promisified" version of readfile: let firstSentence; promisifiedReadfile('./file.txt', 'utf-8') .then((data) => { firstSentence = data; return promisifiedReadfile('./file2.txt', 'utf-8'); }) .then((data) => { let secondSentence = data; console.log(firstSentence, secondSentence) }) .catch((err) => {console.log(err)}); // Here we use promisifiedReadfile() again but instead of using the native promise .then() syntax, we declare and invoke an async/await function: async function readFiles() { let firstSentence = await promisifiedReadfile('./file.txt', 'utf-8'); let secondSentence = await promisifiedReadfile('./file2.txt', 'utf-8'); console.log(firstSentence, secondSentence); } readFiles(); ``` ### await * The `await` keyword can only be used inside an `async` function. `await` is an operator: it returns the resolved value of a promise. * `await` returns the resolved value of the awaited promise. ### try...catch * use try...catch statements within our async functions for error handling. ## Request with fetch API * JavaScript uses an event loop to handle asynchronous function calls. When a program is run, function calls are made and added to a stack. ### Approach 1: fetch API with .then * We can chain `.then()` methods to handle `promises` returned by the `fetch()` function. ```javascript const apiKey = '60b2f9aa6133458a9e6b7871725e5bc9'; const url = 'https://api.rebrandly.com/v1/links'; // Some page elements const inputField = document.querySelector('#input'); const shortenButton = document.querySelector('#shorten'); const responseField = document.querySelector('#responseField'); // Asynchronous functions const shortenUrl = () => { const urlToShorten = inputField.value; const data = JSON.stringify({destination: urlToShorten}); fetch(url, { method: 'POST', headers: { 'Content-type': 'application/json', 'apikey': apiKey }, body: data }) .then(response=> { if(response.ok){ return response.json() } throw new Error('Request failed!') },(networkError => { console.log(networkError.message) })) .then((jsonResponse)=> { renderResponse(jsonResponse) }) } ``` ### Approach 2: fetch API with await ```javascript const apiKey = 'your-API-key'; const url = "https://api.rebrandly.com/v1/links"; // Some page elements const inputField = document.querySelector("#input"); const shortenButton = document.querySelector("#shorten"); const responseField = document.querySelector("#responseField"); // Asynchronous functions const shortenUrl = async () => { const urlToShorten = inputField.value; const data = JSON.stringify({ destination: urlToShorten }); try { const response = await fetch(url, { method: "POST", body: data, headers: { "Content-type": "application/json", apikey: apiKey, }, }); if (response.ok) { const jsonResponse = await response.json(); renderResponse(jsonResponse); } } catch (error) { console.log(error); } }; ``` ## Error * to create a customized error, you can write `new Error('a customized message')` ### throw * When we use the `throw` keyword, the error is thrown and code after the throw statement will not execute. * example : `throw Error('message')` ## Currying JS * ## hoisting in JS * JavaScript hoists function declarations, including the function body, to the top of its scope * var variables are hoisted to the top of function blocks. * Since the release of ES6, there are really no situations where it is preferable to use var variables. * let and const differ from var in how they initialize as well; while the names are hoisted, they are not initialized. * [MDN Hoisting in JS] ## event loop * Since JavaScript is single-threaded, as we saw in the for loop example, we’ll never have that flavor of “true” concurrency. * The event loop is made up of these parts: * Memory Heap * a block of memory where we store objects in an unordered manner. JavaScript variables and objects that are currently in use are stored in the heap * The heap provides dynamic memory allocation at runtime for data types that don’t have a fixed size, like objects and functions. * Objects are stored in heap while the fixed-size reference is stored in the call stack, so when you modify a value, you are changing the reference. * Call Stack * The stack, or call stack, tracks what function is currently being run in your code. * Frames enter the stack in a last in, first out (LIFO) order. ![image](https://hackmd.io/_uploads/HyLMrMdVp.png) * Event Queue * a list of messages corresponding to functions that are waiting to be processed, such as various web APIs or async functions. * event queue in context: When the call stack is empty, if there is anything in the event queue, the event loop can add those one at a time to the stack for execution. * Event Loop * Node or Web APIs ### Memory leaks ## Design pattern * [singleton patter- by WDS] [prototype]:https://www.w3schools.com/jsref/jsref_prototype_string.asp [MDN Hoisting in JS]: https://developer.mozilla.org/en-US/docs/Glossary/Hoisting [singleton patter- by WDS]: https://www.youtube.com/watch?v=sJ-c3BA-Ypo