Skip to content

Latest commit

 

History

History
1821 lines (1278 loc) · 53.3 KB

File metadata and controls

1821 lines (1278 loc) · 53.3 KB

JavaScript Questions

List Down The Primitive And Non-Primitive(Object) Types.

data_type

  • Primitive Types: string, number, boolean, undefined, null, symbol.
  • Non-Primitive(Object) Types: array, object, function, date, regx.

What Is JSON (JavaScript Object Notation)?

  • JSON is basically an object represented in the form of a string.
// Parse JSON to object by JSON.parse()
let obj = '{"gretting": "hello"}';
let plainObj = JSON.parse(obj);
console.log(plainObj); // {gretting: 'hello'}

// Parse object to JSON by JSON.stringfy()
let data = {"name": "Erika"};
let jsonData = JSON.stringfy(data);
console.log(jsonData); // '{"name": "Erika"}'

What Is Not Defined, Undefined, Empty and Null?

Not Defined

  • Not defined means the variable doesn't exist.

Undefined

  • Undefined means a variable has been declared but has not yet been assigned a value.
  • Type of undefined = undefined.
let a;
console.log(a);           // undefined
console.log(typeof a);    // undefined

Empty

  • Empty is used to refer to a unique string with zero length.
let a = "";
console.log(a);        // ''
console.log(a.length); // 0

let b = " ";
console.log(b);         // ' '
console.log(b.length);  // 1

Null

  • Null is used to refer to nothing.
  • Type of null = object.
let a = null;
console.log(a);           // null
console.log(typeof a);    // object

console.log(null == undefined);  // true
console.log(null === undefined); // false

What Is Call By Value, Call By Reference And Call By Sharing?

Call By Value

call_by_value

  • When you declare a primitive type (string, number, boolean, null, undefined, symbol) variable a and b, it will has own memory location and store it's own value in it, then assign b equal to a, b also has own memory location and store a's value in it. b's value will not change when a's value changes, a and b's memory location is isolate, they won't interrupt each other.
var a = 2;
var b = a;
a = 3;

// a = 3, b = 2

Call By Reference

call_by_reference

  • When you declare a non-primitive(objects) type(array, object, function, date, regx) variable a and b, it will has own memory location and store it's own value in it, then assign b equal to a, b doesn't have own memory location, a and b will has same memory location, b's value will change when a's value changes.
var a = {greeting:'Hello'};
var b = a;

a.greeting = 'Hola';

console.log(a.greeting) // Hola 
console.log(b.greeting) // Hola  

var c = [1, 2, 3];
var d = c;

c[0] = 5;

console.log(c) // [5, 2, 3] 
console.log(d) // [5, 2, 3]


Call By Sharing


What Is Shallow Copy And Deep Copy?

shallow_deep_copy shallow_deep_copy

Shallow Copy

  • Duplicates as little as possible. If b is a shallow copy of a, b points to a's location in memory, b will change it's value when changes a.
  • Method => spread operator (The spread operator makes deep copies of data if the data is not nested.), object.assign

Deep Copy


What Is Spread Operator?

  • It consists of three dots (...). The spread operator allows you to spread out elements of an iterable object such as an array, map, or set.
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arrCombined = [...arr1, ...arr2];
console.log(arrCombined); // [1, 2, 3, 4, 5, 6]

What Is Rest Operator?

  • It consists of three dots (...) which collect all remaining elements into an array.
Example_1:

const getLength = (...num) => {
     console.log(num.length) // 5
}

getLength(1, 2, 3, 4, 5);


Example_2:

let avg = function(...arr) {
  let sum = 0;
  for (let i = 0; i < arr.length; i++) {
    sum += arr[i];
  }
  return sum / arr.length;
}

console.log(avg(1, 3, 5, 7, 9)); // 5
  • Rest opeator is often used in combination with destructuring.
const numbers = [1, 2, 3, 4, 5, 6];
const [a, b, ...rest] = numbers; // a = 1, b = 2, c = [3, 4, 5, 6] 

What Is Destructuring Assignment?

  • The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
  • Destructuring array or object preventing from changing original values.
const [a, b] = [1, 2]; // a = 1, b = 2

const [a, , b] = [1, 2, 3];  // a = 1, b = 3

const [a, ...b] = [1, 2, 3]; // a = 1, b = [2, 3]

const [a, b, ...c] = [1, 2, 3, 4, 5]; // a = 1, b = 2, c = [3, 4, 5]

What Are The Differences Between push(), pop(), unshift(), shift()?

Methods push() pop() unshift() shift()
ADD the element in the END of array DELETE the element in the END of array ADD the element in the BEGINNING of array DELETE the element in the BEGINNING of array
Return New length The removed item New length The removed item
let arr = [1, 2, 3, 4, 5];

