Level Up Your Javascript Skills: 12 Basic Notions

by admin admin Date: 25-02-2019 javascript guide tips


If you are a developer at any level, understanding its basic concepts is crucial.

This article highlights 12 basic concepts that are critical to understanding by any JS developer, but do not represent the full range of what a JS developer should know.

1. Value vs. Reference Variable Assignment

To coding bug-free JavaScript, is essential to understand how JavaScript assigns variables. If you don't understand it, you can easily write code that changes values inadvertently.

JavaScript always assigns variables by value: when the assigned value is one of JavaScript’s five primitive type (i.e., Boolean, null, undefined, String, and Number) the actual value is assigned. However, when the assigned value is an Array, Function, or Object a reference to the object in memory is assigned.

Let's make an example.

In the following code, var2 is set as equal to var1. Since var1 is a primitive type (String), var2 is set as equal to var1's String value and can be thought of as completely distinct from var1 at this point. Accordingly, reassigning var2 has not effect on var1.

let var1 = 'My string';
let var2 = var1;
var2 = 'My new string';
console.log(var1);
// 'My string'
console.log(var2);
// 'My new string'

Now, let’s compare this with object assignment.

let var1 = { name: 'Jim' }
let var2 = var1;
var2.name = 'John';
console.log(var1);
// { name: 'John' }
console.log(var2);
// { name: 'John' }

If you expected behavior like primitive assignment, you could see how this could cause problems! This can be particularly hideous if you create a function that mutates an object unintentionally.

2. Closures

"Closure" is an important JavaScript pattern for accessing a variable privately. In this example, createGreeter returns an anonymous function with access to the greeting provided, "Hello." SayHello will have access to this greeting for all future uses!

 

function createGreeter(greeting) {
  return function(name) {
    console.log(greeting + ', ' + name);
  }
}
const sayHello = createGreeter('Hello');
sayHello('Joe');
// Hello, Joe

In another scenario, you can imagine an initial apiConnect (apiKey) function that returns some methods that use the API key. The apiKey should only be provided once and never again in this case.

function apiConnect(apiKey) {
  function get(route) {
    return fetch(`${route}?key=${apiKey}`);
  }
  function post(route, params) {
    return fetch(route, {
      method: 'POST',
      body: JSON.stringify(params),
        headers: {
          'Authorization': `Bearer ${apiKey}`
        }
      })
  }
  return { get, post }
}
const api = apiConnect('my-secret-key');
// No need to include the apiKey anymore
api.get('http://www.example.com/get-endpoint');
api.post('http://www.example.com/post-endpoint', { name: 'Joe' });

3. Destructuring

Don't be discarded by destructing the JavaScript parameter! It is a common way of extracting properties from objects cleanly.

const obj = {
  name: 'Joe',
  food: 'cake'
}
const { name, food } = obj;
console.log(name, food);
// 'Joe' 'cake'

If you want to extract properties under a different name, you can specify them using the following format.

const obj = {
  name: 'Joe',
  food: 'cake'
}
const { name: myName, food: myFood } = obj;
console.log(myName, myFood);
// 'Joe' 'cake'

Destructuring is used in the following example to pass the person object cleanly to the introduction function. In other words, destructuring can (and is often) used directly to extract function parameters. If you know React, you've probably seen this before!

const person = {
  name: 'Eddie',
  age: 24
}
function introduce({ name, age }) {
  console.log(`I'm ${name} and I'm ${age} years old!`);
}
console.log(introduce(person));
// "I'm Eddie and I'm 24 years old!"

4. Spread Syntax

The spread operator is a JavaScript concept that can throw people away but is relatively simple! Math.max can not be applied to the array in the following case because it does not take an array as an argument, it takes the individual elements as arguments. The spread operator ... is used to remove the array from the individual elements.

const arr = [4, 6, -1, 3, 10, 4];
const max = Math.max(...arr);
console.log(max);
// 10

5. Rest Syntax

Let's talk about the rest syntax of JavaScript. You can use it to place in an array any number of arguments passed to a function!

function myFunc(...args) {
  console.log(args[0] + args[1]);
}
myFunc(1, 2, 3, 4);
// 3

6. Array Methods

