Categories
JavaScript Best Practices

JavaScript Best Practices— JSONP and Deployment

JavaScript lets us do a lot of things. It’s sometimes too forgiving in its syntax.

The organize our code, we should use some basic design patterns. In the article, we’ll look at using JSONP and deployment strategies.

JSONP

JSONP is JSON with padding. We can use this instead of JSON to bypass the same-domain browser policy.

We should use this carefully since we’re loading data from 3rd party sites.

With JSONP, we have JSON wrapped in a function call.

The function name is provided with a JSONP request.

For instance, a JSONP request URL may look like:

http://example.org/getdata?callback=myHandler

where the myHandler is the name of the function on our app that’ll be called once the request is made.

The URL is loaded into the script element and then it’ll call myHandler once it’s done loading.

Deploying JavaScript

There are some things that we have consider when we deploy JavaScript code.

We’ve to be sure that we combine scripts so that they’re compacted.

Whitespaces, long names, etc. are all removed and replaced with shorter spaces and names.

Combining scripts is one more step before we deploy.

And we may lose some caching benefits. It’s not good to invalidate the cache for a small change in the bundle.

Also, we got to come with some versioning pattern for the bundle so we don’t lose track of them.

Minifying and Compressing

Minifying and compression code is important. The smaller the bundle, the less code that users have to download.

This means users can use our app faster.

That’s definitely good for users.

Minification and compression can give up to a 50% reduction in size compared to the original code.

We can compress our bundles with gzip compression. Our web server can be configured to serve gzipped bundles instead of plain text.

This will also give us a size reduction.

Compression will give us 70% smaller files on average.

With minification and compression together, users only download files that are 15% of the size of the original code.

Expires Header

Our cache should expire after a while. This way, users don’t have to refresh manually to see the latest changes.

We can change the expiry header to a value that we’re comfortable with.

If we set the cache long, then we’ve to rename the files every time we deploy so that the cache will be invalidated automatically.

Using a CDN

CDN stands for a content delivery network. These are paid services that let us distribute copies of our files in different data centers around the world.

This way, because of the proximity in location, the files will be served faster to users.

We can link to library files on CDNs and use them.

Loading Strategies

If we load files in our app, then we can load them in a few ways.

We can have inline scripts for simple scripts:

<script>  
  console.log("hello");  
</script>

Or we can load them from external sources:

<script src="external.js"></script>

There are some attributes that we can use to load scripts in different ways.

We can use the defer directive to make our script download in a way that doesn’t block our browser from running other code.

The Place of the Script Element

Script elements should be loaded as a bundle so that we don’t have lots of files that we have to load in order.

The more script tags we have, the more likely that we’ll screw up the order.

Therefore, we should make sure that we reduce the number of script tags by bundling.

HTTP Chunking

We can also chunk our pages so that they load in chunks.

We can move all the JavaScript to the head tag, while loading the rest of the body can load later.

Dynamic Script Elements

We can use the defer or async attributes in our script tags.

defer loads them asynchronously but in order.

async loads them asynchronously but may not be in order.

We can also create script tags dynamically by writing:

const script = document.createElement("script");  
script.src = "foo.js"; document.documentElement.firstChild.appendChild(script);

This will create a script tag that we can attach to the head tag or anywhere else.

Conclusion

We can reduce the size of our script bundles by minifying and compressing them.

This way, our code can be less than half of the size of the original code.

We can also use the defer and async directives to load script files.

And we can create scripts on the fly to defer loading.

JSONP lets us load JSON without the same domain restriction.

Categories
JavaScript Best Practices

JavaScript Best Practices —Comments

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

In this article, we’ll look at the best practices for commenting code.

Keys to Effective Comments

Wrong comments should be removed. They’re misleading and may lead to developers making wrong decisions.

If they’re just a repeat of the code, then they should definitely not be written.

If there’re any tricky parts of the code that needs explanation, then we may need comments to explain them.

