Categories
JavaScript Tips

Useful JavaScript Tips — This, Modules, and 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.

Returning Objects to Enable Chaining of Functions

We can return objects in methods to let us chain functions.

For instance, we can do that by writing:

const obj = {
  height: 0,
  width: 0,
  setHeight(height) {
    this.height = height;
    return this;
  },
  setWidth(width) {
    this.width = width;
    return this;
  }
}

Then we can call it by running:

obj.setHeight(100).setWidth(300);

and we get that obj.height is 100 and obj.width is 300.

Also, we can do the same for classes.

For instance, we can write:

class Obj {
  setHeight(height) {
    this.height = height;
    return this;
  }

  setWidth(width) {
    this.width = width;
    return this;
  }
}

Then we can write:

new Obj().setHeight(100).setWidth(300)

Safe String Concatenation

We can use the concat method to concatenate strings.

For instance, we can write:

const one = 1;
const two = 2;
const three = '3';
const result = ''.concat(one, two, three);

Then we get that result is '123' .

Run a Module if it’s not Required

We can check the module.parent property to see if a JavaScript file is required by another file.

For instance, we can write:

if (!module.parent) {
  // run code ...
} else {
  module.exports = app;
}

If module.parent is falsy, then we run the code inside the if block.

Otherwise, we export the module members so that they can be required.

Passing Arguments to callback Functions

We can pass arguments to callback function if we create a function that returns the callback with the arguments included.

For instance, we can write:

const callback = (a, b) => {
  return () => {
    console.log(a + b);
  }
}

Then we can write:

const x = 1, y = 2;
document.getElementById('foo').addEventListener('click', callback(x, y));

We called callback to return a function that adds the 2 arguments together.

This means that we can include those arguments in the callback.

Using indexOf to Check if Something is Included

We can use the indexOf method to check if a string has some substring.

For instance, we can write:

'something'.indexOf('thing') !== -1

or:

'something'.indexOf('thing') >= 0

indexOf returns -1 if a substring isn’t found.

If it’s found, then it returns the first index of the substring.

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

'something'.includes('thing');

Then true is returned if the substring is found.

So, it would return true .

The same methods are also in arrays.

So we can write:

['foo', 'bar'].indexOf('foo') !== -1

or:”

['foo', 'bar'].indexOf('foo') >= 0

or:

['foo', 'bar'].includes('foo')

Arrow Functions

We can use arrow functions to make our code shorter if our function doesn’t have to have its own this .

For instance, we can write:

const squared = arr.map((x) => x ** 2);

We have an implicit return for single statement arrow functions.

It’s much shorter to use them.

However, bind , call , or apply won’t work with them since they don’t have their own this .

Also, we can’t use the arguments object inside it, but that isn’t much of a loss.

Measuring Performance of Our Code

We can use console.time and console.timeEnd to measure the performance of our code.

For instance, we can write:

console.time("populate array");
let arr = Array(100),
    len = arr.length,
    i;

for (i = 0; i < len; i++) {
    arr[i] = new Object();
};
console.timeEnd("populate array");

We start measuring with console.time .

Then we run the code that we want to measure the performance of.

Then we called console.timeEnd to stop measuring.

Making Parameters Mandatory

We can make parameters mandatory if we throw errors in the function that returns the default parameter value.

For instance, we can write:

const err = ( message ) => {
  throw new Error( message );
}

const getSum = (a = err('a is required'), b = err('b is not required')) => a + b

We can call functions when we assign default parameter values.

Therefore, we can throw errors if they’re not set by running the err function.

err only runs if the parameter isn’t set.

Conclusion

We can make chainable functions if we return this in our object or class methods.

Also, we can sure parameters are set if we run a function that throws errors on the right side of the assignment operator.

Categories
JavaScript Tips

Useful JavaScript Tips — Variables 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.

Assignment Operators

We can use compound assignment operators to make updating the values of numeric variables easier.

There are the += , -= , *= , /= , and %= operators which we can use to update numeric variables to whatever value we want based on the current one.

For instance, we can write:

x += 2;

Then we update the value of x by incrementing the current value by 2.

It’s the same as:

x = x + 2;

Likewise, we can do the same with the rest.

-= is subtraction.

*= is multiplication.

/= is for division.

And %= is for getting the remainder based on the current value.

So:

x %= 2;

is the same as:

x = x % 2;

Then we get the remainder of x divided by 2 based on the current value of x and reassigns it.

Converting Truthy or Falsy Values to Boolean

We can use the !! operator to convert anything to a boolean.

For instance, we can write:

!!""
!!0
!!null
!!undefined
!!NaN

They’re all falsy, so they all return false .