// Push
console.log(arr.push(6)); // 6 (length)
console.log(arr); // [1, 2, 3, 4, 5, 6]

// Pop
console.log(arr.pop()); // 6
console.log(arr); // [1, 2, 3, 4, 5]

// Unshift
console.log(arr.unshift(6)); // 6 (length)
console.log(arr); // [6, 1, 2, 3, 4, 5]

// Shift
console.log(arr.shift()); // 6 
console.log(arr); // [1, 2, 3, 4, 5]

What Are The Difference Between slice(), splice() and split()?

Methods slice (start index, end index) splice (index, howmany, item1, ....., itemx) split (separator, howmany)
Array, string Array String
Return a new array object Changes the contents of an array by removing existing elements and/or adding new elements. Splits a string object into an array
- Starting at the given start argument, but the end doesn't include
- Negative value defines the position from the end of the array
- Starting at the given start argument, but the end doesn't include
- Negative value defines the position from the end of the array
NOT changes the original array CHANGES the original array NOT changes the original array
let arr1 = [1, 2, 3, 4, 5];

// Slice
Example_1:
console.log(arr1.slice(0)) // [1, 2, 3, 4, 5]

Example_2:
console.log(arr1.slice(2, 4)) // [3, 4]

Example_3:
console.log(arr1.slice(-2)) // [4, 5] 

// Splice
Example_1:
// At position 1, remove 3 items: 
let arr2 = [1, 2, 3, 4, 5];
arr2.splice(1, 3);
console.log(arr2); // [1, 5]

Example_2:
// At position 1, add 2 elements
let arr3 = [1, 2, 3, 4, 5];
arr3.splice(1, 2, 55, 66);
console.log(arr3); // [1, 55, 66, 4, 5] 

Example_3:
// Negative index 
let arr4 = [1, 2, 3, 4, 5];
arr4.splice(-2);
console.log(arr4) // [1, 2, 3]

// Split
Example_1:
let str1 = "How are you";
console.log(str1.split(" ")); // ['How', 'are', 'you']

Example_2:
let str2 = "adfgdfhgdfh";
console.log(str2.split("")) // ['a', 'd', 'f', 'g', 'd', 'f', 'h', 'g', 'd', 'f', 'h']


What Is Hoisting?

  • Hoisting is JavaScript's default behavior of moving declarations to the top.
console.log(a); // Uncaught ReferenceError: a is not defined
console.log(a); // undefined
var a;
var v = 5;
var v;
console.log(v); // 5
function test(v) {
  console.log(v) // 10
  var v = 3
}
test(10)
  • Only hoists declarations, not initializations.
console.log(a); // undefined
var a = 5;
  • Not only hoists variable, also hoists function, and the function's priority is higher than variable.
console.log(a) // function a(){}
var a;
function a(){};
  • JavaScript in strict mode(use strict) does not allow variables to be used if they are not declared.
  • You can use let/const instead of var to avoid hoisting, actually let/const has hoisting, but they have TDZ(Temporal Dead Zone).

What Is "Use strict"?

  • This strict context prevents certain actions from being taken and throws more exceptions.
  • Using strict mode, don’t allow to use a variable without declaring it, duplicating a parameter name is not allowed, etc.
  • Related Reference: 我知道你懂 hoisting,可是你了解到多深?

What Is Let And Const?

  • Let and Const is block scope, Var is function scope.
function varFunction () {
  var ming = 'May';
  if (true) {
    var ming = 'Joe';
  }
  console.log(ming);  // Joe
}

function letFunction () {
  let ming = 'May';
  if (true) {
    let ming = 'Joe';
  }
  console.log(ming);  // May
}

varFunction();
letFunction();

  • Compare var and let in loop
// With var we have a function scope, and only one shared binding for all of we loop iteration
for (var i = 0; i < 10; i++) {
  setTimeout(function () {
    console.log('execute ' + i + ' times; '); 
  }, 10);
}

// execute 10 times; execute 10 times; execute 10 times; execute 10 times; execute 10 times; execute 10 times; execute 10 times; execute 10 times; execute 10 times; execute 10 times;


// With let we have a block scope and when used in the for loop we get a new binding for each iteration
for (let i = 0; i < 10; i++) {
  setTimeout(function () {
    console.log('execute ' + i + ' times;');
  }, 10);
}

// execute 0 times; execute 1 times; execute 2 times; execute 3 times; execute 4 times; execute 5 times; execute 6 times; execute 7 times; execute 8 times; execute 9 times;

  • Let is for declare variables.
  • Const is for declare const variables, need initialize in declaration, can't reassignment.