Markers shouldn’t be left in the code. If we use markers to mark defective code that should be fixed, then we should just fix the code.

Summaries of code are better than just repeating code since it lets us look for information more easily with the code.

If a piece of code describes the code’s intent, then it might be useful since it probably isn’t clear from just reading the code.

Information That Cannot Possibly Be Expressed by the Code Itself

Information like copyright can’t be written in the code itself. Therefore, we may need comments to explain them.

Comments that are used for generating documentation are also helpful.

Commenting Efficiently

Commenting shouldn’t be a time-consuming task. Too many or too few comments are both bad.

We got to achieve a middle ground.

If we’re using a tedious commenting style, then we should simplify it.

Words that describe what the program is doing also may not be easy to come by.

Use Styles that don’t Discourage Modification

We should make our comments easy to maintain just like our code.

For instance, if we’re making an elaborate table with comments, then we should consider simplifying that so that others won’t have to update it.

If we use asterisks to delimit comments, then we should reduce those.

Use the Pseudocode Programming Process to Reduce Commenting Time

We can outline code by writing them with pseudocode first before converting them to English.

Integrate Comments into Our Development Style

Leaving comments until the end isn’t a very good habit.

We’ll probably forget to do them and it becomes its own chore.

By the time we finished our code, we probably already forgot about the assumptions and decisions that we want to comment on.

Therefore, we should just comment as we code to make our lives easier and before we forget what to write.

Performance is not a Good Reason to Avoid Commenting

Comments increase code file size, but compilers and interpreters ignore them, so the performance hits are negligible if there’s any.

Optimum Number of Comments

We should just comment as much as we need to and forget about an optimum number of comments.

Avoid Self-Indulgent Comments

We shouldn’t write comments just to express our feels in the code.

No one really cares and they take up valuable space.

Endline Comments and Their Problems

Endline comments don’t align to the right side of the code since it’s hard to do so.

Also, we’ve to move our cursor all the way to the right to add or edit the comment.

Therefore, they’re hard to maintain and most people won’t want to touch them.

If they’re on the right, then people writing the comment have to make them short to keep the line lengths short.

Therefore, there isn’t much benefit to keeping them on the right and lots of problems.

Avoid Endline Comments on Single Lines

We shouldn’t comment on every line of our code. And we shouldn’t have them on the right.

There’s not that much to write about for one line of code.

Avoid Endline Comments for Multiple Lines of Code

Our comments probably won’t fit at the end of the line.

It’s just a bad place for comments.

Use Endline Comments to Annotate Data Declarations

Data declarations can have comments placed on the right of them.

These lines are usually short, so there’s space for comments to the right.

Avoid Using Endline Comments for Maintenance Notes

Since we’re supposed to be using version control systems for storing code, maintenance notes belong to the commit comments.

Therefore, keep them out of the code files.

Use Endline Comments to Mark Ends of Blocks

If we have long blocks, then we should mark the end of blocks with end line comments.

This way, we know where’s the end of each block is.

Conclusion

Comments can be tricky. We shouldn’t use them to repeat our code or commit comments.

Also, comments at the end of a line should be used sparingly or short lines.

Comments should also be easy to maintain so that we’ll be willing to update them.

Categories
JavaScript Best Practices

JavaScript Best Practices — Code Organization

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 how we should organize our JavaScript code.

Statements That Must Be in a Specific Order

We should organize code that must be run in a specific order so that the dependencies are obvious.

For instance, we can write the code that needs to be run first by writing something like:

const subtotal = calcSubtotal();
const taxes = calcTaxes(subtotal);
const total = subtotal + taxes;

With the code above, we know that we need to calculate the subtotal before we can use that to calculate the taxes.

Then we need both to calculate the total.

Also, the parameter for calcTaxes is subtotal so that we know that we know subtotal is a dependency for calcTaxes .

Document Unclear Dependencies with Comments

If dependencies aren’t clear, then we need to clarify them with comments.