Other operands will return true . For instance, if we have:

!!"hi"

then that would return true .

Currying

Curry is the action of converting a function that takes multiple arguments into a series of functions that take a single argument.

It’s useful for creating functions that have some arguments applied and reuse that.

For instance, if we have an add function:

const add = (x, y) => {
  return x + y;
}

Then we can curry the function by writing:

const curriedAdd = (x) => {
  return (y) => {
    return x + y;
  }
}

Then we can call it by writing:

curriedAdd(1)(2)

and get 3.

Partial Application

We can partially apply arguments into a function by writing:

const plus10 = (y) => {
  return 10 + y;
}

Then we can write:

plus10(3);

Then we get 13.

To generalize this, we can write:

const partApply = (f, x) => {
  return (y) => {
    return f(x, y);
  }
}

Then we can call partApply by passing in a function for f and a value for x .

For instance, we can write:

const plus10 = partApply(add, 10);

Then we get 13 if we call plus10(3) since 10 is applied as the first argument.

Filtering and Sorting a List of Strings

We can sort filter strings with the filter method.

We can get the ones that we return an array that has words that have the same length as its index by writing:

const filtered = words
  .filter((word, index) => {
    return word.length > 2
  })

So if we have:

const words = ['do', 'if', 'foo', 'bar'];

Then we get:

["foo", "bar"]

Then we can call sort without any callback to sort strings since that’s how sort sorts array items without a callback.

So we can chain them by writing:

const filtered = words
  .filter((word, index) => {
    return word.length > 2
  })
  .sort();

Then we get [“bar”, “foo”] for filtered .

Using Immediately Invoked Function Expressions (IIFEs)

We can create and use IIFEs to enclose variables in a function so that they stay private.

For instance, we can write:

(() => {
  let x = 1;
  //...
})()

Then x stays inside the function.

This is one way to create private variables in a function.

Quick Way to Convert Numbers

To convert numbers easily, we can use the + operator to convert anything to a number.

For instance, we can write:

const one = +'1';

Then one is the number 1 instead of string '1' since we used the + operator on it.

Shuffle an Array

We can shuffle an array by using the sort method and return a random number that can be positive or negative so that we can shuffle them.

For instance, we can write:

const arr = [1, 2, 3];
arr.sort(() => -1 + (Math.random() * 2));

sort sorts an array in place, so we get a different value of it.

Returning -1 + (Math.random() * 2) will make the callback return something -1 and 1.

Conclusion

We can use various methods to filter and sort arrays.

Also, we can use assignment operators to make assignment statements shorter.

Categories
JavaScript Tips

Useful JavaScript Tips — Arrays, and Variables

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.

Assignment Operators

We can save some typing by using some compound assignment operators.

We can use the ++ and -- operators to increment and decrement by one respectively.

For instance, we can write:

a++

to increment a by 1.

Likewise, we can use:

++a

to do the same thing.

The only difference is whether it returns the later value or the old one.

We can do the same thing with -- , but decrements the value instead.

Ternary Operator

If we have:

const newValue;
if(value > 100) {
  newValue = 5;
} else {
  newValue = 2;
}

Then we can shorten it by writing:

const newValue = (`value > 100) ? 5 : 2;`

They do the same thing.

Null, Undefined, or Empty Checks

We can check for null , undefined and an empty string together by writing the following:

if (foo !== null || foo !== undefined || foo !== '') {
  const bar = foo;
}

We have to check null , undefined and empty string individually.

This is because empty string, null and undefined are different.

If we want to check other falsy values like 0 or NaN , then we can shorten it to:

const bar = foo || 'default';

Then when foo is any falsy value, then 'default' will be assigned to bar .

Array Literals

Instead of using the Array constructor:

const a = new Array();
a[0] = 'foo';
a[1] = 'bar';

We can write an array literal as follows:

const a = ['foo', 'bar'];

They do the same thing, but the array literal notation is much shorter.

Associative Array

We shouldn’t use the Array constructor for creating associative arrays.

Rather, we should create an object with dynamic keys.

For instance, we can write:

const skills = {
  'markup language' : 'HTML5',
  'programming language' : 'JavaScript'
};

We have 2 keys which aren’t valid identifiers.

But we can still use them since JavaScript objects can take string property names.

Asynchronous Loops

If we want to loop through setTimeout calls, then we can use let as follows:

for (let i = 0; i < 10; i++) {
  setTimeout(() => {
    console.log(i);
  }, 1000);
}

let is block-scoped, so the current value of i would be passed in.

Create an Array Sequence

We can create an array with a sequence of numbers starting from 0 with the Array constructor, fill , and map .

For instance, we can write:

const arr = Array(50).fill().map((_, i) => i);

We used the Array constructor to create an array with empty slots.

Then we called fill to fill the empty array with undefined .

This way, we can use map to map the entries by passing in a callback and return the index i of each entry.

Then we get an array between 0 and 50.

Ordering Object Properties

We can use the Object.keys method to return properties in an array.

Arrays are sortable so we can use that.

For instance, we can write:

Object.keys(obj)

and get the keys.

Also, we can use the Map constructor to create a map, which is traversed in insertion order.

For instance, we can write:

const map = new Map();
map.set('foo', 1);
map.set('@', 2);
map.set('bar', 3);
for (const [key, value] of map) {
  console.log(key, value);
}

Now we have Map instance that we can loop through keys in the same order that they’re inserted.

Avoiding Using Arguments

Don’t use the arguments object to get all the arguments.

Instead, we use the rest operator to get function arguments as an array.

For instance, we can write:

const foo = (...args) => {
  `for(const a of args) {
    //...
  }
}`

The ... is the rest operator which collects all the arguments in a function call and returns it as an array.

We can then call it by writing:

foo(1, 2, 3);

and args would be [1, 2, 3] .

Conclusion

We can use the rest operator to get the arguments from a function call.

The assignment operators are great. We can use the ++ and -- operators to increment and decrement our variables.

Also, we should use array literals as much as we can.

Categories
JavaScript Tips

Useful JavaScript Tips — Arrays and JSON

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.

Calculating the Average and Median

We can get the average by calculating the sum of the array and dividing that by the length of the array.

For instance, we can write:

const values = [2, 10, 28];
const sum = values.reduce((total, current) => current + total, 0);
const avg = sum / values.length;

We have the values array, which we get the sum of by using reduce .

Then we divide the returned sum by the length of values .

To get the median, we can sort the array, then get the average of the low and high middle value from the sorted array.

For instance, we can write:

const values = [2, 10, 28];
values.sort((a, b) => a - b);
const lowMiddle = Math.floor((values.length - 1) / 2);
const highMiddle = Math.ceil((values.length - 1) / 2);
const median = (values[lowMiddle] + values[highMiddle]) / 2;

We call sort to sort the array in ascending order by using the (a, b) => a — b callback.

Then we get the index of the low middle value by getting the floor of value ‘s length minus 1 divided by 2.

Likewise, we get the index of the high middle value by getting the ceiling of that.

Then we get the average of both values entries to get the median .

JSON.Stringify

We can turn objects into a string with JSON.stringify .

For instance, we can write:

const obj = {
  foo: `1`,
  bar: 2
};

const selectedProperties = ['foo'];

const str = JSON.stringify(obj, selectedProperties);

We have the obj object which we called stringify on with obj and select the properties with the second argument.

Then we get:

"{"foo":1}"

as the value of str .

We can also pass in a function:

const obj = {
  foo: 1,
  bar: 2
};

const selectedProperties = (key, val) => {
  if (!key || key === 'foo') {
    return val;
  }

  return;
}

const str = JSON.stringify(obj, selectedProperties);

We have a function that checks when to return val according to the given property.

Object.defineProperties

We can use Object.defineProperty to define a property to get more control over it.

For instance, we can write:

Object.defineProperty(obj, 'prop', {
  value: '123',
  enumerable: false,
  writable: false,
  configurable: false
});

We defined the prop property in obj value '123' , and all other properties set to false .

enumerable means whether we can see it from Object.keys or the for-in loop.

writable means whether we can change the value of it.

configurable means whether we can change the property descriptors.

Flattening Multidimensional Arrays

We can use the flat method to flatten multidimensional arrays.

For instance, we can write:

const arr = [[1, 2],[3, 4, 5]];
const flattened = arr.flat();

Then we get [1, 2, 3, 4, 5] for flattened .

We can also use concat to concatenate arrays.

For instance, we can write:

`const flattened` = [].concat.apply([], `arr`);

Also, we can use reduce to do the same thing:

const flattened = arr.reduce((flattened, curr) => flattened.concat(curr));

The spread operator can also do the same thing:

const arr = [[1, 2],[3, 4, 5]];
const flattened = arr.reduce((flattened, curr) => [...flattened, ...curr]);

That returns the arrays merged together.

We can also use the concat method with the spread operator:

const arr = [[1, 2],[3, 4, 5]];
const flattened = [].concat(...arr);

We spread the arr entries into arguments of the concat method.

Then concat appends the entries from the arrays.

Deduplicating an Array

We can remove duplicates from an array in several ways.

We can use the filter method to only return an array with the first instances of each entry by writing:

const deduped = [1, 1, 'b', 'b'].filter((el, i, arr) => arr.indexOf(el) === i);

We use the indexOf method, which returns the index of the first instance of entry to check whether it’s the first instance.

Also, we can convert it to a set to remove the duplicates and put spread it back into an array:

const deduped = Array.from(new Set([1, 1, 'b', 'b']));

or:

const deduped = [...new Set([1, 1, 'b', 'b'])];

Converting an array to a set removes the duplicates. Then we use Array.from or the spread operator to turn it back to a set.

Conclusion

We can use built-in methods and operations to calculate averages and medians.

Also, we can use them to remove duplicates.

We can also use them to flatten arrays.

JSON.stringify can take arguments to select which properties to stringify.

Categories
JavaScript Tips

JavaScript Tips — Good Constructs to Use

JavaScript is a very flexible language. There’s a lot of things in JavaScript that we probably shouldn’t write. Old constructs that aren’t good coexist with new constructures that are better.

In this article, we’ll look at some good parts of JavaScript that we should use regularly.

Don’t Use var, Use let or const

var is an outdated keyword for declaring variables. Instead, we should use let and const . let and const are both block-scoped, so that we can use them without worrying about clashing scopes as long as they’re in a block.

For instance, we can write the following:

let x = 1;
const y = 2;

instead of:

var x = 1;
var y = 2;

const also have the advantage that we can’t reassign a new value to it. However, it doesn’t make an object immutable.

Use === or Object.is Instead of ==

== saves one character of typing, but the rules for comparing with == is complex and hard to remember. It also produces lots of unexpected results. Therefore, we shouldn’t use == .

For instance, the following both return true :

[10]  == 10
'10' == 10

We probably don’t want that. Therefore, we should write the following instead:

[10] === 10
'10' === 10

Then they both return false since the data type and value of both operands have to match in order for the === to consider them the same. However, NaN === NaN returns false .

To check for NaN , we should use the isNaN function, which tries to convert its argument to a number and check against that. Therefore, isNaN(‘NaN’) and isNaN(NaN) both return true .

There’s also the Number.isNaN function, which doesn’t do any conversion when checking. Therefore, Number.isNaN(‘NaN’) returns false and Number.isNaN(NaN) returns true .

There’s also the Object.is method, which does the same thing as === ecept that NaN is the same as itself.

We can use that as follows:

Object.is('foo', 'bar')

The arguments are the 2 things that we want to compare.

undefined, null, 0, false, NaN, ‘’ (empty string) are all Falsy.

We have to remember these since they all return false when we try to convert them to boolean with !! or Boolean .

Use Semicolons for Line Termination

JavaScript is forgiving in that it doesn’t need semicolons for terminating lines. It’ll just insert the semicolons after line breaks or wherever it thinks it can end the line.

However, this will produce unexpected results. For instance:

const foo = () => {
  return
  {
    first: 'john'
  };
}

will return undefined because the semicolon is added after return , so the code below it is never run.

Therefore, we should insert semicolons as needed to clarify where a line ends.

Use Class Syntax for Object Constructors

In JavaScript, classes are the same as object constructore functions. However, the syntax is stricter so that it’s harder to make mistakes, especially when we need to do inheritance. For instance, we can write the following class:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
}

which is the same as:

function Person(firstName, lastName){
  this.firstName =  firstName;
  this.lastName = lastName;
}

It’s just that the class syntax is more conventional syntax, especially for people who worked with other object-oriented languages.

It makes even more sense if we have methods. For instance, with the class syntax, we write:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  fullName() {
    return `${this.firstName } ${this.lastName }`;
  }
}

The Person class above has the fullName method. On the other hand, with the old constructor function syntax, we write:

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

Person.prototype.fullName = function() {
  return `${this.firstName } ${this.lastName }`;
}

This just doesn’t make as much sense for many developers, especially for non-JavaScript developers.

The class syntax makes things much clearer. The class syntax makes even more sense with inheritance. With the old syntax, we write:

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

Person.prototype.fullName = function() {
  return `${this.firstName } ${this.lastName }`;
}

function Student(studentId) {
  Person.call(this, studentId);
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Person;

There’re no errors if we missed anything when we write the code above.

However, with the class syntax, we write:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  fullName() {
    return `${this.firstName } ${this.lastName }`;
  }
}

class Student extends Person {
  constructor(firstName, lastName, studentId) {
    super(firstName, lastName);
    this.studentId = studentId;
  }
}

We’ll also get errors if we didn’t follow the syntax like forgetting to call super when we have extends .

Conclusion

There’re a few important things we should use to write JavaScript code, including === instead of == , class syntax instead of constructor functions and prototype, use let and const instead of var to declare variables and constants, and remember falsy values