Javascript Flashcards
TODO need to add the following: - Generators - Fetch
Create a class with a constructor, public field/method, private field/method, static field/method, private static method, and a property with accessor.
class MyClass { // Constructor constructor() { // Constructor body } // Instance field myField = "foo"; // Instance method myMethod() { // myMethod body } // Static field static myStaticField = "bar"; // Static method static myStaticMethod() { // myStaticMethod body } // Static block static { // Static initialization code } // Fields, methods, static fields, and static methods all have // "private" forms #myPrivateField = "bar"; } // Accessor methods, allow you to act on the property directly. myClass.myProp get myProp() { return 1; } set myProp(value) { this.somethingElse = 1; }
Give a brief overview of the major iterations of Javascript
The web started out completely static. Over time, some simple client-side logic was made possible via scripting languages with conflicting compatibility. Standardization came in the form of ECMAScript (really the javascript standard). ES1 (1997)
After that the major releases are ES3, ES5, then ES6 which has released updates roughly every year since 2015.
ES3 (1999) introduced a number of features,
- strict equality ===
- try/catch
- regexp
ES5 (2009)
- “use strict”
- Array methods
- JSON handling
- getters/setters
ES6, generally speaking meant the need for the Babel transpiler to write code in ES6 and ship it with ES5 compatibility. New features include
- Classes
- Big arrow =>
- Destructuring and rest and spread operators
- let and const
- Promises and async/await
Discuss the different ways to declare variables and functions
// var var x = 2; // Creates a global variable when used outside a function (global is window in the browser) // var declarations are hoisted //let and const are ES6 features let: let x = 2; const: const x = 2; // A constant cannot change value through assignment or be re-declared while the script is running. It must be initialized to a value. const x; // ERROR //let and const have the scope of their containing block statement
=========
~~~
// Here x is an undeclared variable
x = 2;
// Declaring but not assigning results in undefined values.
var x; // x === undefined
let x; // x === undefined
// Functions
// Function Declaration (it is hoisted)
foo(); // “bar”
function foo() {
console.log(‘bar’);
}
//Function Expressions (not hoisted)
var baz = function() {
console.log(‘bar2’);
};
~~~
Create an array and iterate it with different methods
let arr = [1, 2, 3]; for (var i = 0; i < arr.length; i++) { console.log(arr[i] + ' at index ' + i); } arr.forEach((x, i) => console.log(x + ' at index ' + i)); for (const x of arr) { console.log(x); }
What are the different loops and show how to use them
for - loops through a block of code a number of times
for/of - loops through the values of an iterable object
for/in - loops through the properties of an object
while - loops through a block of code while a specified condition is true
do/while - also loops through a block of code while a specified condition is true
let arr = [1, 2, 3]; // for for (var i = 0; i < arr.length; i++) { console.log(arr[i] + ' at index ' + i); } // for/of for (const x of arr) { console.log(x); } //for/in only enumerable string properties const person = {fname:"John", lname:"Doe", age:25}; let text = ""; for (const x in person) { text += person[x]; } // while while (i < 10) { text += "The number is " + i; i++; } //do while do { text += "The number is " + i; i++; } while (i < 10);
Implement ES6 class features using ES5 javascript.
function Apple(size) { this.color = red; this.size = size; } Apple.prototype.appleMethod = function() { return this.color + this.size; } // or this way const myObject = { myField: 1, myMethod: function(params) { // do something }, // this works too! myOtherMethod(params) { // do something else }, //getters and setters get b() { return this.myField + 1; }, set b(x) { this.myMethod(x); }, // Static methods and fields don't really exist, but you can define a prototype with methods and properties shared by all objects which set our prototype. }
What is a javascript object, discuss the prototype
An object is just a collection of key/value pairs. Additionally it inherits through the prototype chain, all the way up to the object prototype.
What is hoisting?
JavaScript Hoisting refers to the process whereby the interpreter appears to move the declaration of functions, variables or classes to the top of their scope, prior to execution of the code.
// Function hoisting catName("Tiger"); function catName(name) { console.log(`My cat's name is ${name}`); } /* The result of the code above is: "My cat's name is Tiger" */ // var hoisting console.log(num); // Returns 'undefined' from hoisted var declaration (not 6) var num; // Declaration num = 6; // Initialization console.log(num); // Returns 6 after the line with initialization is executed.
Class hoisting:
Classes defined using a class declaration are hoisted, which means that JavaScript has a reference to the class. However the class is not initialized by default, so any code that uses it before the line in which it is initialized is executed will throw a ReferenceError.
Function expressions and class expressions are not hoisted.
Explain how the logical operators like && work, what do they return and what are they checking
Logical AND, &&
like expr1 && expr2
Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.
Logical OR, ||
like expr1 || expr2
Returns expr1 if it can be converted to true; otherwise, returns expr2. Thus, when used with Boolean values, || returns true if either operand is true; if both are false, returns false.
Logical NOT, !
like !expr1
Returns false if its single operand that can be converted to true; otherwise, returns true.
These operators with 2 operands are short circuiting operations.
List javascript types
Seven data types that are primitives:
Boolean - true and false.
null - A special keyword denoting a null value
undefined - A top-level property whose value is not defined.
Number - An integer or floating point number. For example: 42 or 3.14159.
BigInt - An integer with arbitrary precision. For example 9007199254740992n
String - A sequence of characters that represent a text value. For example: “Howdy”.
Symbol - A data type whose instances are unique and immutable.
Object - named containers for values
== vs ===
== is loose equality check, does type conversions
=== adds a typeof check, values must be of the same type
What is truthy and what is falsy
In JavaScript, a truthy value is a value that is considered true when encountered in a Boolean context. All values are truthy unless they are defined as falsy. That is, all values are truthy except false, 0, -0, 0n, “”, null, undefined, and NaN.
Show how to use a regexp
const re = /ab+c/; // Compiled at script load time const re = new RegExp('ab+c'); // Compiled at runtime const testStr = 'my test str'; re.exec(testStr); //returns an array or null, it's complicated... re.test(testStr); // returns true or false testStr.match(re); // returns array of matches or null testStr.replace(re, 'something'); testStr.search(re); //returns first index of or -1
Compare and contrast null vs undefined.
Undefined is the value of any object property not specifically assigned a value, it is also the value of an uninitialized var declaration. You can set values specifically to undefined though this is discouraged, null is better.
Show how to use promises and async/await, explain how promises work, what’s actually going on under the hood
doSomething() .then((result) => doSomethingElse(result)) .then((newResult) => doThirdThing(newResult)) .then((finalResult) => { console.log(`Got the final result: ${finalResult}`); }) .catch(failureCallback); // Equivalently async function foo() { try { const result = await doSomething(); const newResult = await doSomethingElse(result); const finalResult = await doThirdThing(newResult); console.log(`Got the final result: ${finalResult}`); } catch (error) { failureCallback(error); } } foo(); // Returns a pending promise which will eventually resolve with an undefined value
What is destructuring how do you use it
unpack values from arrays, or properties from objects, into distinct variables.
// Arrays let a, b, rest; [a, b] = [10, 20]; // a = 10 // b = 20 [a, b, ...rest] = [10, 20, 30, 40, 50]; // a = 10 // b = 20 // rest = [30,40,50] // when an destructured index does not exist const [a, b, c] = [1, 2]; // c = undefined // Unless using a default const [a, b, c = -1] = [1, 2] // c = -1 // Objects let person = { firstName: 'John', lastName: 'Doe' }; let { firstName: fname, lastName: lname } = person; // fname = 'John' // lname = 'Doe' // Shorthand when properties and variables have the same name let { firstName, lastName } = person; // firstName = 'John' // lastName = 'Doe' // Property that doesn't exist becomes undefined let { firstName, lastName, middleName } = person; // middleName = undefined // Or use a default let { firstName, lastName, middleName = 'unknown' } = person; // middleName = 'unknown' // Can also do nested destructuring let employee = { id: 1001, name: { firstName: 'John', lastName: 'Doe' } }; let { name: { firstName, lastName } } = employee; // firstName = 'John' // lastName = 'Doe' // Spread operator let person = {firstName: 'John', lastName: 'Doe', middleName: 'middle', age: 36 } let {firstName, lastName, ...theRest } = person // theRest = {middleName: 'middle, age: 36} // Destructure function arguments let display = ({firstName, lastName}) => console.log(`${firstName} ${lastName}`); let person = { firstName: 'John', lastName: 'Doe' }; display(person);
Rest and Spread syntax, what is it and how do you use it
Rest syntax (…) refers to two things
1) allows a function to accept an indefinite number of arguments as an array
function sum(...theArgs) { let total = 0; for (const arg of theArgs) { total += arg; } return total; } console.log(sum(1, 2, 3)); // expected output: 6 console.log(sum(1, 2, 3, 4)); // expected output: 10
2) Enables destructuring to assign a value with the rest of an object or array
const { a, ...others } = { a: 1, b: 2, c: 3 }; console.log(others); // { b: 2, c: 3 } const [first, ...others2] = [1, 2, 3]; console.log(others2); // [2, 3]
Spread syntax (…) expands iterables into function arguments or elements. expands object literals into key-value pairs
Used in 3 scenarios
1) Function arguments list (myFunction(a, …iterableObj, b))
function sum(x, y, z) { return x + y + z; } const numbers = [1, 2, 3]; sum(...numbers); // 6 // Could be used anywhere in the argument list function sum(v, w, x, y, z) { return v + w + x + y + z; } const numbers = [1, 2, 3]; sum(0, ...numbers, 4); // 10
2) Array literals ([1, …iterableObj, ‘4’, ‘five’, 6])
const parts = ['shoulders', 'knees']; const lyrics = ['head', ...parts, 'and', 'toes']; // ["head", "shoulders", "knees", "and", "toes"]
3) Object literals ({ …obj, key: ‘value’ }).
note: spread enumerates own properties
onst obj1 = { foo: 'bar', x: 42 }; const obj2 = { foo: 'baz', y: 13 }; const clonedObj = { ...obj1 }; // Object { foo: "bar", x: 42 } const mergedObj = { ...obj1, ...obj2 }; // Object { foo: "baz", x: 42, y: 13 }
String template literals, what do they do how to use them
Mainly for string interpolation
const five = 5; const ten = 10; console.log(`Fifteen is ${five + ten} and not ${2 * five + ten}.`); // "Fifteen is 15 and not 20."
Allows for multiline strings
console.log(`string text line 1 string text line 2`); // "string text line 1 // string text line 2"
Also can do tagged templates which allow you to define your own formatting function, not worth going into further.
What is strict mode, how do you use it
Mode that applies to either entire scripts or functions. At the top of either do 'use strict';
function myStrictFunction() { // Function-level strict mode syntax 'use strict'; function nested() { return 'And so am I!'; } return `Hi! I'm a strict mode function! ${nested()}`; } function myNotStrictFunction() { return "I'm not strict."; }
This mode applies a number of restrictions to normally “acceptable” javascript, namely to prevent unintentional errors.
For example, throwing an error when assigning to an undeclared variable (which normally would just create a global-scope variable).
Write a switch statement
const expr = 'Papayas'; switch (expr) { case 'Oranges': console.log('Oranges are $0.59 a pound.'); break; case 'Mangoes': case 'Papayas': console.log('Mangoes and papayas are $2.79 a pound.'); // expected output: "Mangoes and papayas are $2.79 a pound." break; default: console.log(`Sorry, we are out of ${expr}.`); }
Work with dates (create a date, get todays date, date manipulation, comparison)
// Different ways to create dates, these all create dates interpreted in local timezone. Could use Date.UTC() instead const now = new Date(); const birthday2 = new Date('1995-12-17T03:24:00') // This is ISO8601-compliant and will work reliably const birthday3 = new Date(1995, 11, 17) // the month is 0-indexed const birthday4 = new Date(1995, 11, 17, 3, 24, 0) const birthday5 = new Date(628021800000) // passing epoch timestamp // Do manipulation and comparison with getTime(), this returns milliseconds since epoch const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000); // Formatting date.toIsoString(); date.toLocaleString(); // lots of options in parameters, but is locale aware which is useful
What are javascript modules, how do you use them. How does that relate to CommonJS, UMD, NodeJS etc. What is the native support.
There were a number of third party tools to enable modularization of javascript. ES6 added import/export for native module support, the support is much better now in modern browsers. WebPack is a tool for putting all those pieces together with a huge number of other useful features/plugins. WebPack can interpret modules in a number of ways.
Using ES6 (native javascript) modules
// Export with the export keyword export const name = 'square'; export function draw(ctx, length, x, y, color) { ctx.fillStyle = color; ctx.fillRect(x, y, length, length); return { length, x, y, color }; } // Export multiple at the end of a module like so export { name, draw, reportArea, reportPerimeter }; // Import with the import keyword import { name, draw, reportArea, reportPerimeter } from './modules/square.js'; const myName = 'my ' + name; // In the index.html page, import the script with type="module" <script type="module" src="main.js"></script> // Can do a default export as follows export default randomSquare; export default function (ctx) { // … } // Them import without the curly braces import randomSquare from './modules/square.js'; import myFunction from './modules/square.js'; // Can rename both an import or an export using 'as' keyword export { function1 as newFunctionName, function2 as anotherNewFunctionName }; // inside main.js import { newFunctionName, anotherNewFunctionName } from './modules/module.js'; export { function1, function2 }; // inside main.js import { function1 as newFunctionName, function2 as anotherNewFunctionName, } from './modules/module.js'; // Could also import a "module object" with '*' export { field, moduleFunction }; import * as Module from './modules/module.js'; const myField = Module.field; const functionResult = Module.moduleFunction(); // Can export/import classes class Square { constructor(ctx, listId, length, x, y, color) { // … } draw() { // … } // … } export {Square}; // in another file... import {Square} from './modules/square.js'; const square1 = new Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue'); square1.draw(); square1.reportArea(); square1.reportPerimeter(); // Can aggregate modules in an new intermediary file // In file called shapes.js export { Square } from './shapes/square.js'; export { Triangle } from './shapes/triangle.js'; export { Circle } from './shapes/circle.js'; // Then import with import { Square, Circle, Triangle } from './modules/shapes.js'; // Also possible to load a module dymically import('./modules/myModule.js') .then((module) => { // Do something with the module. });
Iterate the keys/values of an object. What is an enumerable property?
There are many ways, most common are:
1). for…in loops - This method traverses all of the enumerable string properties + prototype chain
2). Object.keys(myObj) - This method returns an array with only the enumerable own string property names (“keys”) in the object
3). Object.getOwnPropertyNames(myObj) - This method returns an array containing all the own string property names including non-enumerable
Use big/fat arrow notation, for example mapping an array. Write the equivalent as a function
// Traditional Anonymous Function
(function (a) {
return a + 100;
});
// same as
(a) => {
return a + 100;
};
//same as
(a) => a + 100;
// same as
a => a + 100;
Create and use (get/put) a Map. How do you iterate. Why would you use this vs a standard object
const map1 = new Map(); map1.set('a', 1); map1.set('b', 2); map1.set('c', 3); map1.get('a'); // 1 map1.set('a', 97); map1.get('a'); // 97 map1.size; // 3 map1.size; // 2 // Iterating const myMap = new Map(); myMap.set(0, 'zero'); myMap.set(1, 'one'); for (const [key, value] of myMap) { console.log(`${key} = ${value}`); } // 0 = zero // 1 = one
Maps can be better than objects due to
- Accidental keys
- Performance in some situations
- Easy iteration
- Easily obtain size
JSON stringify and parse, show how to use.
// Parse const json = '{"result":true, "count":42}'; const obj = JSON.parse(json); obj.result; // true obj.count; // 42 // Stringify JSON.stringify(); // '{"result":true, "count":42}'
Demonstrate some functional programming with arrays, like map, reduce and filter
[4, 2, 1, 3] .filter(num => num < 4) .sort() .map(num => num.toString()) .join(':') // returns '1:2:3'