JavaScript Review — Part I.

After doing a project using Node.js, I realized that I hadn’t fully gone through JavaScript and was still getting some things confused with Dart. So, I decided to go over some concepts again.

Here are the concepts I go through in order:
- -

Up until now, I’ve been using only arrow functions, but I’ve come to the realization that arrow functions lack some features of regular functions.

Arrow functions do not have an arguments binding (but they do have access to the arguments of the nearest non-arrow parent function)

(left) regular function // (right) arrow function

Arrow functions do not have their own “this”, and similar to arguments, it will be the value of this of the closest non-arrow parent function ().

- Arrow functions do not have access to prototype chaining nor constructor function. Therefore, you cannot use the new keyword to create an instance with arrow functions. (More on prototypes below).

Hoisting is a technique which

Function Declaration // need function name
function sayHello(name) {
console.log(`Hello ${name}`);
Function Expression // don't need function name
const sayHello = function(name) {
console.log(`Hello ${name}`);

When a function is defined using a function declaration, a function object is created before run-time, which allows for hoisting.

sayHello("Soo"); // function hoistingfunction sayHello(name) {
console.log(`Hello ${name}`);

For hoisting, you need to use the keyword (declaring with let keyword will result in a ReferenceError — ). This is because variables declared using are both declared and initialized before runtime, whereas those declared with are declared before runtime, but initialized after runtime.

I personally haven’t found a use for hoisting yet…and my personal opinion is that it could leave room for potential errors.

I’m used to Dart, which is a language but JavaScript does not have class implementation per se, and uses Prototypes are used to create inheritance among Objects and provide shared property. All prototypes are linked to a You can access prototypes of an object through .

Above, I declared a created a constructor function and defined the bark prototype separately, but you can use to bring those separate lines of code into one large function. IIFEs are functions that are immediately executed after being defined, and cannot be called again.

(function () { 
}()); // the bracket() here is what executes the function

Through , you can access methods and properties of parent prototypes. Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype.

You can create a property with the same name as the prototype, which overrides the instance property (. If you delete the instance property and try to access it again, it will still be accessible through the prototype. You must do it directly through the prototype itself.

Unlike Dart, which uses curly brackets {} for a Map, JS creates an instance of Map class using I’ve been using Objects only because it provides the key-value relationship I need, and its easy to find the properties with a dot-notation. However, it seems that there are some cases where Map would be preferable

  • (functions, objects, primitive) whereas Object’s keys must be a String or Symbol
  • you can easily , but not for Objects
  • Better for frequent additions and removals of key-value pairs
  • You can use and loops for Maps (for-loop in the next section)
  • Maps are considered iterables, where as Objects are not
const hobbyMap = new Map([["Soo", "snowboarding"], ["Mike", "singing"], ["Sarah", "DJing"]]);const hobbyFunc = (value, key, map) => console.log(`${key} likes ${value}`);hobbyMap.forEach(hobbyFunc);
// Soo likes snowboarding
// Mike likes singing
// Sarah likes DJing

Although you can technically set a property of a Map like an Object, it does not actually store it in the Map for queries. You should use method.

const infoMap = new Map([["firstName", "Soo"], ["lastName", "Kim"]]);infoMap.hasPets = true;
console.log(infoMap.hasPets); // true
console.log(infoMap.has("hasPets")); // false - does not work!
infoMap.set("hasPets", true);
console.log(infoMap.has("hasPets")); // true
infoMap.set("petNames", ["Happy", "Queens", "Luna"]);
console.log(infoMap.get("petNames")); // ["Happy", "Queens", "Luna"]
  • loops through of an object
    - my quick cheat definition of enumerable property is simply ()
  • each iteration returns a (or if there is no explicit key associated with the object, the )
const fruitArray = ["apple", "banana", "orange", "peach"];for (const x in fruitArray) console.log(x); // 0 1 2 3 for (const x in fruitArray) console.log(fruitArray[x]); 
// apple banana orange peach
const nameObject = { first: "Soo", last: "Kim" };for (const x in nameObject) console.log(x); // first last for (const x in nameObject) console.log(nameObject[x]); // Soo Kimconst infoMap = new Map([["name", "Soo Kim"], ["numOfPets", 3]]);for (const x in infoMap) console.log(x); // undefined
  • loops through the of an iterable object, such as String, Array, Map, DOM
const fruitArray = ["apple", "banana", "orange", "peach"];for (const x of fruitsArray) console.log(x);
// apple banana orange peach
const nameObject = { first: "Soo", last: "Kim" };for (const key of Object.keys(nameObject)) console.log(key);
// first last
const infoMap = new Map([["name", "Soo Kim"], ["numOfPets", 3]]);for (const entry of infoMap) console.log(entries);
// ["name", "Soo Kim"] ["numOfPets", 3]
for (const key of infoMap.keys()) console.log(key ); // name numOfPetsfor (const [key, value] of infoMap) console.log(`${key}: ${value}`);
// name: Soo Kim numOfPets: 3

, you can destructure it and assign it to new variables according to its index, using . On the left side, you’ll define the new variables, and on the right must be the iterable.

const numbers = [1, 2, 3];
const [one, two, three] = numbers;
console.log(one, two, three); // 1, 2, 3
function Person(name) {
[this.firstName, this.lastName] = name.split(' ');

The assignment is in order but you do not need to have the same amount of variables on each side.

const numbers = [7, 8, 9];
const [seven, , nine] = numbers;
console.log(seven, nine); // 7, 9

You can also assign values to variables, but it supersede the destructured assignment.

const numbers = [1, 2, 3];
const [one, two, three = 10, four = 4] = numbers;
console.log(one, two, three, four); // 1, 2, 3, 4

For the destructuring is based on using . The order does not matter BUT the .

const me = { firstName: "Soo", lastName: "Kim" };
const { firstName, lastName } = me;
console.log(firstName, lastName); // Soo Kim

You can rename the new variables like so:

const me = { firstName: "Soo", lastName: "Kim" };
const { firstName: myName, lastName: myLastName } = me;
console.log(myName, myLastName); // Soo Kim

It’s useful when you want only certain property values from a large Object.

The above can be tweaked like so that in the itself, you can destructor the Object to be received.

You can use destructoring assignment for array and Object combined.

const employees = [
{ name: "Soo Kim", age: 30, job: "developer" },
{ name: "Mary Jane", age: 25, job: "marketer" },
{ name: "Lucy Jones", age: 37, job: "manager" },
const [ , { name: managerName }] = employees;
console.log(managerName); // Mary Jane

For an Object within another Object:

const manager = {
name: "Lucy Jones",
age: 37,
contact: {
email: "",
mobile: "123456789",
const { contact: { email: managerEmail } } = manager;
console.log(managerEmail); //



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store