Categories
JavaScript Tips

Useful JavaScript Tips — Closures and Arrays

Like any kind of apps, JavaScript apps also have to be written well.

Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at some tips we should follow to write JavaScript code faster and better.

Looping Over Arrays

JavaScript provides many array methods that we can use to work with arrays in a concise manner.

while Loop

We can use the while loop to loop through arrays.

For instance, we can write:

let index = 0;
const arr = [1,2,3];

while (index < arr.length) {
  console.log(arr[index]);
  index++;
}

We update the index at each iterator to access the objects in arr .

Classical for Loop

There’s also the classical for loop for iterating overt items in an array.

It works by setting up the initial condition, the ending condition, and the array index update statement on the first line of the loo.

For instance, we write:

const arr = [1,2,3];
for (let index = 0; index < arr.length; index++) {
  console.log(arr[index]);
}

forEach

We can use the forEach method to loop through array entries.

It takes a callback that we can run code on each entry.

For instance, we can write:

const arr = [1,2,3];

arr.forEach((val, index, array) => {
  console.log(index, array, val);
});

We have arr which we called forEach on.

Then we get the array entry with val , the index of the entry with index , and the array itself with array .

map

map lets us map our array entries from one to the other.

For instance, we can write:

const arr = [1,2,3];
const cube = x => x ** 3;
const cubes = arr.map(cube);

We have the cube function which we pass in as the callback for the map function.

x has the array entry’s value.

cubes has the new array with each entry of arr cubed.

reduce

The reduce method lets is combine the entries into a single value.

For instance, we can write:

const arr = [1,2,3];
const sum = (total, y) => total + y;
const sum = arr.reduce(sum, 0);

We have arr which we called reduce on by passing in the sum function as its callback.

The first parameter is the accumulate total so far and the second is the entry being added into the total .

The 2nd argument of reduce is the initial value.

The combination of the entries is done from left to right.

There’s also a reduceRight method that combines entries from right to left.

filter

The filter method returns an array that meets the condition in the callback.

For instance, we can write:

const arr = [1,2,3];
const isEven = x => x % 2 === 0;
const evenArr = arr.filter(isEven);

We have isEven , which is a function that checks if an array entry x is evenly divisible by 2.

We call filter on arr with isEven passed in.

Then evenArr should have all the even entries in arr .

every

The every method checks if every entry in the array meet some given condition.

For instance, we can write:

const arr = [1,2,3];
const under10 = x => x < 10;
const allUnder10 = arr.every(under10);

We have under10 , which checks if every entry is under 10.

x is the array entry.

Then we called every with under10 as the callback.

allUnder10 should be true since all entries in arr are less than 10.

some

some checks if one or more elements in the array match the given condition.

For instance, we can write:

const arr = [1,2,3];
const under10 = x => x < 10;
const someUnder10 = arr.some(under10);

Then someUnder10 should be true since there’s at least one entry in arr that’s less than 10.

Closures

We can create an enclosed scope in loops by running:

for (let i = 0; i < 3; i++) {
  funcs[i] = ((value) => {
    console.log(value);
  })(i);
}

This way, we get the value of the index variable looped when we called the function in funcs .

Conclusion

We can use array methods to save us the effort of looping through entries and doing what we want.

Also, we should wrap our code in IIFEs to create a closure with the index variable value of a loop.

Categories
JavaScript Tips

Useful JavaScript Tips — Objects and Scopes

Like any kind of apps, JavaScript apps also have to be written well.

Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at some tips we should follow to write JavaScript code faster and better.

Polluting Global Scope

We should never define global variables to declare the global scope.

To avoid this, we use let and const to declare variables.

For instance, we write:

ler x = 1;

or:

const y = 2;

We shouldn’t declare variables with var or without a keyword before it.

They both declare global variables, which we don’t want.

Likewise, we should not use function declarations.

Instead, we should use function expressions.

So instead of writing:

function foo() {}

We write:

const foo = () => {}

We can also enclose our variables within IIFEs to keep them private:

(() => {
  let  = 1;
})()

Now they are not accessible outside the function.

Use Strict Mode

We should use strict mode to disallow some bad constructs in our code.

For instance, we can’t assign things to reserved keywords like:

undefined = 1;

Also, we can’t accidentally define global variables by assigning to variables without declaring them.

So we can’t create global variables like:

foo = 1;

foo is a global variable since we declared it without a keyword.

Strict Equality

We shoild use the === or !== operators to compare values since data type conversions aren’t done before comparison with them.

For instance, instead of writing:

a == b

We write:

a === b

It’s much safer than the == operator.

Likewise, for inequality, we should use the !== operator.

So we can write:

a !== b

instead of:

a != b

Use && or || to Conditionally Evaluate Expressions

We should use the || operator to return the right operand if the left operand is falsy.

For instance, we can write:

const str = '' || 'foo';

to return 'foo' since empty string is falsy.

Similarly, we can use the && operator to evaluate the right expression if the left expression is truthy.

So we can write:

const baz = obj.foo && obj.foo.baz;

This way, obj.foo.baz is only returns only if obj.foo is truthy.

This can avoid lots of undefined errors when accessing nested properties.

Convert Value Types

We can convert strings to numbers by using the + operator.

For instance, we can write:

const foo = +'100'

to get 100 as the value of foo .

Also, we can use the !! operators to convert anything to a boolean.

For example, we can write:

!!0

to convert it to false since it’s falsy.

Follow Style Guides

There are many good style guides that we can follow to write good JavaScript code.

For instance, we can following the Google JavaScript Style Guide, airbnb/javascript guide, and others so that we can follow some good practices when writing JavaScript.

To automate the process of checking for bad good, we can use ESLint co check for them.

Creating Immutable Objects in JavaScript

We can create immutable objects in JavaScript with the Object.seal method.

For instance, we can write:

Object.seal(foo);

to make foo immutable.

It makes the object immutable and doesn’t return anything.

It prevents the modification of property descriptors.

There’s also the Object.preventExtensions for preventing adding properties to an object.

For instance, we can write:

Object.`preventExtensions`(foo);

Also, we can write:

`Object.freeze(`foo`);`

Then we can do all the things that seal and prevenExtensions does.

Creating Hash Maps without Side Effects

We can create a pure object without a prototype by using Object.create with the null argument.

For instance, we can write:

const map = Object.create(null);

Then the map object won’t have a prototype.

We can use it as a dictionary safely.

Cloning Immutable Objects

We can use the clone package to clone an object.

For instance, we can write:

const clone = require('clone');

const a = { foo: { bar: 1 } };
const b = clone(a);

Now we can clone a and make the clone a value of b so that we can us manipulate b without affecting a .

Conclusion

We can prevent objects from being modified with some Object methods.

Also, we can use the clone property to clone objects.

In addition, we can use && or || to do things other than creating boolean expressions.

Categories
JavaScript Tips

Useful JavaScript Tips — Numbers and String Whitespaces

Like any kind of apps, JavaScript apps also have to be written well.

Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at some tips we should follow to write JavaScript code faster and better.

Check if a Number is Finite

The isFinite method lets us check if a value is a finite number or not.

For instance:

Number.isFinite(1)

returns true .

On the other hand:

Number.isFinite(1)

returns false .

Format a Decimal Number into a String

We can use the toFixed method to format a decimal number into a string.

For instance, we can write:

(20.22).toFixed()

and get '20' .

Also, we can pass in the number of decimal digits we want to keep by writing:

(20.22).toFixed(1)

and get “20.2” .

Format a Number into a Language Sensitive String

The toLocaleString method lets us get a string that has a number formatted according to the locale.

For instance, we can write:

(20.22).toLocaleString('fr-ca')

Then we get “20,22” .

Format a Number into Exponential Notation

The toExponential method lets us convert a number into a string that’s in exponential notation.

For instance, we can write:

(21.22).toExponential()

Then we get “2.122e+1” .

Change the Number of Decimal Digits of a Number

The toPrecision method formats a number into a string that has the given number of decimal digits.

For instance, we can write:

(21.21).toPrecision(5)

Then we get “21.210” .

We can also pass in a number that’s smaller than the number of decimal digits in the number.

Then we get a string with the number formatted into exponential notation.

For instance, we can write:

(21.21).toPrecision(1)

And we get “2e+1” .

Converting a Number to a String

The toString method converts a number to a string.

The argument it takes is the radix.

For instance, if we want to convert the decimal number 10 to binary, we can write:

(10).toString(2)

Then it returns “1010" .

Parsing a String into an Integer

We can parse a string into an integer with the parseInt method.

For instance, we can write:

Number.parseInt('10.00')

and we get back 10.

It also takes a second argument with the radix.

So if we want to convert it to a given base, we can do that by writing:

Number.parseInt('16', 16)

Then we get 22 since we converted '16' to a base 16 number.

Parsing a String into a Floating Point Number

There’s the Number.parseFloat method to convert a string into a floating-point number.

For instance, we can write:

Number.parseFloat('10.00')

and get 10.

It can also convert a string to a number if it starts with a number by removing the non-numerical parts and converting the rest to a number.

For example, we can write:

Number.parseFloat('36 bottles')

Then we get 36.

Check if a Number is Within a Safe Range

