Categories
JavaScript Best Practices

JavaScript Best Practices — Variable Names to Avoid

JavaScript is a very forgiving language. It’s easy to write code that runs but has issues in it.

In this article, we’ll look at the kind of names we want to avoid for JavaScript variables.

Avoid Misleading Names or Abbreviations

Is a name is misleading, then we should correct them.

So a variable shouldn’t have double meanings. The variable age should hold the age of something for example.

Avoid Names with Similar Meanings

If names have a similar meaning, then we should avoid them. Something like employeeCode and employeeNum can easily confuse us.

If we have to fix problems, then we’ll run into issues with the confusing that these names bring.

Avoid Variables with Different Meanings but Similar Names

Variable names with different meanings but look similar are also no good.

Something like employeeRecs and employeeReps aren’t good.

The difference in their spelling is only by 1 letter, which can easily be missed.

Avoid Names that Sound Similar

Name that sound similar may also confuse us. Therefore, we should avoid them.

For instance, wrap and rap sound the same, so we can easily confuse the 2 names.

Avoid Numerals in Names

Since numbers are already used for array indexes, we shouldn’t use them for variables names as a suffix.

If we have foo1 and foo2 , then either they aren’t differentiated enough in their name or they should be in the same array.

Avoid Misspelled Words in Names

Misspelled words can easily throw people off, so we should avoid them to avoid any problems with them in the future.

If we have variable names that are misspelled, we should correct them before we go further.

Don’t Differentiate Variable Names Solely by Capitalization

Only differentiating names by capitalization doesn’t differentiate them much.

It’s hard for us to look at names that only differ by this little.

Avoid Multiple Natural Languages

If everyone uses English in the team, then all the names should be in English.

Otherwise, having names in different languages that not everyone may understand will bring problems if they have to read the code.

Make sure everyone knows the language before we name things.

Avoid the Names of Standard Constructors, Variables, and Functions

We should avoid any keywords that are used by the JavaScript language or its standard library.

For instance, we shouldn’t name things with words like, undefined , Array , and things like that.

Don’t Use Names that are Totally Unrelated to What the Variables Represent

If a variable is named for something, then we should make sure that it holds the value that’s given by the name.

So numApples should hold the number of apples for example.

Avoid Names Containing Hard-to-Read Characters

If they’re hard to read characters, then we should avoid them so that everyone can read them easier.

Characters like l and I shouldn’t be used together for example as they both look like a vertical line.

Conclusion

When naming variables, we should make them as easy to understand as possible.

This means that misspellings should be fixed. Names that have a similar meaning, sound, or appearance should also be changed.

Also, we’ve to make sure that everyone knows the language that the variable name is written so that everyone can understand them.

Categories
JavaScript Best Practices

JavaScript Best Practices for Writing More Robust Code — Functions

JavaScript is an easy to learn programming language. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust JavaScript code.

In this article, we’ll look at the best ways to write functions that are less likely to cause errors.

Use Arrow Functions as Much as Possible

JavaScript arrow functions are great. They let us write functions in a shorter and cleaner way.

Also, we don’t have to worry about the value of this inside a function. The value of this is always a pain to think about since it takes on a different value in different locations.

Also, we don’t have to worry about the value of the arguments object since it doesn’t bind to it.

Therefore, we should use it as much as possible. For instance, we can write something like:

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

In the code above, x => x * 2 is our arrow function. As we can see, it’s short, and since it’s one line, we don’t have to write return explicitly to return x * 2 . One line functions are much cleaner.

We don’t have to write out the function keyword all the time to declare a function.

Also, we also can’t call bind , call , or apply with it, so that we don’t have to worry about those methods either. This is another reason that we should use arrow functions as much as possible since there are fewer risks for errors from calling these methods.

They also can’t be used as constructor functions so we can’t use the new keyword with them. This is good because don’t want to use constructor functions anymore with the new class syntax.

Another good thing is that they don’t have a prototype property since they can’t be used as constructor functions. That’s another place that we can’t commit errors in the code.

Also, there’re no function declarations with arrow functions, so they can’t be hoisted. This means that they can only be referenced after they’re defined. This removes a lot of confusion with where we can call or reference an arrow function.

They can be used as top-level functions, as methods of objects, or be nested anywhere.

