Categories
JavaScript Tips

Useful JavaScript Tips — Timestamps, Combining Values, and Calling Functions

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.

Extracting UNIX Timestamps in JavaScript

We can get the UNIX timestamp of a Date instance with the + operator.

For instance, we can write:

+new Date(2020, 0, 1)

Then we get 1577865600000.

Also, we can use the getTime method to do the same thing:

new Date(2020, 0, 1).getTime()

Then we get the same thing returned.

The date can also be parsed if it’s in YYYY-MM-DD format.

So we can write:

new Date('2020-01-01').getTime()

And we also get the same thing.

The timestamp is in the number milliseconds since January 1, 1970 12AM UTC.

So we can divide the returned number by 1000 to convert it to seconds.

Combining Array Values into One

We can use the reduce method to reduce array entries into one result.

For instance, if we have:

const cart = [{price: 10}, {price: 40}, {price: 20}];

Then we get can the total price from the cart by writing:

`const reducer = (total, item) => total + item.price;const total =` cart`.reduce(reducer, 0);`

Then total is 70 since we combined all the cart entries’ price properties by adding their values together.

Detect if a Document is Ready

We can detect if a page is loaded completely with the document.readyState property.

For instance, we can write:

if (document.readyState === 'complete') {
  //...
}

to detect if a page is fully loaded and then do something.

We can also check the state periodically using:

let stateCheck = setInterval(() => {
  if (document.readyState === 'complete') {
    clearInterval(stateCheck);
    // document ready
  }
}, 100);

Then we can check the loading state of the page every 100 milliseconds until it’s ready.

In the if block, we call clearInterval to end the timer so we’ll stop checking for the readyState .

Also, we can listen to the readystatechange event with:

document.onreadystatechange = () => {
  if (document.readyState === 'complete') {
    // document ready
  }
}

This is better than creating a timer and running it until the ready state changes.

Calculate the Maximum or Minimum Value of an Array

We can pass in as many values into the Math.max or Math.min methods to check for the max or min values of the array.

For instance, we can write:

const max = Math.max(1, 2, 3);

to return the maximum value or:

const min = Math.min(1, 2, 3);

to return the minimum value.

To pass in an array, we can use the spread operator:

const max = Math.max(...[1, 2, 3]);

or:

const min = Math.min(...[1, 2, 3]);

Or we can use apply as follows:

const max = Math.max.apply(undefined, [1, 2, 3]);

or:

const min = Math.min.apply(undefined, [1, 2, 3]);

apply takes the value of this as the first argument, which is undefined since Math.max and Math.min are static methods.

The 2nd argument is an array of arguments that we want to pass in as arguments into the array.

Destructuring in Function Parameters

We can destructure object parameters with the destructuring syntax.

For instance, we can write:

const greet = ({ name, lastName }) => {
  console.log(`hi, ${name} ${lastName}`);
};

We get the object’s name and lastName properties with the destructuring assignments.

Then we can call it by calling:

greet({ name: 'jane', lastName: 'doe' })

We can also set a default value for the destructured variables.

For instance, we can write:

const greet = ({ name = 'jane', lastName = 'smith' }) => {
  console.log(`hi, ${name} ${lastName}`);
};

Then when we call it by writing:

greet({})

Then name is 'jane' and lastName is 'smith' since we didn’t set the value of either property.

Prevent Changing Built-in Prototypes

We can call Object.freeze to prevent changing objects, which include built-in prototypes.

So we can write:

Object.freeze(Object.prototype);
Object.freeze(Array.prototype);
Object.freeze(Function.prototype);

to prevent changing any built-in prototypes.

Conclusion

We can prevent changing built-in prototypes with Object.freeze .

Also, we can use the spread operator or apply to call a function with an array of arguments.

There are also various ways to get a UNIX timestamp.

Categories
JavaScript Tips

Useful JavaScript Tips — Objects, Methods, and URLs

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.

Select a Method Dynamically

We can select a method dynamically by using the bracket notation.

For example, we can write:

animal[isDog ? 'bark' : 'speak']()

instead of:

if (isDog) {
  animal.bark()
} else {
  animal.speak()
}

They do the same thing.

The first uses the ternary operator.

The second us the if statement.

The first one is shorter, so we can consider using it.

Tools for Debugging

We can use the console object to help us debug.

For instance, we can use console.log to log the value of an expression.

We can write:

console.log(a)

to log the value of a .

Chrome Dev Tools

The output of the console log ends up in the Console tab of the Chrome dev tools.

Debugger

The Chrome Dev Tools window also has a debugger built-in.

We can add breakpoints and check the variable values there.

The debugger is in the Sources tab.

We can go to a file and toggle on breakpoints.

Then the code will pause at the breakpoint.

There is more than one type of breakpoint.