const a = 10;
a = 20;  // TypeError: Assignment to constant variable.

What Is Block Scope And Function Scope?

  • Block scope is everything inside a set of braces {block scope here}
  • A block scope is sometimes the same as a function scope.
function test(x) {
   // this is both a block scope and a function scope
   let y = 5;
   if (x) {
       // this is a smaller block scope that is not the same as the function scope
       let z = 1;
   }
}
function foo() {
    if (true) {
        var a = 1;
        let b = 2;
        const c = 3;
    }
    console.log(a); // 1
    console.log(b); // b is not defined
    console.log(c); // c is not defined
}

What Is Local Scope And Global Scope?

Local Scope

  • Variables declared within a JavaScript function, become local to the function.
  • Local variables have Function scope: They can only be accessed within the function.
// code here CAN NOT use carName

function myFunction() {
  var carName = "Volvo";

  // code here CAN use carName

}

Global Scope

  • A variable declared outside a function, becomes global.
  • A global variable has global scope: All scripts and functions on a web page can access it.
var carName = "Volvo";

// code here can use carName

function myFunction() {

  // code here can also use carName

}
  • If you assign a value to a variable that has not been declared, it will automatically become a global variable.
  • This code example will declare a global variable carName, even if the value is assigned inside a function.
myFunction();

// code here also can use carName

function myFunction() {
  carName = "Volvo";
  
  // code here can use carName
}

Explain What Is TDZ (Temporal Dead Zone)?

  • TDZ is short of Temporal Dead Zone. You will get error notification if you try to access a variable after hoisting and before initialization which declared with let or const.
function test() {
    var a = 1; // Start varable c's TDZ
    var b = 2;
    console.log(c); // Uncaught ReferenceError: Cannot access 'c' before initialization
    if (a > 1) {
      console.log(a);
    }
    let c = 10 // End varable c's TDZ
}

test();

What Is "this"?

  • The this keyword refers to an object, the value of this is determined by how a function is called.

Default Binding

  • In a JavaScript function(default), the owner of the function is the global object, so this refers to the global object.
var a = 123;

function foo() {
  console.log(this.a);
}

foo(); // 123

  • In a JavaScript function(strict), strict mode does not allow default binding, So in strict mode is undefined.
"use strict";

var a = 123;
function foo() {
  console.log(this.a);
}

foo(); // undefined

Implicit Binding

  • In an object method, this refers to the owner of the method.
function func() {
  console.log( this.a );
}

var obj = {
  a: 2,
  foo: func
};

func();     // undefined
obj.foo();  // 2

  • In HTML event handlers, this refers to the HTML element that received the event.
<button onclick="this.style.display='none'">Click to Remove Me!</button>
// The button will disappear when click the button

Explicit Binding

  • Use another variable to temp save this.
let el = document.getElementById('app');

el.addEventListener("click", function(event) {
  var that = this;
  console.log(this.textContent); // show the textcontent

  innerFunc();

  function innerFunc() {
    console.log(this.textContent); // undefined
    console.log(that.textContent); // show the textcontent
  };

}, false);

  • Use call(), apply() to execute the function.
var person = {
  name: "Kuro",
  hello: function(thing, whom) {
    console.log(this.name + " says " + thing + " to " + whom);
  }
}

var person2 = {
  name: "Jack"
};

person.hello("love you", "Amy");                 // Kuro says love you to Amy
person.hello.call(person, 'love you', 'Amy')     // Kuro says love you to Amy
person.hello.apply(person, ["love you", "Amy"]); // Kuro says love you to Amy

person.hello.call(person2, "miss you", "Amy");    // Jack says miss you to Amy
person.hello.apply(person2, ["miss you", "Amy"]); // Jack says miss you to Amy

  • Use bind() to creates a new function that will force the this inside the function to be the parameter passed to bind().
var obj = {
  x: 123
};

var func = function () {
  console.log(this.x);
};

func();            // undefined
func.bind(obj)();  // 123

New Binding

function foo(a) {
  this.a = a;
}

var obj = new foo(123);
console.log( obj.a ); // 123

What Are Differences Between Bind(), Call() And Apply()?

  • Bind() is when you want that function to later be called with a certain context, useful in events. Use call() or apply() when you want to invoke the function immediately, and modify the context. Fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments. The difference is that call() takes the function arguments separately, and apply() takes the function arguments in an array.

What Is Callbacks?

  • Take a function as another function's parameter, called by another function.
  • Control the sequence of function execute.
window.setTimeout(function() { ... }, 1000);

Why Do We Use Callback?


What Is Promise?

