🕸️

Node.js

How does this work in JavaScript.
  • this is a reference to the object that is executing the function at run time.
  • Specifically, the following rules apply:
    • 1. new:
      • If the new keyword is used when calling the function, this inside the function is a brand new object.
    • 2. applycall, or bind 
      • If applycall, or bind are used to call/create a function, this inside the function is the object that is passed in as the argument.
    • 3. obj.method()
      • If a function is called as a method, this is the object that the function is a property of.
    • 4. If a function is invoked as a free function invocation, meaning if it was invoked without any of the conditions present above, this is the global object.
      • In a browser, it is the window object.
      • If in strict mode ('use strict'), this will be undefined instead of the global object.
    • 5. If multiple of the above rules apply:, the rule that is higher wins and will set the this value.
Can you give an example of one of the ways that working with this has changed in ES6?
  • See #6 above
How prototypal inheritance works in JavaScript
  • All JavaScript objects have a __proto__ property, that is a reference to another object, the object's prototype
If a property is accessed on an object, and if the property is not found, the Javascript Engine will:
  • recursively look up the prototype chain until
    1. It finds the property defined on one of the __proto__s
    2. or it reaches the end of the prototype chain
    3. I.O.W. — it will look it up on the object's prototype (__proto__ ), and the prototype object's prototype (__proto__) and etc...

  • It simulates classical inheritance
What's the difference between a variable that is: nullundefined or undeclared?
  • A variable that is undefined is a variable that has been declared, but not assigned a value. It is of type undefined
  • The value null represents the intentional absence of any object value
  • Undeclared variables are created when you assign a value to an identifier that is not previously created using var, let or const
  • A null variable
🔼 Explain hoisting.
  • hoisting describes the behavior of variable declarations in your code.
  • Variables declared with var will have their declaration "moved" up to the top of their module/function-level scope, which we refer to as hoisting.
💡
However, only the declaration is hoisted, the assignment (if there is one), will stay where it is.
Hoisting Functions
Function declarations have the body hoisted
// Function Declaration
console.log(foo); // [Function: foo]
foo(); // 'FOOOOO'
function foo() {
  console.log('FOOOOO');
}
console.log(foo); // [Function: foo]
function expressions (written in the form of variable declarations) only has the variable declaration hoisted.
// Function Expression
console.log(bar); // undefined
bar(); // Uncaught TypeError: bar is not a function
var bar = function () {
  console.log('BARRRR');
};
console.log(bar); // [Function: bar]
Hosting variables declared via let and const
  • Variables declared via let and const are hoisted as well.
  • However, unlike var and function, they are not initialized and accessing them before the declaration will result in a ReferenceError exception.
x; // undefined
y; // Reference error: y is not defined

var x = 'local';
let y = 'local';
⏫⏬ Describe event bubbling & event capturing.
event bubbling
  • When an event triggers on a DOM element, it will attempt to handle the event if there is a listener attached, then the event is bubbled up to its parent and the same thing happens.
  • This bubbling occurs up the element's ancestors all the way to the document.
💡
Event bubbling is the mechanism behind event delegation.
event capturing

With capturing, the event is first captured by the outermost element and propagated to the inner elements.

Capturing is also called "trickling", which helps remember the propagation order:

trickle down, bubble up
Event bubbling and capturing are two ways of event propagation in the HTML DOM API, when an event occurs in an element inside another element, and both elements have registered a handle for that event. The event propagation mode determines in which order the elements receive the event.

Arun Johny

On the difference between an attribute and a property?
Attributes are defined in your HTML markup.
  • For example, the HTML element <input type="text" value="Name:"> has the attributes of type and value
  • At run time, the browser will parse your HTML mark up and create a DOM node.
This node is an object. So for a given DOM node object, properties are the properties of that object.
Once the browser parses this code, a HTMLInputElement object will be created, and this object will contain dozens of properties like: accept, accessKey, align, alt, attributes, autofocus, baseURI, checked, childElementCount, childNodes, children, classList, className, clientHeight, etc.