For instance, we can write:

const obj = {
  foo: () => {
    console.log('foo');
  }
}

So we can call the obj.foo method to log 'foo' .

We can also write:

const bar = () => {
  const foo = () => {
    console.log('foo');
  }
}

to nest foo inside bar .

Therefore, they’re good to use in places other than for constructor functions. We don’t really want to use constructor functions anyways since there’s the class syntax which actively checks for errors in our code instead of letting errors slide with constructor functions.

This is even more critical when we inherit from another constructor function.

Using the Rest Operator for Getting Long List of Arguments

The rest operator should always be used instead of the arguments object if we have a long list of arguments passed into our function.

It’s denoted by ... in the function signature and it returns the extra arguments that aren’t set as the value of the named parameters as an array.

They work with arrow functions and traditional functions. For instance, we can use the rest operator as follows:

function f(a, b, ...args) {
  console.log(args);
}

When we call f(1, 2, 3, 4, 5); then args is [3, 4, 5] since 1 is set to a and 2 is set to b .

We can also use them with arrow functions:

const f = (a, b, ...args) => {
  console.log(args);
}

Then we get the same result as before.

This way, we don’t have to use the arguments object to get the arguments, or use call or apply to call a function with extra arguments.

Like any array, we can use the destructuring syntax with it. For instance, we can write:

const f = (a, b, ...[d, e]) => {
  console.log(d, e);
}

Then when we call it as follows:

f(1, 2, 3, 4, 5);

We get that d is 3, e is 4. Note that we don’t have to destructure all the arguments that are passed in.

This is much better than the arguments object since it’s an array rather than an array-like object and we can use destructuring syntax with it.

Conclusion

Arrow functions should be used in our JavaScript code except when we need to create constructors or reference this in an object method.

The rest operator is the best way to get the arguments of a function that isn’t assigned to named parameters.

Categories
JavaScript Best Practices

JavaScript Best Practices for Writing More Robust Code — Checking for Feature Availability

JavaScript is an easy to learn programming language. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust JavaScript code.

In this article, we’ll look at various ways to check if a library is available in the browser you target before using it.

Modernizr

The Modernizr library lets us detect if a feature is available before using it. We can add it to our app with a script tag as follows:

<script
      type="text/javascript"
     src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"
    ></script>

Then we can add code like the following to test if a library is available as follows:

window.Modernizr.addTest("hasJquery", "jQuery" in window);

In the code above, we check if jQuery is available by calling Modernizr’s addTest method to check if the 'jQuery' property is in the global window object to see if jQuery has been added.

Then we can check with the Modernizr.on method as follows:

window.Modernizr.on("hasjquery", result => {
  console.log(result);
});

result will be true if jQuery exists and false otherwise. Note that most methods are only available in a custom build, which can be created by going to https://modernizr.com/download?setclasses.

Then every time the page loads, the feature check will be run to check if the hasjquery feature returns true .

We can also add checks for multiple features as follows:

const detects = {
  'hasjquery': 'jQuery' in window,
  foo() {
    return true
  }
}
Modernizr.addTest(detects);

In the code above, we have the hasjquery check and the foo check. Note that the check can be a function in addition to a boolean.

If it’s a function, then it should return a boolean.

Modernizr also has the atRule method to check is a CSS @ rule is available in the current browser.

For instance, we can use it as follows:

const keyframes = Modernizr.atRule('@keyframes');

If the @keyframes is available in the current browser, the keyframes would have the value '@keyframes' . Otherwise, it would have the string value 'false' .

The Modernizr _domPrefixes method gets all the CSS prefixes that are supported by a browser.

For instance, the Modernizr._domPrefixes property may return something like the following:

["moz", "o", "ms", "webkit"]

This means that we can set properties with these prefixes like for flexbox with -moz-flex , -ms-flexbox , and -webkit-box for setting the flexbox property within a browser.

ms is for Internet Explorer, moz is for Firefox, o is for Opera, and webkit for Webkit based browsers like Safari.

We can use Modernizr’s hasEvent method to check if an event is available in a browser. It takes 2 arguments. The first is the string for an event name, and the second is the object which the event listener can be attached to.

The 2nd argument is optional.

For instance, we can write the following code to use the hasEvent method:

console.log(Modernizr.hasEvent('devicelight', window))
console.log(Modernizr.hasEvent('blur', window))

In the code above, we check if the devicelight event handler can be attached to window and listened to in the browser.

Also, we checked if the blur event can be listened to in the browser on the window object.

They both should return boolean. For desktop browsers, the first one should return false , but the second one should return true since it’s available for all browsers.

The Modernizr mq method lets us programmatically check if the current browser window state matches the media query.

It takes one argument, which is the string with the CSS for the media query that we want to check.

For instance, we can do that as follows:

const query = Modernizr.mq('(min-width: 300px)');

In the code above, we check if the screen is 300px or wider. If it is, then it returns true . Otherwise, it returns false .

Modernizr’s prefixed method takes a string CSS value in the DOM style in camelCase and returns the version of that property that the browser actually supports.

This helps us determine what kind of prefix we need in our CSS to properly style our app in the current browser.

For instance, we can use it as follows:

const boxSizing = Modernizr.prefixed('boxSizing');

In the code above, we check if any prefix is needed for the box-sizing CSS property. If we do, then it’ll return the prefix with the property for the string. Otherwise, it’ll just return the string we passed in.

Conclusion

We can use Modernizr to detect various features that are available in the current browser. They include screen sizes, objects that are loaded in the browser, and CSS prefixes.

At rules can also be checked if they’re available.

Categories
JavaScript Best Practices

JavaScript Best Practices for Writing More Robust Code — Functions

JavaScript is an easy to learn programming language. It’s easy to write programs that runs and does something. However, it’s hard to account for all the uses cases and write robust JavaScript code.

In this article, we’ll look at how to write JavaScript functions that are more robust and maintainable.

Multiple Parameters is Better Than One Object Parameter

If there aren’t too many parameters in our function, we should have multiple parameters instead of one single object parameter.

It’s much clearer to have multiple parameters instead of one single object parameter.

For instance, the following:

const fullName = (person) => `${this.firstName} ${this.lastName}`

is harder to read than:

const fullName = (firstName, lastName) => `${firstName} ${lastName}`

because we don’t know what the person parameter in the function signature contains until we look at the code.

In the second example, we know that firstName and lastName are the parameters right away.

If the functions are more complex than what we have above, then it’s even harder to trace what our function has.

A good rule of thumb is that for functions that have 5 or fewer parameters, then they should be listed separately in the function signature.

Otherwise, we have no choice but to combine some or all of them into one object parameter to keep the number of parameters 5 or less.

This is because once a function has more than 5 parameters, now the function signature becomes harder to read.

Also, if a function have lots of arguments, then it’s harder to remember the order to pass in the arguments so we can call our function correctly.

Skipping parameters is also a problem if our function has lots of parameters since we have to check where to pass in undefined to so that we can skip passing in a value for that parameter.

If we pass in an object, then we can just set properties to undefined and be done with calling the function instead of thinking where we need to pass in undefined if our function has lots of parameters.

Destructuring and Functions

Destructuring is a nice feature of ES2015 that lets us decompose array entries and object entries into their own variables.

In terms of functions, we can use it to destructure object or array parameters to selectively reference object properties or array entries that we need.

For instance, if we have the following function:

const fullName = (person) => `${this.firstName} ${this.lastName}`

Then we can rewrite it with the destructuring syntax by writing:

const fullName = ({
  firstName,
  lastName
}) => `${firstName} ${lastName}`

And then we can call it as follows:

fullName({
  firstName: 'joe',
  lastName: 'smith'
})

In the code above, we passed in:

{
  firstName: 'joe',
  lastName: 'smith'
}

to fullName , and then because of the destructuring syntax, the JavaScript interpreter will automatically get the value with the given property name and interpolate the string with that variable value.

So firstName in the destructured object is the same one that’s referenced in the string, which is also the same as the firstName property that’s passed into the fullName function.

Therefore, the console log output should be 'joe smith' .

It also works with nested objects. For instance, we can write:

const fullName = ({
  name: {
    firstName,
    lastName
  }
}) => `${firstName} ${lastName}`

Then if we call fullName as follows:

fullName({
  name: {
    firstName: 'joe',
    lastName: 'smith'
  }
})

We’ll get the same result as before. It’s important to note that we don’t have to include every property in the object in the destructuring syntax.