promise

  • Promise is guarantee to do specfic things after an asynchronous action is resolved or rejected, one of the ways we can deal with asynchronous operations, prevent callback hell. It takes two parameters, one for success (resolve) and one for fail (reject) :
const myPromise = new Promise((resolve, reject) => {
    // condition
});
  • A promise starts in the pending state which indicates that the promise hasn’t completed, it ends with either success (resolve) or fail (reject) state, and the value won't be change when the states of promise parse to resolve or reject :
    (1) Resolved: The state of a promise representing a successful operation.
    (2) Rejected: The state of a promise representing a failed operation.
    (3) Pending: Initial state, before the promise succeeds or fails.
const myPromise = new Promise((resolve, reject) => {
    let condition;

    if(condition is met) {
        resolve('Promise is resolved successfully.');
    } else {
        reject('Promise is rejected');
    }
});
  • How to deal with states :
    (1) then(): If the promise gets resolved, the then() method is called, then we can decide what to do with the resolved promise. then() accepts two function arguments, the first handler supplied to it will be called if the promise is resolved, The second one will be called if the promise is rejected.
    (2) catch(): If the promise gets rejected, it will jump to the catch() method.
    (3) finally(): Execute the same piece of code whether the promise is resolved or rejected.
    (4) all(): Creates a new promise that will be resolved when all of promises are resolved. If any of the promises are rejected, the returned promise will be rejected immediately and will provide the value of the promise that was rejected.
    (5) Keep waiting : During pending.
myPromise.then((message) => {
    console.log(message);
}).catch((message) => {
    console.log(message);
});

Explain What Is Asynchronous And Synchronous?


What Is Async/Await?

  • Async and Await is syntax sugar for promises in javaScript.
  • Await ensures executing next step after specific operations.
  • An Await operand can only be used inside an Async function.
  • The Async functions return a promise.
async function fetchData() {
  await a();
  ......  // Execute after a
  await b();
  ......  // Execute after b
}

fetchData();

fetchData().then(() => {
  ...... // Execute after fetchData
});

What Is Expressions And Statement?

  • Expression: Any unit of code that can be evaluated to a value is an expression.
1;
1 + 2;
"Hello";
10 > 9;

  • Statements: A statement is an instruction to perform a specific action. Such actions include creating a variable or a function, looping through an array of elements, evaluating code based on a specific condition etc. JavaScript programs are actually a sequence of statements.
if (expression)
    statement 1
else
    statement 2

What A Function Statements(Declaration) And Function Expressions?

  • Function Statement :

(1) A function created with a name.

function statement(item) {
    console.log('Function statement example' + item);
}

(2) Function declarations are hoisted.

callTest(); // 123

function callTest() {
    console.log(123);
}

callTest(); // 123

  • Function Expression :

(1) The name may be omitted in function expressions, making that function anonymous.

var expression = function(item) {
    console.log('Function expression example'+ item);
  }

(2) Function declarations are not hoisted.

callTest(); // callTest is not a function

var callTest = function() {
	console.log(123);
}

callTest(); // 123

What Is IIFE (Immediately Invoked Function Expression)?

  • (pronounced 'iffy') Is a function defined as an expression and executed immediately after creation.
  • By wrapping our function in parenthesis, we tell the parser to parse our JavaScript as a function expression, the enclosing parenthesis at the end of IIFE are used to invoke functions.
(function() {
    //...
})();

  • We can’t access the variable superSecret outside of the IIFE. All of the code within our IIFE stays within the private scope of our function. Is a good way at protecting the scope of your function and the variables within it, ensures that code inside IIFE does not interfere with other code or be interfered by another code so code is safe.
(function() {
  var superSecret = 195;
})()
console.log(superSecret); // Uncaught ReferenceError: superSecret is not defined

Why Don't Use A Named Function Then Invoke It? That Would Create The Same Result?


What Is First Class Function?


What Is Higher Order Function (HOF)?

  • To match one of the criteria as below

(1) Takes one or more functions as arguments.

// Higher Order Function
function higherOrderFunctio(callback) {
  console.log("higherOrderFunction");
  callback();
}

function callbackFunction() {
  console.log("callbackFunction");
}

// Callback Function
higherOrderFunction(callbackFunction);

(2) Returns a function as its result.

// Higher Order Function 
function higherOrderFunction) {
  console.log("higherOrderFunction");
  return function(arg1) {
    console.log(arg1 + "...");
  };
}

// Returned Function
var returnedFunction = higherOrderFunction();
returnedFunction("returnedFunction");

What Is Event Capturing and Event Bubbling?

event_capturing_bubbling