Sime Vidas

🎒What is a closure, and how/why would you use one?
Closure
  • A closure is the combination of a function and the lexical environment within which that function was declared.
  • The word lexical refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available.
  • Closures are functions that have access to the outer (enclosing) function's variables—scope chain even after the outer function has returned.
Why you would use one:
  • Data privacy / emulating private methods with closures. Commonly used in the module pattern.
Explain event delegation. Why is it useful? Give an example of how you would use it
  • Event delegation is a way of handling ui-events to DOM elements via a single common parent rather than each child, through the magic of event "bubbling" (aka event propagation).
  • For example, adding a <li> item to an <ul> that can be clicked
  • 👍 The benefit of event delegation is that you can dynamically/implicitly/easily add event listeners to DOM nodes to handle events.
document.querySelectorAll('button').forEach(button => {
		button.addEventListener('click', handleClick)
})

Can become:

document.addEventListener('click', e => { 
	if (e.target.closest('button')) {
		handleButtonClick()
	}
})
What language constructions do you use for iterating over object properties and array items?
For objects:
for-in loops: for (var property in obj) { console.log(property); }.
⚠️
However, this will also iterate through its inherited properties, and you will add an obj.hasOwnProperty(property) check before using it.
Object.keys(): Object.keys(obj).forEach(function (property) { ... })
  • Object.keys() is a static method that will list all enumerable (not inherited) properties of the object that you pass it.
Object.getOwnPropertyNames() Object.getOwnPropertyNames(obj).forEach(function (property) { ... }).
  •  Object.getOwnPropertyNames() is a static method that will lists all enumerable and non-enumerable properties of the object that you pass it.
For arrays:
for loops for (let i = 0; i < arr.length; i++)
  • The common pitfall here is that var is in the function scope and not the block scope and most of the time you would want block scoped iterator variable.
  • ES2015 introduces let which has block scope and it is recommended to use that instead. So this becomes: for (let i = 0; i < arr.length; i++).
forEach arr.forEach(function (el, index) { ... })
  • This construct can be more convenient at times because you do not have to use the index if all you need is the array elements. There are also the every and some methods which will allow you to terminate the iteration early.
for-of loops  for (let elem of arr) { ... }.
  • ES6 introduces a new loop, the for-of loop, that allows you to loop over objects that conform to the iterable protocol such as StringArrayMapSet, etc. It combines the advantages of the for loop and the forEach() method. The advantage of the for loop is that you can break from it, and the advantage of forEach() is that it is more concise than the for loop because you don't need a counter variable. With the for-of loop, you get both the ability to break from a loop and a more concise syntax.
Can you describe the main difference between the Array.forEach() loop and Array.map() methods and why you would pick one versus the other?
forEach
  • Iterates through the elements in an array.
  • Executes a callback for each element.
  • Does not return a value.
const a = [1, 2, 3];
const doubled = a.forEach((num, index) => { // Do something with num and/or index.
});
// doubled = undefined
map
  • Iterates through the elements in an array.
  • "Maps" each element to a new element by calling the function on each element, creating a new array as a result.
const a = [1, 2, 3];
const doubled = a.map((num) => { return num * 2;
});
// doubled = [2, 4, 6]
💫
The main difference between .forEach and .map() is that .map() returns a new array.
What's a typical use case for anonymous functions?
  • IIFEs to encapsulate some code within a local scope so that variables declared in it do not leak to the global scope.
  • As callbacks that are used once or for functional programming constructs like LoDash
What's the difference between host objects and native objects?
  • Native objects are objects that are part of the JavaScript language defined by the ECMAScript specification, such as StringMathRegExpObjectFunction, etc.
  • Host objects are provided by the runtime environment (browser or Node), such as windowXMLHTTPRequest, etc.
Explain Function.prototype.bind.
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

MDN