In JavaScript, a number is considered to be safe if it’s between -2 ** 53 and 2 ** 53 .

To check that, we can use the Number.isSafeInteger method.

For instance, we can write:

Number.isSafeInteger(2 ** 53)

which returns true , and:

Number.isSafeInteger(2 ** 53 + 1)

which is false .

Checking if a Value is NaN

Checking for NaN is tricky.

Therefore, we should use the Number.isNaN to do it since we can’t use === to do the comparison.

For instance, we can write:

Number.isNaN(NaN)

and that would return true .

Also:

Number.isNaN('foo' / 'bar')

returns true .

Check if a value is an Integer

The isInteger method lets us check if a value is an integer.

We can use it by writing:

Number.isInteger(1)

which returns true , or:

Number.isInteger(0.2)

which returns false .

Trimming the beginning of a String

We can remove whitespace from the beginning of a string with the trimStart method.

For instance, we can write:

'   foo'.trimStart()

Then it returns “foo” .

Trimming the End of a String

There’s also the trimEnd method to remove whitespace from the end of a string.

For example, we write:

'foo   '.trimStart()

Then it returns “foo” .

Trimming Both Ends of a String

The trim method will remove whitespace from both ends of a string.

For instance, we can write:

'   foo   '.trim()

Then it returns 'foo' .

Conclusion

There are various ways to parse and check numbers.

Also, JavaScript strings have methods to remove whitespaces.

Categories
JavaScript Tips

Useful JavaScript Tips — Loops and Sorting Dates

Like any kind of apps, JavaScript apps also have to be written well. Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at some tips we should follow to write JavaScript code faster and better.

Break Out of a for Loop

If we want to end a for loop early, we can use the break keyword.

For instance, we can write:

for (const val of list) {
  console.log(val);
  if (val === 'b') {
    break;
  }
}

If val is 'b' then we end the loop with break .

We can also do the same with an old for loop:

for (let i = 0; i < list.length; i++) {
  console.log(list[i]);
  if (list[i] === 'b') {
    break;
  }
}

We do the same thing, except it’s longer because of the indexes.

Check if an Object is Empty

We can check if an object is empty with the Object.entries method. It returns the non-inherited key-value pairs in an object.

Therefore, we can write:

Object.entries(obj).length === 0

to check if obj is empty by checking the array returned by Object.entries ‘s length.

It’s a good idea to check that obj is actually by adding:

obj.constructor === Object

Lodash also has the isEmpty function to do the same thing.

We can write:

_.isEmpty(obj)

to do the check.

Return the Result of an Async Function

An async function returns a promise with the resolved value of the promise.

For instance, if we write:

const getJSON = async () => {
  const response = await fetch('./file.json')
  return response
}

then we return a promise that resolves to the response object. We can then use it with other async functions or call then on it.

Check if a JavaScript Array has a Given Value

We can use the includes method to check if an array has the given value.

For instance, we can write:

['red', 'green'].includes('red');

Then we can check if 'red' is in the array it’s called on. It should return true since it’s included in the array. If the value in the argument isn’t included, then it returns false .

Rename Fields When Object Destructuring

We can rename fields when we’re destructuring objects. To do that, we can use the : symbol to do it.

For instance, we can write:

const person = {
  firstName: 'james',
  lastName: 'smith'
}

const { firstName: name, lastName } = person;

Then we renamed firstName to name. So name is 'james'.

Using Symbols

We can use symbols to create an identifier that’s always unique. Each symbol that’s created won’t be the same even if they have the same content.

For instance:

Symbol() === Symbol()

returns false .

Symbol('foo') === Symbol('foo')

is also false .

We can use them as property identifiers.

For instance, we can write:

const foo = Symbol('foo');
const obj = {
  [foo](){
    //...
  }
}

We can also write:

const foo = Symbol('foo');
class Bar {
  [foo](){
    //...
  }
}

We can use symbols in both objects and classes as identifiers.

Public Class Fields

We can add public class fields by putting them in constructors or methods.

For instance, we can write:

class Foo {
  constructor() {
    this.count = 0
  }
}

Sorting an Array by Date

To sort an array by date, we can use the sort method and compute the difference between the dates 2 entries and return it.

For instance, given the following array:

const tasks = [{
    title: 'eat',
    date: new Date('2020-06-23')
  },
  {
    title: 'drink',
    date: new Date('2020-06-10')
  },
  {
    title: 'sleep',
    date: new Date('2020-06-22')
  }
]

We can sort it by date descending order by writing:

tasks.sort((a, b) => +b.date - +a.date);

sort sorts an array in place.

The + operator converts dates to UNIX timestamps so that we can compute their difference.