How To Prevent Default Event?

  • Using preventDefault() to prevent default actions that browsers make when an event is triggered.
  • Such as you may want to do some data validation, data checks, processing, configuring headers, and so on before sending the request to a URL.
const form = document.getElementById('form');

form.addEventListener('submit', (event) => {
   event.preventDefault();
  
  // process data and submit a request manually
})

Explain What And When Use The map(), forEach(), filter(), find(), reduce()?

  • map(): Returns new array with transformed elements, leaving back original array unchanged.
  • forEach(): Like a for loop, but is more readable and intuitive. Use it when we want to perform a specific action for each element of an array.
  • filter(): Return an array which that match the criteria.
  • find(): Returns the first element in an array that satisfies a provided function.
  • reduce(): Return a value by running the reducer across all elements of the array, leaving back original array unchanged.
let people = [
  {
    name: 'Casper',
    like: 'Noodles',
    age: 18
  },
  {
    name: 'Wang',
    like: 'Rice',
    age: 24
  },
  {
    name: 'Bobo',
    like: 'Steak',
    age: 1
  },
  {
    name: 'Andy',
    like: 'Fish',
    age: 3
  }
];

// Map
let map = people.map((item) => item.age + 1);
console.log(map); // [19, 25, 2, 4]

// Foreach
people.forEach((item) => console.log(item.name + " likes " + item.like); )
// Casper likes Noodles
// Wang likes Rice
// Bobo likes Steak
// Andy likes Fish

// Filter
let filter = people.filter((item) => item.age <= 3)
console.log(filter); // [{name: 'Bobo', like: 'Steak', age: 1}, {name: 'Andy', like: 'Fish', age: 3}]

// Find
let find = people.find((item) => item.age <= 3)
console.log(find) // {name: 'Bobo', like: 'Steak', age: 1}

// Reduce
const agesArr = people.map((item) => item.age);
const reduce = agesArr.reduce((accumulator, current) => accumulator + current
);

console.log(reduce); // 46

What Are The Differences Between map(), forEach()?

Methods map() foEach()
Return Returns a new array DOES NOT return a new array, returns undefined
DOES NOT change the original array
Ability to chain other methods Can't chain other methods

How To Access Values On An Object?

const object = {
   "num": 1,
   "str": "Hello World",
   "obj": {
      "x": 5
   }
};

// Dot notation
const val = object.obj.x;
console.log(val); // 5

// Bracket notation
const val = object["obj"]["x"];
console.log(val); // 5

// Destructuring Syntax
const {num, str} = object;
console.log(num, str); // 1 "Hello World"

How To Iterate Object?

let obj = {name : "Erika", age : 18}

// Object.keys(), Object.value() and Object.entries returns an array
for (let key of Object.keys(obj)) {
    console.log(key + ","); // name, age
}

for (let value of Object.values(obj)) {
    console.log(value + ","); // Erika, 18
}

for (let [key, value] of Object.entries(obj)) {
    console.log(key + " = " + value + ",");  // name = Erika, age = 18
}

// Use forEach
Object.keys(obj).forEach((key) => console.log(key + ",")) // name, age
Object.values(obj).forEach((val) => console.log(val + ",")) // Erika, 18

Object.keys(obj).forEach((key) => console.log(key + " = " + obj[key] + ",")) // name = Erika, age = 18
Object.entries(obj).forEach((item) => console.log(item[0] + " = " + item[1] + ","))  // name = Erika, age = 18
Object.entries(obj).forEach(([key, value]) => console.log(key + " = " + value + ","))  // name = Erika, age = 18

How To Iterate Map?

let map = new Map();
let arr = ["Erika", "Joe", "Ray"];

for (let i = 0; i < arr.length; i++) {
    map.set(i, arr[i]);
}

for (let [key] of map) {
    console.log(key + ",");  // 0, 1, 2
}

for (let [, val] of map) {
    console.log(val + ",");  // Erika, Joe, Ray
}

for (let key of map.keys()) { 
      console.log(key + ","); // 0, 1, 2
}

for (let val of map.values()) { 
      console.log(val + ","); // Erika, Joe, Ray
}

for (let [key, value] of map) { 
     console.log(key + " = " + value + ",");  // 0 = Erika, 1 = Joe, 2 = Ray
}

map.forEach((val, key) => console.log(key + " = " + val + ",")) // 0 = Erika, 1 = Joe, 2 = Ray

What Is Set?

  • The set object lets you store unique values of any type, whether primitive values or object references.
  • Set doesn't allow duplicate values.
let arr = [1, 2, 2, 3];

// Check if a value is in a set object
const mySet = new Set(arr);
console.log(mySet(1)); // true

// Remove the duplicate value
let arr2 = [...new Set(arr)];
console.log(arr2); // [1, 2, 3]