One is the XHR/fetch breakpoint which halts the program when a network request is sent.

DOM breakpoints are triggered when DOM element changes.

Event listener breakpoints are trigger when an event happens.

All variables in the scope are printed when a breakpoint is reached.

We can click the + button on the breakpoint to show the values of the expression.

If we want to continue running the code, we can step over the code to resume execution until the next line and stops.

Step into goes into the function being run.

The same pane has the call stack, which has all the functions called recorded.

We can use:

node --inspect

to debug Node.js apps in the browser.

Call and Apply

call and apply can be used to change the value of this and call a function.

It works with traditional function.

For instance, given the following function:

function greet(greeting) {
  console.log(`${greeting}, ${this.name}`);
}

We can write:

greet.call({
  name: 'james'
}, 'hi');

We used the call function to call greet by setting the value of this with the first argument.

Then pass in the argument we want to the greet function as the second argument.

Therefore, we see that 'hi, james’ is logged in the console.

apply is similar, except the arguments are passed in as an array.

For instance, we can write:

function greet(greeting) {
  console.log(`${greeting}, ${this.name}`);
}

greet.apply({
  name: 'james'
}, ['hi']);

We have an array instead of just the argument as the 2nd argument.

And we get the same result.

Count the Number of Properties in an Object

We can use Object.keys to return an array of noninherited string property keys.

Therefore, we can use the length property to get the number of properties in the object.

For instance, if we have:

const dog = {
  color: 'white',
  breed: 'poodle'
}

Then we can write:

Object.keys(dog).length

Then we get 2 since dog has 2 own properties.

Sort an Array of Object by its Property Value

The sort method can be used to sort an array of objects by its property value.

For instance, if we have:

const list = [
  { color: 'red', size: 'm' },
  { color: 'green', size: 's' },
  { color: 'blue', size: 'xl' }
]

Then we can write:

list.sort((a, b) => (a.color > b.color)

Then we sort the entries by the color property alphabetically.

Then we get that list is:

[
  {
    "color": "blue",
    "size": "xl"
  },
  {
    "color": "green",
    "size": "s"
  },
  {
    "color": "red",
    "size": "m"
  }
]

Encode a URL

JavaScript comes with the encodeURI() function to encode the URL.

For instance, if we have:

encodeURI("http://example.com/ hello!/")

Then we get:

"http://example.com/%20hello!/"

returned.

There’s also the encodeURIComponent() function that encodes everything including the URL path separators.

For instance, we can write:

encodeURIComponent("http://example.com/ hello!/")

Then we get:

"http%3A%2F%2Fexample.com%2F%20hello!%2F"

returned.

Conclusion

We can select a method dynamically with brackets and expressions inside them.

Also, we can encode URLs with encodeURI or encodeURIComponent depending on our needs.

Debugging is also easy with the debugger.

Sorting items is easy if we pass in a callback.

Categories
JavaScript Tips

Useful JavaScript Tips — Objects

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.

Picking and Reject Object Properties

We can use the Object.keys method to get the keys and pick the ones we want.

For instance, we can write:

const reject = (obj, keys) => {
  return Object.keys(obj)
    .filter(k => !keys.includes(k))
    .map(k => Object.assign({}, {[k]: obj[k]}))
    .reduce((res, o) => Object.assign(res, o), {});
}

In the code above, we called Object.keys to get the keys.

Then we called map to map the object key to their own object with the property value of the key as the value.

Then we used reduce to combine the objects array from map into one object with reduce .

We can call it by writing:

const obj = {
  foo: 1,
  bar: 2,
  bar: 3
}
const newOb = reject(obj, ['foo', 'bar']);

Using Object.is for Object Comparisons

We can use the Object.is method for comparisons. The difference between === and Object.is is that NaN equals itself.

For instance, we can write:

Object.is(NaN, NaN);

and it would return true .

Create a Function to Log Values

We can create a function that logs the value and return it so that we can do both when debugging.

For instance, we can write:

const tap = (x) => {
  console.log(x);
  return x;
}

Then we log x and return it with the function.

It’s handy for things like:

.filter(c => tap(c.numItems > 100))

Then we can log the value of the express and return it at the same time.

Array Tricks

We can do a few things with arrays that we may not have thought of yet.

Iterating Through an Empty Array

We can create an arrays with empty slots with the array constructor.

To do that we can write:

const arr = new Array(10);

Passing in a number as its only arguments makes the constructor return array with the given number of empty slots.

Since we passed in 10, we get an array with 10 empty slots.

Populating Empty Arrays

We can use fill to populate empty arrays.

For instance, we can write:

const arr = new Array(10);
const nums = arr.fill().map((_, i) => i)

to create an array with numbers from 0 to 9.

We call fill to fill the empty slots with undefined . Then we can call map with a callback to return the array index to fill it with numbers.

Passing an Empty Parameter to a Method

We can pass in null or undefined to skip arguments.

For instance, we can write:

foo('a', null, 'b')

or:

foo('a', undefined, 'b')

But we can also use the spread operator and write:

foo(...['a', , 'b']);

Then we can skip an entry in the array.

When we spread the entries as arguments, it’ll become undefined so we do the sam,e thing as the previous example.

Unique Array Values

We can remove duplicates from an array by converting it to a set and then convert it back to an array with the spread operator.

For instance, we can write:

const arr = [...new Set([1, 2, 3, 3])];

Then we get:

[1, 2, 3]

as the value of arr .

Binding Objects to Functions

We can use bind to return a function with the value of this that we want.

for instance, if we have:

const getName = function () {
 console.log(this.name);
};

Then if we write:

const getJoe = getName.bind({ name: 'joe' });

Then this.name would be 'joe' in getJoe since bind returns a function that has the value of this as given in the first argument.

Likewise, we can write:

const getJane = getName.bind({ name: 'jane' });

Then this.name would be 'jane' .

Conclusion

We can create arrays with empty slots with the Array constructor.

Then, we can use the fill method to fill it with entries.

We can return a new object without some properties by using Object.keys and Object.assign .

Also, we can use Object.is to compare values including NaN . Therefore, it’s slightly more useful than === .

Categories
JavaScript Tips

Useful JavaScript Tips — Casting and Internationalization

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.

Converting String to Number

The Number function can be used to convert strings to numbers.

For instance, if we write:

Number('1')

Then we get 1.

Strings are trimmed before they’re converted to numbers, so Number(“ 1 “) returns the same result.

Any empty string results in 0.

Also, Number works with decimals. So Number(“1.2”) returns 1.2.

Converting Booleans to a Number

Booleans can also be converted to numbers.

For instance, we can write:

Number(true)

then it returns 1.

If we write:

Number(false)

it returns 0.

Converting Dates to a Number

We can pass a Date instance to a number. Passing a Date instance to Number would return a UNIX timestamp.

For instance, we can write:

Number(new Date(2020, 0, 1))

and it returns 1577865600000.

Converting Special Values to Number

We can pass in special values to Number to convert it to a number.

For instance, we can write:

Number(null)

then it returns 0.

Number(undefined) returns NaN , and Number(NaN) returns NaN .

Converting to Booleans

The Boolean converts any values to a boolean.

Any falsy values will return false . Otherwise, it return true .

For instance, the following all returns false :

Boolean(false)
Boolean(0)
Boolean(NaN)
Boolean("")
Boolean(null)
Boolean(undefined)

All other values returns true .

instanceof Operator

The instanceof operator lets us check value to see if it’s an instance of a constructor,

For instance, we can write:

class Animal {}
class Dog extends Animal {}

Then the following will return true :

const dog = new Dog()
dog instanceof Animal
dog instanceof Dog

It’ll return true for a subclass instance if the right operand is the parent class or subclass.

new Operator

We can use the new operator to create a new object from a constructor.

For instance, we can write:

const date = new Date();

We can also create our own constructor and use the new operator with it:

function Dog(breed, color) {
  this.breed = breed;
  this.color= color;
}

Then we can write:

const dog = new Dog('poodle', 'white');

typeof Operator

We can use the typeof operator to check the type of a value.

For instance, we can write:

typeof 1

and we get 'number' .

typeof '1'

returns 'string' .

typeof { name: 'james' }
typeof [1, 2, 3]

return 'object' .

typeof true

returns 'boolean' .

typeof undefined

returns 'undefined' .

typeof (() => {})

returns 'function' and

typeof Symbol()

returns 'symbol' .

Internationalization

JavaScript’s standard library has its own internationalization API.

The Intl.Collator object gives us access to language-sensitive comparison features.

Intl.DateTimeFormat lets us format dates in a language-sensitive manner.

Intl.NumberFormat lets us format numbers in a language-sensitive manner.

Intl.PluralRules lets us format plurals in a language-sensitive manner.

Intl.RelativeTimeFormat lets us access language-sensitive time formatting features.

Then Intl.getcanonicalLocales lets us check if a locale is valid.

It takes a string or an array of strings.

For instance, we can write:

Intl.getCanonicalLocales('en')

or:

Intl.getCanonicalLocales(['en-us', 'en-gb'])

They both return true since they’re valid locale strings.

On the other hand, if we have:

Intl.getCanonicalLocales('en_gb')

that’ll return false since it’s not a valid locale.

Intl.Collator

The Intl.Collator is a constructor that we can pass in a locale to and then do comparisons based on that locale.

For instance, we can write:

const collator = new Intl.Collator('en-gb')
collator.compare('a', 'c')

Then we get -1, so the strings are in ascending order.

On the other hand, if we have:

collator.compare('d', 'c')

Then 1 is returned, so they are in descending order.

Intl.DateTimeFormat

The Intl.DateTimeFormat constructor lets us access language-sensitive date and time formatting features.

For instance, we can use it as follows:

const date = new Date();
const formatter = new Intl.DateTimeFormat('fr-ca');
const formatted = formatter.format(date);

In the example above, we have the Intl.DateTimeFormat constructor.

We just pass in a locale string into the constructor.

Then we call the format method to call date on it to format the date.

So formatted will be “2020–05–12” .

We can also call the formatToParts function to return an object with the formatted date parts.

For instance, we can write:

const date = new Date();
const formatter = new Intl.DateTimeFormat('fr-ca');
const parts = formatter.formatToParts(date);

Then we get:

[
  {
    "type": "year",
    "value": "2020"
  },
  {
    "type": "literal",
    "value": "-"
  },
  {
    "type": "month",
    "value": "05"
  },
  {
    "type": "literal",
    "value": "-"
  },
  {
    "type": "day",
    "value": "12"
  }
]

as the value of parts .

Conclusion

JavaScript’s standard library has many useful internationalization features.

Also, there are many functions to convert data types.

Categories
JavaScript Tips

Useful JavaScript Tips — Functions and Casting

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.

Function Parameters

A JavaScript function can accept zero or more parameters.

For instance, we can write:

const foo = () => {
  //...
}

or:

const bar = (a) => {
  //...
}

or:

const baz = (a, b) => {
  //...
}

Starting with ES6, we can set default values for parameters,

For instance, we can write:

const baz = (a = 1, b = 2) => {
  //...
}

Then if we don’t pass in anything when we call baz then a is 1 and b is 2.

Since ES2018, trailing commas are allowed for function parameters.

This helps reduce bugs because of missing commas around parameters.

For instance, we can write:

const baz = (a = 1, b = 2,) => {
  //...
}

We can also call a function with trailing commas:

baz(3, 4,)

Also, we can use the spread operator to spread array entries into arguments.

For instance, we can write:

const args = [2, 'foo'];
baz(...args);

We can also destructure object parameters into variables so that we don’t have to remember the order that arguments have to be passed in.

We can write:

const baz = ({ a = 1, b = 2 }) => {
  //...
}

We destructure the properties into variables.

If the property isn’t set, then we set the default value given.

Switch Statements

An alternative to the if-else statements is to use the switch statement.

For instance, we can write:

switch(a) {
  case 1:
    //do something
    break;
  case 2:
    //do something
    break;
  case 3:
    //do something
    break;
}

We check the value of a and then do something given those values.

We need a break statement at the end of each case so that the code below a matching case won’t run.

Alternatively, we can use return :

switch(a) {
  case 1:
    return 'foo';
  case 2:
    return 'bar';
  case 3:
    return 'baz';
}

Also, we can provide a default case which runs if none of the values of a matches.

For instance, we can write:

switch(a) {
  case 1:
    //do something
    break;
  case 2:
    //do something
    break;
  case 3:
    //do something
    break;
  default:
    break;
}

if and else

The if statement makes a program run something if a condition is true .

For instance, the following always runs:

if (true) {
  // do something
}

And this never runs:

if (false) {
  // never runs
}

We can add an else block below an if block if we need to do something if a condition is false .

For instance, we can write:

if (foo) {
  // do something
} else if (bar) {
  // do something else
} else {
  // fallback case
}

delete Operator

The delete operator lets us remove a property from an object.

For instance, we can write:

const dog = {
  breed: 'chow chow',
  color: 'brown'
}

Then we can remove the color property by writing:

delete dog.color;

We can also write:

delete dog['color'];

Converting to Strings

We can call the toString method on primitive values and objects to get the string representation of it.

Converting Number to String

To convert a number to a string, we can use the String function or the toString method.

For instance, we can write:

String(100);

which returns '100', or:

(100).toString();

which returns the same thing.

Convert Boolean to String

Likewise, we can use the String function or toString method to convert booleans to a string.

If we write:

String(true)

or:

true.toString()

we get true .

We can do the same with false .

Convert Date to String

The String function and toString method can also be used to convert Date instances to strings.

For instance, we can write:

String(new Date(2020, 0, 1))

Then we get:

"Wed Jan 01 2020 00:00:00 GMT-0800 (Pacific Standard Time)"

and we can do the same with toString :

(new Date(2020, 0, 1)).toString()

Converting Special Values to String

The String function can also convert null , undefined , or NaN to a string.

If we write:

String(null)

and we get 'null' .

If we write String(undefined) and we get 'undefined' .

String(NaN) returns ‘NaN' .

Conclusion

JavaScript functions can take zero or more function parameters.

We can set default values for them.

The delete operator can be used to remove a property.