If the difference is more than 1, then sort reverses the order of the 2 entries.

So we get:

[
  {
    "title": "eat",
    "date": "2020-06-23T00:00:00.000Z"
  },
  {
    "title": "sleep",
    "date": "2020-06-22T00:00:00.000Z"
  },
  {
    "title": "drink",
    "date": "2020-06-10T00:00:00.000Z"
  }
]

as the value of tasks .

We can flip a and b around to sort tasks in date ascending order.

To make a copy of tasks before sorting, we can use the spread operator or slice as follows:

const sortedTasks = [...tasks];
sortedTasks.sort((a, b) => +b.date - +a.date);

or:

const sortedTasks = tasks.slice();
sortedTasks.sort((a, b) => +b.date - +a.date);

Conclusion

We can use break to end a loop early.

To sort objects with dates, we can return the difference between the timestamps.

Also, we can check if an object is empty with Object.entries to return an array of key-value pairs and use the length property.

Categories
JavaScript Tips

Useful JavaScript Tips — Strings, Arrays, and Images

Like any kind of apps, JavaScript apps also have to be written well.

Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at some tips we should follow to write JavaScript code faster and better.

Cut a String into Words

To divide a string into words, we can use the split method.

For instance, we can write:

const text = "hello james smith";
const arr = text.split(" ");

Then text would be split into an array of strings by their spaces.

So arr would be [“hello”, “james”, “smith”] .

Load an Image into the Canvas

We can load an image into the canvas by using the drawImage method of the canvas context.

For instance, if we have the following canvas:

<canvas width="300" height="300"></canvas>

and image element:

<img id='cat' style='visibility: hidden' src='http://placekitten.com/200/200' />

We can write:

const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
const img = document.getElementById("cat");
context.drawImage(img, 90, 90, 50, 60, 10, 10, 50, 60);

The first argument of drawImage is the image element.

The 2nd argument is the x coordinate of the top left corner of the image.

The 3rd is the y coordinate of the top left corner.

The 4th is the width of the sub-rectangle of the source image.

The 5th is the height of the sub-rectangle of the source image.

The 6th is the x-coordinate of the destination canvas to place the top-left corner of the source.

The 7th is the y coordinate of the top left corner.

The 8th is the width of the image to the destination canvas.

The last one is the height of the image in the destination.

Slowing Down a Loop

We can slow down a loop with promises.

First, we create our own sleep function with the setTimeout function:

const sleep = (ms) => {
  return new Promise(resolve => setTimeout(resolve, ms))
}

We return a promise that runs setTimeout and call resolve . ms is the delay in milliseconds.

Then we can run the sleep function in a loop by running:

const list = [1, 2, 3];
(async () => {
  for (const item of list) {
    await sleep(1000);
    console.log(item)
  }
})();

We have an array list , which we loop through in an async function.

In the loop body, we called sleep with 1000 to delay the loop by 1 minute.

Then we log the item with the console.log.

Get the First n Items in an Array

To get the first n items in an array, we can use the slice method.

For instance, we can write:

const arr = [1, 2, 3, 4, 5];
const newArray = arr.slice(0, 2);

to return the first 2 array entries from arr in a new array.

So newArray would be [0, 1] .

Convert an Array to a String

We can call the toString method to convert an array to a string.

For instance, we can write:

const list = [1, 2, 3];
const str = list.toString();

Then we get “1,2,3” as the value of str .

It’s not very flexible since it converts it the way it likes to.

To add more flexibility, we can use the join method.

For instance, we can write:

const list = [1, 2, 3];
const str = list.join();

to concatenate the entries of the array into a string.

We can pass in a separator to separate the entries.

So we can write:

const list = [1, 2, 3];
const str = list.join(', ');

To use the comma as a separator.

Flattening Arrays

We can flatten arrays with flat and flatMap .

For instance, we can write:

const animals = ['dog', ['cat', 'wolf']];
const flattened = animals.flat();

We called flat , which is a built-in array method.

Then we see that flattened is [“dog”, “cat”, “wolf”] .

flat can flatten arrays at any level.

If we pass in 2, then it flattens 2 nesting levels.

If we pass in Infinity , then flattening is done recursively.

So if we call:

const animals = ['dog', [['cat', 'wolf']]];
const flattened = animals.flat(2);

We get the same result.

If we write:

const animals = ['dog', [['cat', 'wolf']]];
const flattened = animals.flat(Infinity);

We get complete flattening, which also means the same result.

Conclusion

We can flatten arrays easily with flat .

Also, we can load images from the img tag into a canvas with drawImage .

To pause execution of JavaScript code, we can use setTimeout with promises.