How To Iterate Set?

let arr = [1, 2, 3, 4, 2, 3, 3];
let set = new Set(arr);

for (let val of set) console.log(val) // 1, 2, 3, 4

set.forEach(val => console.log(val)) // 1, 2, 3, 4

What Is Curry?

  • Currying is transforming a function with multiple arguments into a sequence of nesting functions. It returns a new function that expects the next argument inline.
  • We can use currry to reuse function instead of creating function repeatedly.
// Before currying
function minusFunc(x, y) {
  return x + y;
}

console.log(1, 2); // 3


// After currying
// Syntax_1:
function minusFunc(x) {
  return function(y) {
    return x + y;
  }
}

const returnFunc = minusFunc(1);
console.log(returnFunc);      // Function
console.log(returnFunc(2));   // 3
console.log(returnFunc(5));   // 6
console.log(minusFunc(1)(2)); // 3

// Syntax_2:
const minusFunc = (x) => (y) => x - y;

const retuernFunc = minusFunc(1);
console.log(returnFunc);      // Function
console.log(retuernFunc(2));  // -1
console.log(retuernFunc(5));  // -4
console.log(minusFunc(1)(5)); // -4

What Is Closure?

  • If we use the global variables in the wrong way, may cause some problems like:
var count = 0; 

function hamster() {
  count += 1;
  console.log(count + ' hamster(s)');
}

var count = 0;

function cat() {
  count += 1;
  console.log(count + ' cat(s)');
}

hamster(); // 1 hamster(s)
hamster(); // 2 hamster(s)

cat(); // 3 cat(s), but we expect 1 cat(s)
cat(); // 4 cat(s), but we expect 2 cat(s)
cat(); // 5 cat(s), but we expect 3 cat(s)

hamster(); // 6 hamster(s), but we expect 3 hamster(s)

  • Closure uses outer function returns the inner function (which we really want to execute) to let us have private variable without affected by environment.
function hamster() {
    var count = 0; 
    function countHamster() {
      count += 1;
      console.log(count + ' hamster(s)');
  }
  return countHamster;
}

function cat() {
    var count = 0; 
    function countCat() {
      count += 1;
      console.log(count + ' cat(s)');
  }
  return countCat;
}

const countHamster = hamster();
const countCat = cat();

countHamster(); // 1 hamster(s)
countHamster(); // 2 hamster(s)

countCat(); // 1 cat(s)
countCat(); // 2 cat(s)
countCat(); // 3 cat(s)

countHamster(); // 3 hamster(s)

  • Improve code by using anonymous and arrow function.
function hamster() {
  var count = 0; 
  return() => {
    count += 1;
    console.log(count + ' hamster(s)');
  }
}

function cat() {
  var count = 0; 
  return() => {
    count += 1;
    console.log(count + ' cat(s)');
  }
}

const countHamster = hamster();
const countCat = cat();

countHamster(); // 1 hamster(s)
countHamster(); // 2 hamster(s)

countCat(); // 1 cat(s)
countCat(); // 2 cat(s)
countCat(); // 3 cat(s)

countHamster(); // 3 hamster(s);

  • Even use the same outer function, variables don't disturb each other cause the excute environment is different.
function animalCounter(name) {
   var count = 0; 
   return() => {
      count += 1;
      console.log(count + ' ' + name);
  }
}

const hamsterCounter = animalCounter('hamster(s)');
const catCounter = animalCounter('cat(s)');
const dogCounter = animalCounter('dog(s)');

hamsterCounter(); // 1 hamster(s)
catCounter();     // 1 cat(s)
catCounter();     // 2 cat(s)
dogCounter();     // 1 dog(s)
dogCounter();     // 2 dog(s)
dogCounter();     // 3 dog(s)
hamsterCounter(); // 2 hamster(s)

What Is Funcution composition?

  • Function composition is the process of combining two or more functions to produce a new function.
const double = (x) => x * 2;
const square = (y) => y * y;
const minus = (z) => z - 10;

// Before implementing the funcution composition
// Method_1:
let a = double(1);
let b = square(a);

console.log('Method 1', b); // 4

// Method_2:
console.log('Method 2', square(double(1))); // 4

// After implementing the funcution composition
// For only 2 functions
const composeForTwo = (fun1, fun2) => x => fun1(fun2(1));
console.log('Function composition for 2 functons', composeForTwo(square, double)(1)); // 4

// For mutiple functions
const compose = (...fcs) => x => fcs.reduceRight((val, fc) => fc(val), x);
console.log('Function composition for mutiple functions', compose(minus, square, double)(1)); // -6

What Is Stack?

event_loop