For instance, if we didn’t have the parameter for calcTaxes , then we may have to explain that in the comments.

We may write:

/*
 1. calculate subtotal
  2. calculate taxes
  3. calculate total
 */
const subtotal = calcSubtotal();
const taxes = calcTaxes();
const total = subtotal + taxes;

Check for Dependencies with Assertions or Error-Handling Code

If our sequence of code have dependencies, then we want to check for them before we move on to the next step.

For instance, we may want to write assertions or error handling code to check if the required values are available before proceeding.

We may write something like:

const length = calcLength();
const width = calcWidth();
if (length >= 0 && width >= 0) {
  let area = length * width;
}

We check that length and width are 0 or bigger before we calculate the area by multiplying length and width .

If we’re writing a Node app, we may also use the assert module to check the conditions that we want to check instead.

Making Code Read from Top to Bottom

If we have code where the order does matter, then we can make the code read from the top and bottom.

This way, we can read the code easily without jumping up and down the page.

For instance, we may write something like:

travelData.calcQuarterlyRevenue();
salesData.calcQuarterlyRevenue();
marketingData.calcQuarterlyRevenue();

travelData.calcAnnualRevenue();
salesData.calcAnnualRevenue();
marketingData.calcAnnualRevenue();

This way, we can read them in sequence by grouping the quarterly calculations together and the annual ones together.

Grouping Related Statements

Grouping related statements are also important. Putting related statements together lets us read them together.

Reading unrelated code that overlaps with each other is hard because we’ve to jump around to read it.

Conclusion

We should organize our code in a way so that we don’t have to jump around the page to read our code.

Also, we should group related statements together so that we can read related statements together.

Assertions and error handling code should also be added so that we know what’s required to run the code that comes after the assertions.

Categories
JavaScript Best Practices

JavaScript Best Practices — Function Layout and Documentation

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

In this article, we’ll look at the best practices for laying out JavaScript function code and documentation.

Use Blank Lines to Separate Parts of a Function

Any code that’s inside the function’s body should be grouped into related paragraphs so that we can see them easily.

Use Standard Indentation for Function Arguments

Function argument should be indented if they overflow the first line.

For instance, we may write:

const readFile = (
  fileName,
  employeeCount
) => {
  //...
}

and call it as follows:

readFile = (
  fileName,
  employeeCount
)

This is easier to read than having everything in the same line.

Laying Out Classes

We should put the constructor first in the class. Then we add methods.

For instance, we write:

class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    //...
  }
}

We have the instance method greet below the constructor.

If we have More than One Class in a File, Identify Each Class Clearly

We should be easily identify classes that are in the same file.

For instance, we write:

class Animal {
  //...
}

class Person {
  //...
}

to write 2 classes. We make them clear that they’re classes with the class keyword and PascalCase names for each class.

Put One Class in One File

Putting one class per file is a good idea.

We may want to do that to make finding them easier.

Give File a Name Related to the Class Name

If we have one class per file, then the class name should be related to the file name.

This way, we can find the class by their file name easily.

Separate Functions Within a File Clearly

Having blank lines between functions let us read them easily.

For instance, we can write the following:

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

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

This way, we can see our function code easily.

Sequence Functions Alphabetically

We can separate functions alphabetically so that we can look for them easily with our eyes.

So we can write:

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

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

Self Documenting Code

Having self-documenting code is important. We want our code to mostly explain themselves so that everyone else can understand it when they read them.

External Documentation

Even though the code is self-documenting, external documentation is still important.

They’re for high-level decisions mostly, between business requirements documents and the code itself.

Unit development Folders

Unit development folders is an informal document that has notes by developers that are written during development.

It includes justifications for decisions and top-level design standards, and related knowledge that aren’t covered in code.

Detailed-Design Document

This is a low-level design document that let us document class and function level design decisions.

It documents the cases that we considered and alternatives that were skipped.

Programming Style as Documentation

The internal documentation is done with a clear code.

Code-level documentation is done with a good programming style.