Array methods of JavaScript can often provide you with incredible, elegant ways to transform the data you need. We often see questions on how a variety of objects can be manipulated in one way or another on the web. This is usually the perfect case for array methods.

We are going to cover a number of different array methods, organized by similar methods that are sometimes conflated. This list is not comprehensive in any way: We encourage you to review and practice all of them on MDN.

map, filter, reduce

There is some confusion around the JavaScript array methods map, filter, reduce. These are helpful methods for transforming an array or returning an aggregate value.

map: return array where each element is transformed as specified by the function

const arr = [1, 2, 3, 4, 5, 6];
const mapped = arr.map(el => el + 20);
console.log(mapped);
// [21, 22, 23, 24, 25, 26]

filter: return array of elements where the function returns true

const arr = [1, 2, 3, 4, 5, 6];
const filtered = arr.filter(el => el === 2 || el === 4);
console.log(filtered);
// [2, 4]

reduce: accumulate values as specified in function

const arr = [1, 2, 3, 4, 5, 6];
const reduced = arr.reduce((total, current) => total + current);
console.log(reduced);
// 21

find, findIndex, indexOf

The array methods find, findIndex, and indexOf can often be conflated. Use them as follows.

find: return the first instance that matches the specified criteria. Does not progress to find any other matching instances.

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const found = arr.find(el => el > 5);
console.log(found);
// 6

Note once again that while everything meets the criteria after 5, only the first matching element is returned. In situations where you normally break a for loop when you find a match, this is really super helpful!

findIndex: This works almost identically to find, but rather than returning the first matching element it returns the index of the first matching element. Take the following example, which uses names instead of numbers for clarity.

const arr = ['Nick', 'Frank', 'Joe', 'Frank'];
const foundIndex = arr.findIndex(el => el === 'Frank');
console.log(foundIndex);
// 1

indexOf: Works almost identically to findIndex, but instead of taking a function as an argument it takes a simple value. You can use this when you have simpler logic and don’t need to use a function to check whether there is a match.

const arr = ['Nick', 'Frank', 'Joe', 'Frank'];
const foundIndex = arr.indexOf('Frank');
console.log(foundIndex);
// 1

push, pop, shift, unshift

There are a lot of great array method to help add or remove elements from arrays in a targeted fashion.

push: This is a relatively simple method that adds an item to the end of an array. It modifies the array in-place and the function itself returns the item added to the array.

let arr = [1, 2, 3, 4];
const pushed = arr.push(5);
console.log(arr);
// [1, 2, 3, 4, 5]
console.log(pushed);
// 5

pop: This removes the last item from an array. Again, it modifies the array in place. The function itself returns the item removed from the array.

let arr = [1, 2, 3, 4];
const popped = arr.pop();
console.log(arr);
// [1, 2, 3]
console.log(popped);
// 4

shift: This removes the first item from an array. Again, it modifies the array in place. The function itself returns the item removed from the array.

let arr = [1, 2, 3, 4];
const shifted = arr.shift();
console.log(arr);
// [2, 3, 4]
console.log(shifted);
// 1

unshift: This adds one or more elements to the beginning of an array. Again, it modifies the array in place. Unlike a lot of the other methods, the function itself returns the new length of the array.

 

let arr = [1, 2, 3, 4];
const unshifted = arr.unshift(5, 6, 7);
console.log(arr);
// [5, 6, 7, 1, 2, 3, 4]
console.log(unshifted);
// 7

splice, slice

These methods either modify or return subsets of arrays.

splice: Change the contents of an array by removing or replacing existing elements and/or adding new elements. This method modifies the array in place.

The following code sample can be read as: at position 1 of the array, remove 0 elements and insert b.

let arr = ['a', 'c', 'd', 'e'];
arr.splice(1, 0, 'b')

slice: returns a shallow copy of an array from a specified start position and before a specified end position. If no end position is specified, the rest of the array is returned. Importantly, this method does not modify the array in place but rather returns the desired subset.

let arr = ['a', 'b', 'c', 'd', 'e'];
const sliced = arr.slice(2, 4);
console.log(sliced);
// ['c', 'd']
console.log(arr);
// ['a', 'b', 'c', 'd', 'e']

sort

Sorts an array based on the provided function which takes a first element and second element argument. Modifies the array in place. If the function returns negative or 0, the order remains unchanged. If positive, the element order is switched.