What Is Queue?

event_loop


What Is Call Stack?

  • The call stack is what a program uses to keep track of method calls.
  • The call stack is made up of stack frames.
function a() {

    function b() {

        function c() {
            console.log('This is c()');
        }

        c();
        console.log('This is b()');
    }

    b();
    console.log('This is a()');
} 
a();

// This is c();
// This is b();
// This is a();

What Is Stack Overflow?

  • A stack overflow is a runtime error that happens when a program runs out of memory in the call stack.

What Is Callback/Event/Task Queue?

  • This is where the asynchronous code gets pushed to, and waits for the execution.
  • The tasks are broken down further into Macrotasks and Mircotasks, and the priority Mircotasks is higher than Macrotasks.
    (1) Macrotasks: setTimeout, setInterval, I/O, UI Rendering.
    (2) Mircotasks: Promises, MutationObserver.

What Is Job Queue?

  • Apart from callback queue, reserved only for new Promise() functionality.

What Is An Event Loop?

event_loop

You should know before reading about event loop

  • Process: A process can have anywhere from just one thread to many threads.
  • Threaded: A thread is the unit of execution within a process. single thread means it can only do one thing at the same time.
  • Runtime: Where your program will be executed. It determines what global objects your program can access and it can also impact how it runs. This article covers the two JavaScript runtime environments:
    (1) The runtime environment of a browser (like Chrome, or Firefox).
    (2) The Node runtime environment.
  • Web APIs: The Web APIs are provided by the web browser that gives additional functionality to the V8 engine, like the DOM, AJAX, setTimeout and much more.
  • Heap: It's not a data structure here, this is where all the memory allocation happens for your variables, that you have defined in your program.
  • JavaScript is a single-threaded programming language which can run at various runtime, once your browser starts processing too many tasks in the call stack, it may stop being responsive for a long time, even block the UI thread, and the user can't click around, scroll the page, and so on.
  • In order to run the make sure every process isolated and avoid a web page with infinite loops or heavy processing to block your entire browser when using web APIs, the event loop continuous monitoing the call stack and the callback queue. If the call stack is empty, it will take the first event from the queue and will push it to the call stack, which effectively runs it.
console.log('start');

setTimeout(() => {
  console.log('setTimeout1');
})

Promise.resolve()
  .then(() => {
    console.log('Promise1');
  })
  .then(()=> {
    console.log('Promise2');
  })
setTimeout(() => {
  console.log('setTimeout2');
})

console.log('end');

// Result
'start'
'end'
'Promise1'
'Promise2'
'setTimeout1'
'setTimeout2'

What Is Functional Programming (FP)?

  • Functional programming empazies on pure, higher order functions, take function as first class, voiding mutating data and side effect.
  • Related Reference: What is Functional Programming?

What Are The Strengths Of Functional Programming?

  • Allows you to avoid confusing problems and errors in the code
  • Easier to test and execute Unit testing and debug FP Code.
  • Parallel processing and concurrency
  • Hot code deployment and fault tolerance
  • Offers better modularity with a shorter code
  • Increased productivity of the developer
  • Supports Nested Functions
  • Functional Constructs like Lazy Map & Lists, etc.
  • Allows effective use of Lambda Calculus

What Is Pure Function And What Is Impure Function?

  • Pure Functions = Consistent Results
  • The first example returns a value based on the given parameters, regardless of where/when you call it.
    (1) Its return value is the same for the same arguments.
    (2) Its evaluation has no side effects.
// Pure Function
const add = (x, y) => x + y;

console.log(add(2, 4)); // 6
  • Impure Functions = Inconsistent Results
  • The second example returns nothing. It relies on shared state to do its job by incrementing a variable outside of its own scope. In the example : The first time results in 6, next time is 10 and so on.
// Impure Function
let x = 2;

const add = (y) => x += y;

console.log(add(4)); // 6
console.log(add(4)); // 10

What Is Recursion?

  • Recursion is a process of calling itself. A function that calls itself is called a recursive function. A recursive function must have a condition to stop calling itself. Otherwise, the function is called indefinitely.
function recu(i) {
  if(i < 10) {
    i++;
    return recu(i);
  }
    return i;
}

console.log(recu(1))l // 10

What Is Try Catch, Throw And Throw new Error()?

  • Try Catch: Can allow user to use website normarlly although the error occor. The Try statement lets you test a block of code for errors, the catch statement lets you handle the error.
  • Throw: It will terminate the further execution.
  • Throw new Error(): The difference between throw and throw new Error() is the format {name: 'Error', message: 'String you pass in the constructor'}, you can also customize the information you want to debug such as transaction number.