We can also write:

const name = ({
  name: {
    firstName,
  }
}) => `${firstName}`

and call it like:

name({
  name: {
    firstName: 'joe',
    lastName: 'smith'
  }
})

Destructuring also works for arrays. In terms of functions, we can use it to destructure array parameters into variables. For instance, we can write:

const fullName = ([firstName, lastName]) => `${firstName} ${lastName}`

Now the fullName function takes an array as the argument instead of an object.

Then we can call it as follows:

fullName(['joe', 'smith'])

And we’ll get 'joe smith' as the returned value as we did before.

Conclusion

If our function takes 5 or fewer parameters, then they should be separate for easy readability and reduce the cognitive load of whoever’s using the function.

Also, the destructuring syntax is great for situations when we need to take an object or array entries as parameters in our function and we want to selectively reference the entries from those arguments.

Categories
JavaScript Best Practices

JavaScript Best Practices for Writing More Robust Code — Code Organization

JavaScript is an easy to learn programming language. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust JavaScript code.

In this article, we’ll look at how to organize our JavaScript code that it’s clean and harder to break.

Keep Functions Simple

Functions are all pieces of code that can be invoked repeatedly with different arguments.

They should be as simple as possible so that they’re easy to test and maintain. Keeping them simple also makes it easier to understand so that everyone can use it or update it if required.

For instance, an example of a simple function is something like the following:

const add = (a, b) => a + b;

The function above is simple. It only does one thing, which is adding 2 numbers together. It’s simple since it only does one operation and returns it.

Also, testing is easy since we only have to test one operation. It’s also easy for us to understand the code.

Divide Code Into Modules

Since ES2015, JavaScript modules is a standard feature of JavaScript. They allow us to divide code into small chunks and expose what’s required. They load asynchronously, which means no tying up the main thread, unlike scripts that are loaded with script tags, which loads synchronously.

Also, the code in functions is hidden from the outside unless we explicitly export the members of a module. This is something that old-style scripts can’t do.

In old-styles scripts, all top-level code is exposed to the outside, which isn’t ideal and it leads to the use of hacky solutions like immediately invoked function expressions (IIFEs) to be used to hide code that we don’t want to expose to the outside.

Also, modules have strict mode turned on by default, so that it’s very hard for us to make mistakes that we would otherwise make if it’s off, like assigning a read-only global variable or value to a different value or declaring global variables accidentally.

Now that we have modules, we don’t have to worry about how to organize our code and hide code from the outside. All we have to do is to export the code that we want to the outside world with the export keyword.

If we want to use code from another module, then we can import it with the import keyword.

All imports are read-only versions of the member that’s exported from the originating module. Also, static checks are done to stop us from importing things that don’t exist, which is even better.

Old-style scripts don’t provide any static checks for anything from the outside, so it’s easy for us to make mistakes and make typos in our code, resulting in errors.

This is much better than using script tags since it lets us isolate our code much more easily and provides static checks so that it’s hard for us to make mistakes, creating more robust code in the process.

The common use cases for modules is simple. All we have to do is create JavaScript modules files and then use the export and import keywords as follows:

module.js

const foo = 1;
export const bar = 2;

index.js

import { bar } from "./module";

console.log(bar);

In the code above, we create a module by creating module.js and then adding an export expression to export our bar constant.

Since we don’t have export in front of the first line, we didn’t export foo , so it won’t be available to the outside.

Then we imported bar in index.js and used it in the console log. If we try to import foo , we’ll get an error because the static analysis will indicate that foo wasn’t exported, so we can’t import it.

We can also do the import on the fly with the import function. It returns a promise so it’s also asynchronous.

It allows us to import members from another module dynamically. For instance, in index.js , we can write the following:

(async () => {
  const { bar } = await import("./module");
  console.log(bar);
})();

In the code above, we have the import function call, which imports module.js as we did before, but we used await get resolved value, which is an object including bar .

Then we referenced it in console.log as we did before.

Conclusion

Keeping functions simple is a good idea if we want to write robust code because it’s easier to read, understand, and test.

JavaScript modules should be used as much as possible to keep code private while exposing others. Only exported code is exposed to the outside.

Also, strict mode is enabled by default in modules. Static analysis is also available for modules to prevent us from making mistakes when referencing code.