Even if a piece of code doesn’t have comments, we should still be able to understand it.

So the name should be descriptive, spacing should be good and consistent, and code groups should be small.

To Comment or Not to Comment

It’s easy to write comments poorly. And bad comments are more damaging than helpful.

Therefore, we shouldn’t write too many of them.

Keys to Effective Comments

Wrong comments should be removed. They’re misleading and may lead to developers making wrong decisions.

If they’re just a repeat of the code, then they should definitely not be written.

If there’re any tricky parts of the code that needs explanation, then we may need comments to explain them.

Markers shouldn’t be left in the code. If we use markers to mark defective code that should be fixed, then we should just fix the code.

Conclusion

We should aim to write self-documenting code.

To do that, we have good spacing and names.

Code groups should be short and clear so that they’re easy to read.

Blank lines and indentation are important for readability.

Categories
JavaScript Best Practices

JavaScript Best Practices — Arrays and Global Variables

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 how we should work with arrays and global variables in JavaScript.

Make Sure that All Array Indexes are Within the Bounds of the Array

We should make sure that we don’t access array indexes that are out of bounds.

Otherwise, we get undefined as the returned value.

Consider Using Objects Instead of Arrays

Arrays are meant to be accessed sequentially, so if we don’t need that, we may want to use an object instead.

This way, we won’t have to worry about indexes and just access things the way we want.

JavaScript also has maps for key-value pairs and sets for containers that don’t hold duplicate values.

Check the End Points of Arrays

We should check the endpoints of arrays to catch errors that may occur there.

Off by one error isn’t good, so we should be checking for those.

If an Array is Multidimensional, Make Sure its Subscripts are used in the Correct Order

arr[i][j] and arr[j][i] are completely different. So we should make sure that the index is in the right order.

Watch Out for Index Cross-Talk

If we have nested loops, it’s easy to confuse arr[j] with arr[i] , so we should make sure that our code don’t have typos like that or we’ll get unexpected results.

Inadvertent Changes to Global Data

It’s easy to mess up global data since they can be accessed anywhere, so we shouldn’t use them anywhere.

Instead, we can use local variables as much as possible.

Block-scoped variables are even better.

Code Reuse Hindered by Global Data

If we want to reuse code that has global data, then we got to make sure that the global data aren’t affected by the reuse.

This means that reusing code that references global data is hard.

This is another reason that we should have global data in our apps.

Reasons to Use Global Data

It’s rare that we have to have values that must be global, but they may exist.

Things like constants for the mode of our app may be a constant.

Global variables may also be used for simulating enum types if they don’t exist, which is the case in JavaScript.

If we have some values that are related and we need to access them everywhere, then we may want to make one or more global variables out of them.

Also, if we have data that are used everywhere, we may also want to define them as global data.

Use Global Data Only as a Last Resort

Global data should only be used as a last resort.

If something can’t be local at all, then they may have to be global.

However, that shouldn’t be the case in most cases with JavaScript modules.

Access Function

An access function allows us to access global variables in a controlled manner.

We may want to create functions for getter and setting global variables.

Also, we may want to have a locking mechanism for accessing global variables so that we won’t have issues with multiple pieces of code accessing the same global variable.

Reduce the Risks of Using Global Variables

If we ever declare global variables, we should make their name obvious.

For instance, all global variables may start with g .

We should also create a list of all global variables so that everyone knows that they’re global.

They also shouldn’t contain intermediate results.

And we definitely shouldn’t put everything in one big global object and pass them everywhere.

That’s just a recipe for disaster since they can be changed by anything in our program.

Conclusion

We should avoid global variables as much as we can. They just aren’t good for much and they may cause lots of unexpected results.

If we want to use global variables, then we’ve to make sure that they’re accessed in an orderly manner.

If we’re using arrays, then we should watch out for off-by-one errors.

Also, we don’t have to use an array if we don’t need to access the data sequentially. We can use other things like sets and maps.