try {
      throw "I'm Erika";           // I'm Erika
      throw Error("I'm Joe");      // Error: I'm Joe, if the above line exists then this line won't never show
      throw new Error("I'm Ray");  // Error: I'm Ray, if the above two lines exist then this line won't never show
      console.log("You'll never reach me if any above code line shows")
} catch(e) {
      console.log(e);
}

What Is Prototype?

  • All JavaScript objects inherit properties and methods from a prototype.
  • Prototype property allows you to add new properties to object constructors.
function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
}

Person.prototype.nationality = "English";
  • Prototype property allows you to add new methods to object constructors.
function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
}

Person.prototype.name = function() {
  return this.firstName + " " + this.lastName;
};
  • prototype is a property of a Function object. It is the prototype of objects constructed by that function.
  • __ proto __ (pronounced as dunder proto or double underscore proto) is internal property of an object, pointing to its prototype. Current standards provide an equivalent Object.getPrototypeOf(O) method.
function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.log = function () {
  console.log(this.name + ', age:' + this.age);
}

var nick = new Person('nick', 18);

console.log(nick.__proto__ === Person.prototype); // true
console.log(nick.prototype === undefined);        // true

What Is A Prototype Chain?

  • If you try to call a property on an object, JavaScript will go to the prototype object and look for it, until it finds it. If it doesn't find the specific property that you're looking for, it'll return undefined for you.
  • Related Reference : JavaScript Fundamentals: Prototype Chains

What Is Delegate?


How To Convert Binary String To Number And Vice Versa?

  • parseInt(): convert binary string to number
  • toString(): convert number to binary string
// Convert binary string to number
let binaryStr = "1011";
let num = parseInt(binaryStr, 2);
console.log(num); // 11

// Convert number to binary string
let num = 34;
let binaryStr = num.toString(2);
console.log(binaryStr); // "100010"


What Are The Differences Between Library And Framework?

framework_library.png

Library Framework
A set of assistance modules, objects, classes, functions, pre-written code, and so on. Includes a variety of APIs, compilers, support applications, libraries, and so on.
Can be easily substituted by another library. Are tough to replace.
When we call a method from a library, we are in control. Inversion of control, i.e. the framework calls us.
Since developing a library needs less code, performance and load time are improved. The construction of a framework necessitates large amounts of code, which reduces performance and increases load time.
Libraries can be simply linked into existing programs to add specific functionality. It is tough to incorporate a framework seamlessly into an existing project.

Customized javaScript Questions

Where Do You Use Async, Await and Promise?

  • To do somthing after receive the data from API calls.

What Do You Think About JavaScript?

  • With JavaScript we can build websites, mobile apps, web apps, and writing back-end code, It works on many platforms and environments. Many new features in ES6 and ES7 such as spread operator, promise, async, and await can greatly increase our ease of development. JavaScript is also a foundation of frameworks such as React, Vue, etc. We can use the frameworks to solve many real-world problems and extend the language.
  • JavaScript is very relaxed about the difference between strings and numbers. such as using string + number will be string, and using string will be number. It might cause the error code, but we can us TypeScript to prevent this simple error occurs.

Write The Map By Yourself.

const arr = [1, 2, 3];

const myMap1 = (arr, func) => {
  let newArr = [];
  for(let i = 0; i < arr.length; i++) {
    let result = func(arr[i])
    newArr.push(result);
  }
  return newArr;
}

console.log(myMap1(arr, num => num + 1)); // [2, 3, 4]

// Without using for loop
const myMap2 = (oldArr, func, newArr = []) => {
  if (oldArr.length === 0) {
    return newArr;
  } else {
    let [val, ...rest] = oldArr;
    let updateArr = [...newArr, func(val)];
    return myMap2(rest, func, updateArr);
  }
}

console.log(myMap2(arr, num => num + 1)); // [2, 3, 4]


Write The Map By Yourself With TypeScript

type MyFnType<Type> = (arg1: Type) => Type;

const myMap1 = <Type>(arr: Type[], fn: MyFnType<Type>): Type[] => {
  let newArr = [];
  for (let i = 0; i < arr.length; i++) {
    newArr.push(fn(arr[i]));
  }
  return newArr;
};

console.log(myMap1(arr, (x: number) => x + 1));

// Without using for loop
const myMap2 = <Type>(
  oldArr: Type[],
  fn: MyFnType<Type>,
  newArr: Type[] = []
): Type[] => {
  if (oldArr.length <= 0) {
    return newArr;
  } else {
    const [val, ...rest] = oldArr;
    newArr.push(fn(val));
    return myMap2(rest, fn, newArr);
  }
};

console.log(myMap2(arr, (x: number) => x + 1));