Explain the differences on the usage of foo between function foo() {} and var foo = function() {}
  • The former is a function declaration while the latter is a function expression.
💫
The key difference is that function declarations have its body hoisted but the bodies of function expressions are not (they have the same hoisting behavior as variables).
Explain the difference between: function Person(){}var person = Person(), and var person = new Person()?
  • function Person(){} is a function declaration (probably intended to be used as a constructor indicated by PascalCasing
  • var person = Person() is an invocation of function Person(){} as a function, not as a constructor.
  •  var person = new Person() creates a new instance of the person object via the new operator, which inherits from Person.prototype
Can you explain what Function.call and Function.apply do? What's the notable difference between the two?
  • Both .call and .apply are used to invoke functions and the first parameter will be used as the value of this within the function.
.call takes in comma-separated arguments as the next arguments
function add(a, b) {
  return a + b;
}

console.log(add.call(null, 1, 2)); // 3
.apply takes in an array of arguments as the next argument.
function add(a, b) {
  return a + b;
}

console.log(add.apply(null, [1, 2])); // 3
💫
An easy way to remember this is C for call and comma-separated and A for apply and an array of arguments.
What's the difference between feature detection, feature inference, and using the UA string?
Feature Detection: checks to see if a browser will support a certain block of code, and runs different code if it doesn't
if ('geolocation' in navigator) {
  // Can use navigator.geolocation
} else {
  // Handle lack of feature
}
Feature Inference: checks for a feature, but uses another function because it assumes it will also exist.
if (document.getElementsByTagName) {
  element = document.getElementById(id);
}
  • UA String is a browser-reported string that allows the network protocol peers to identify the application type, operating system, software vendor or software version of the requesting software user agent. It can be accessed via navigator.userAgent.
💫
Feature Detection is better and more robust than Feature Inference . UA Strings are not recommended because it can be spoofed.
Why is extending built-in JavaScript objects not a good idea?
Extending a Javascript object, aka adding to it's prototype (__proto__) is usually not recommended because it can break your code.
  • For example, if two libraries extend the .forEach method's behavior differently, these implementations will overwrite each other and cause the aforementioned problem
  • The only time you may want to extend a native object is when you want to create a polyfill (providing your own implementation for a method that is part of the JavaScript specification but might not exist in the user's browser due to it being an older browser)
What is the difference between == and ===?
== is the abstract equality operator while === is the strict equality operator.
  • The == operator will compare for equality after doing any necessary type conversions.
  • The === operator will not do type conversion, so if two values are not the same type === will simply return false
1 == '1'; // true
1 == [1]; // true
1 == true; // true
0 == ''; // true
0 == '0'; // true
0 == false; // true
== is only really useful when checking for null and or undefined
var a = null;
console.log(a == null); // true
console.log(a == undefined); // true
Explain the same-origin policy with regards to JavaScript.
The same-origin policy prevents JavaScript from making requests across domain boundaries.
  • An origin is defined as a combination of URI scheme, hostname, and port number.
  • It is mean to prevent a malicious script on one page from obtaining access to sensitive data on another web page through that page's Document Object Model.
What is the difference between Error and Exception?
JavaScript syntax

Errors and exceptions are syntactically synonymous in JavaScript. The language only implements the Error keyword (through window.Error). You may define custom errors, using the Error.constructor, which takes name and message as parameters.

JavaScript Error
  • There is also the line number sugar that can be used to trace bug occurrences inside the code. JavaScript only has Error. Whether you hear people talking about Exceptions or Errors, in JavaScript they refer to the same thing.
  • Browsers make a distinction: ReferenceError (when accessing a variable with a name that doesn't exist in the heap, or when you make a typo(more here.), TypeError is also a known JS error, more here.
JavaScript Exception
  • A known JavaScript Exception is DOM Exception 8. It occurs when you access an object that is not ready, such as an XMLHttpRequest that has not completed the request.
Implementation
  • Code-wise the difference has no impact.
  • When using try catch or try catch finally blocks, you will deal with both JavaScript Exception and Error.
Behind the scenes
  • the browsers use the same window.Error constructor. An Exception is an Error instance with a name and message that contain "Exception".
  • Try: var myCustomError = new Error("myException", "An exception occurred.");. "Exception" is text in a string. More on Error here.
💫
Convention By convention, there is a difference between Error and Exception. An Error indicates a clear violation. A TypeError or ReferenceError means you are not following the language specs. An Exception is thrown when you access an XMLHttpRequest response before it is complete. Error is a "you broke the law" shout and Exception is an "Almost there!" pad on the shoulder. Hope the analogy helps!

StackOverflow

Why is it called a Ternary operator, what does the word "Ternary" indicate?
  • Ternary means three. Think "Trinary".
  • Accepts three operands: if , then , and else
What is strict mode? What are some of the advantages/disadvantages of using it?
  • Strict mode is a way to opt into a restricted variant of JavaScript
  • Enforces certain rules
  • Enabled by "use-strict"
Pros

Summary: Faster, more secure and eliminates silent errors

  • 👍Makes it impossible to accidentally create global variables
  • 👍this is undefined in the global context
  • 👍Requires function parameter names to be unique
  • 👍Disables confusing features
  • 👍Throws exceptions for:
    • silently failing assignments
    • attempts to delete un-deletable properties
Cons
  • 👎Many missing features that some developers might be used to.
  • Examples
    // Objects are variables too. 
    // Using an object, without declaring it, is not allowed: 
    
    'use strict'; 
      
      // Will throw an error 
      x = {p1:10, p2:20};
    //Writing to a read-only property is not allowed.
    
    'use strict'; 
     let obj = {}; 
     Object.defineProperty(obj, "x", {value:0, writable:false}); 
      
     // Will throw an error 
     obj.x = 3.14;
  • 👎No access to function.caller and function.arguments.
  • 👎Concatenation of scripts written in different strict modes might cause issues.
What are some of the advantages/disadvantages of writing JavaScript code in a language that compiles to JavaScript?

Like typescript

Pros

Summary: More succinct and maintainable

  • 👍Fixes some of the longstanding problems in JavaScript and discourages JavaScript anti-patterns.
  • 👍Enables you to write shorter code, by providing some syntactic sugar on top of JavaScript, which I think ES5 lacks, but ES2015 is awesome.
  • 👍Static types are awesome (in the case of TypeScript) for large projects that need to be maintained over time.
Cons
  • 👎Require a build/compile process as browsers only run JavaScript and your code will need to be compiled into JavaScript before being served to browsers.
  • 👎Most developers are not familiar with these languages and will need to learn it. There's a ramp up cost involved for your team if you use it for your projects.
  • 👎Smaller community
What tools and techniques do you use debugging JavaScript code?
JavaScript
Explain the difference between mutable and immutable objects.
  • A mutable object is an object whose state can be modified after it is created.
  • An immutable object is an object whose state cannot be modified after it is created.
What is an example of an immutable object in JavaScript?
  • Built-in types like numbers, strings and some Javascript objects like  MathDate are immutable.
  • Custom objects are generally mutable BUT can be simulated via
    • Freeze — Object.freeze()
    • Seal — Object.seal()
    • Defining "Object Constant Properties" — By combining writeable: false and configurable: false you can create an immutable object
      let myObject = {};
      Object.defineProperty(myObject, 'number', {
        value: 42,
        writable: false,
        configurable: false,
      });
      console.log(myObject.number); // 42
      myObject.number = 43;
      console.log(myObject.number); // 42
      Preventing Extensions — calling Object.preventExtensions()
      var myObject = {
        a: 2,
      };
      
      Object.preventExtensions(myObject);
      
      myObject.b = 3;
      myObject.b; // undefined
What are the pros and cons of immutability?
Pros
  • Easier change detection
    • Object equality can be determined in a performant and easy manner through referential equality. This is useful for comparing object differences in React and Redux.
  • Less complicated programming because less to think about
  • Defensive copies are no longer necessary when immutable objects are returning from or passed to functions, since there is no possibility an immutable object will be modified by it.
Easy sharing via references
  • One copy of an object is just as good as another, so you can cache objects or reuse the same object multiple times.
Thread-safe
  • Immutable objects can be safely used between threads in a multi-threaded environment since there is no risk of them being modified in other concurrently running threads.
Less memory
  • Using libraries like ImmmutableJS, objects are modified using structural sharing and less memory is needed for having multiple objects with similar structures.
Cons
Can result in poor performance
  • Naive implementations of immutable data structures and its operations can result in extremely poor performance because new objects are created each time. It is recommended to use libraries for efficient immutable data structures and operations that leverage on structural sharing.
  • Allocation (and deallocation) of many small objects rather than modifying existing ones can cause a performance impact. The complexity of either the allocator or the garbage collector usually depends on the number of objects on the heap.
  • Cyclic data structures such as graphs are difficult to build. If you have two objects which can't be modified after initialization, how can you get them to point to each other?
How can you achieve immutability in your own code?
  • Using const declarations with the techniques above.
  • You can use libraries like like immutable.js, mori or immer.
Explain the difference between synchronous and asynchronous functions.
Synchronous functions are blocking while asynchronous functions are not.
  • In synchronous functions, statements complete before the next statement is run. In this case, the program is evaluated exactly in order of the statements and execution of the program is paused if one of the statements take a very long time.
  • Asynchronous functions usually accept a callback as a parameter and execution continue on the next line immediately after the asynchronous function is invoked.
What is event loop?
  • The event loop is a single-threaded loop that monitors the call stack and checks if there is any work to be done in the task queue.
  • If the call stack is empty and there are callback functions in the task queue, a function is dequeued and pushed onto the call stack to be executed.
Video
  • What is the difference between call stack and task queue?
What are the differences between variables created using letvar or const?
  • Variables declared using the:
  • var keyword:
    • are scoped to the function in which they are created, or if created outside of any function, to the global object.
    • are hoisted ⇒ allows reference before declaration
    • allows redeclaration
    let and const keywords:
    • are block scoped, meaning they are only accessible within the nearest set of curly braces (function, if-else block, or for-loop).
    • not hoisted ⇒ reference before declaration throws an error
    • redeclaration not allowed
    • let vs. const: const cannot have it's value reassigned
What are the differences between ES6 class and ES5 function constructors?
  • Consider the following:
// ES5 Function Constructor
function Person(name) {
  this.name = name;
}

// ES6 Class
class Person {
  constructor(name) {
    this.name = name;
  }
}
  • The main difference in the constructor comes when using inheritance.
If we want to create a Student class that subclasses Person and add a studentId field, this is what we have to do in addition to the above.
// ES5 Function Constructor
function Student(name, studentId) {
  // Call constructor of superclass to initialize superclass-derived members.
  Person.call(this, name);

  // Initialize subclass's own members.
  this.studentId = studentId;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

// ES6 Class
class Student extends Person {
  constructor(name, studentId) {
    super(name);
    this.studentId = studentId;
  }
Can you offer a use case for the new arrow => function syntax? How does this new syntax differ from other functions?
  • One obvious benefit of arrow functions is to simplify the syntax needed to create functions, without a need for the function keyword.
  • The this within arrow functions is also bound to the enclosing scope which is different compared to regular functions where the this is determined by the object calling it.
What advantage is there for using the arrow syntax for a method in a constructor?
  • the value of this gets set at the time of the function creation and can't change after that.
  • could be helpful in react class components. you could use an arrow function without the need to .bind a callback to it's parent component
What is the definition of a higher-order function?
A higher-order function is any function that takes one or more functions as arguments, which it uses to operate on some data, and/or returns a function as a result.

The classic example of this is map, which takes an array and a function as arguments. map then uses this function to transform each item in the array, returning a new array with the transformed data. Other popular examples in JavaScript are forEach, filter, and reduce.

map
const transformNamesToUppercase = function (names) {
  return names.map((name) => name.toUpperCase());
};
transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']
Can you give an example for destructuring an object or an array?
// Variable assignment.
const foo = ['one', 'two', 'three'];
const [one, two, three] = foo;


const o = {p: 42, q: true};
const {p, q} = o;
Can you give an example of generating a string with ES6 Template Literals?
const person = {name: 'Christian', age: 28};
console.log(`Hi, my name is ${person.name} and I am ${person.age} years old!`);
// 'Hi, my name is Christian and I am 28 years old!'

console.log(`This is line one.
This is line two.`);
// This is line one.
// This is line two.
Can you give an example of a curry function and why this syntax offers an advantage?
  • Currying is a pattern where a function with more than one parameter is broken into multiple functions that, when called in series, will accumulate all of the required parameters one at a time.
  • This technique can be useful for making code written in a functional style easier to read and compose.
  • It's important to note that for a function to be curried, it needs to start out as one function, then broken out into a sequence of functions that each accepts one parameter.
Example
function curry(fn) {
  if (fn.length === 0) {
    return fn;
  }

  function _curried(depth, args) {
    return function (newArgument) {
      if (depth - 1 === 0) {
        return fn(...args, newArgument);
      }
      return _curried(depth - 1, [...args, newArgument]);
    };
  }

  return _curried(fn.length, []);
}

function add(a, b) {
  return a + b;
}

var curriedAdd = curry(add);
var addFive = curriedAdd(5);

var result = [0, 1, 2, 3, 4, 5].map(addFive); // [5, 6, 7, 8, 9, 10]
What are the benefits of using spread syntax and how is it different from rest syntax?
spread syntax
  • ES6's spread syntax is very useful when coding in a functional paradigm as we can easily create copies of arrays or objects without resorting to Object.create(), .slice(), or a library function.
  • This language feature is used often in Redux.
function putPizzaInArr(arr) {
  return [...arr, 'pizza'];
}

const result = putDookieInAnyArray(['I', 'love']); // ['I', 'love', 'pizza']

const person = {
  name: 'Christian',
  age: 28,
};

const copyOfChristian = {...person};
rest syntax
  • ES6's rest syntax offers a shorthand for including an arbitrary number of arguments to be passed to a function.
  • It's like an inverse of the spread syntax, taking data and stuffing it into an array rather than unpacking an array of data, and it works in function arguments, as well as in array and object destructuring assignments.
  • function addFive(...numbers) {
      return numbers.map((x) => x + 5);
    }
    
    const result = addFive(4, 5, 6, 7, 8, 9, 10); 
    // result = [9, 10, 11, 12, 13, 14, 15]
    
    const [a, b, ...rest] = [1, 2, 3, 4]; 
    // a = 1, b = 2, rest = [3, 4]
    
    const {e, f, ...others} = {
      e: 1,
      f: 2,
      g: 3,
      h: 4,
    }; 
    // e: 1, f: 2, others: { g: 3, h: 4 }
How can you share code between files?
In the browser environment
  • as long as the variables/functions are declared in the global scope (window), all scripts can refer to them. Alternatively, adopt the Asynchronous Module Definition (AMD) via RequireJS for a more modular approach.
In node.js
  • the common way has been to use CommonJS. Each file is treated as a module and it can export variables and functions by attaching them to the module.exports object.
  • ES2015 defines a module syntax which aims to replace both AMD and CommonJS. This will eventually be supported in both browser and Node environments.
Why you might want to create static class members?
  • Use static variables when : The value of the variable is independent of the objects (not unique for each object). E.g. number of students.
What is the difference between while and do-while loops in JavaScript?

The most important difference between while and do-while loop is that in do-while, the block of code is executed at least once, even though the condition given is false.