let arr = [1, 7, 3, -1, 5, 7, 2];
const sorter = (firstEl, secondEl) => firstEl - secondEl;
arr.sort(sorter);
console.log(arr);
// [-1, 1, 2, 3, 5, 7, 7]

7. Generators

Don’t worry about the *. The generator function specifies what value is yielded next time next() is called. Can either have a finite number of yields, after which next() returns an undefined value, or an infinite number of values using a loop.

function* greeter() {
  yield 'Hi';
  yield 'How are you?';
  yield 'Bye';
}
const greet = greeter();
console.log(greet.next().value);
// 'Hi'
console.log(greet.next().value);
// 'How are you?'
console.log(greet.next().value);
// 'Bye'
console.log(greet.next().value);
// undefined

And using a generator for infinite values:

function* idCreator() {
  let i = 0;
  while (true)
    yield i++;
}
const ids = idCreator();
console.log(ids.next().value);
// 0
console.log(ids.next().value);
// 1
console.log(ids.next().value);
// 2
// etc...

8. Identity Operator (===) vs. Equality Operator (==)

Make sure you know the difference the in JavaScript between the identify operator (= = =) and the equality operator (= =). Before comparing values, the = = operator will perform type conversion, while the = = = operator will not perform any type conversion before comparing.

console.log(0 == '0');
// true
console.log(0 === '0');
// false

9. Object Comparison

An error I see is that newcomers to JavaScript compare objects directly. Variables refer to to to the memory objects, not the objects themselves! One way to compare them actually is to convert objects to JSON strings.

But this has a disadvantage: object property order is not guaranteed! A safer way to compare objects is to pull a library specializing in the comparison of deep objects (e.g. isEqual for lodash).

The following objects appear equal but they are in fact pointing to different references.

const joe1 = { name: 'Joe' };
const joe2 = { name: 'Joe' };
console.log(joe1 === joe2);
// false

In contrast, the following is true because one object is equal to the other object and therefore points to the same reference (only one object is in memory).

const joe1 = { name: 'Joe' };
const joe2 = joe1;
console.log(joe1 === joe2);
// true

To fully understand the ramifications of setting a variable equal to another variable that points to a reference to an object in memory, be sure to review the value vs. reference section above!

 

10. Callback Functions

Far too many people are intimidated by JavaScript callback functions! They are simple, take this example. The console.log function is being passed as a callback to myFunc. It gets executed when setTimeout completes. That’s all there is to it!

 

function myFunc(text, callback) {
  setTimeout(function() {
    callback(text);
  }, 2000);
}
myFunc('Hello world!', console.log);
// 'Hello world

11. Promises

Once you understand the JavaScript callbacks , you'll soon find yourself in a nested "callback hell."

Wrap your async logic in a Promise and resolve on success or reject on fail. Use “then” to handle success and catch to handle failure.

const myPromise = new Promise(function(res, rej) {
  setTimeout(function(){
    if (Math.random() < 0.9) {
      return res('Hooray!');
    }
    return rej('Oh no!');
  }, 1000);
});
myPromise
  .then(function(data) {
    console.log('Success: ' + data);
   })
   .catch(function(err) {
    console.log('Error: ' + err);
   });
   
// If Math.random() returns less than 0.9 the following is logged:
// "Success: Hooray!"
// If Math.random() returns 0.9 or greater the following is logged:
// "Error: On no!"

12. Async Await

Once you get the hang of JavaScript promises, you might like async await, which is just “syntactic sugar” on top of promises. In the following example we create an async function and within that we await the greeter promise.

const greeter = new Promise((res, rej) => {
  setTimeout(() => res('Hello world!'), 2000);
})
async function myFunc() {
  const greeting = await greeter;
  console.log(greeting);
}
myFunc();
// 'Hello world!'

If you didn't know about any of these 12 concepts, you've probably grown in JavaScript at least a little! And if you knew them all, I hope it was an opportunity to practice and develop your knowledge. What other concepts are critical to you? In the comments, let me know.

 

 

Original Source

Business vector created by freepik - www.freepik.com

 
by admin admin Date: 25-02-2019 javascript guide tips hits : 3315  
 
 
 
 

Related Posts