Categories
JavaScript

Good Parts of JavaScript — Expressions, Literals, Objects, and Functions

JavaScript is one of the most popular programming languages in the world. It can do a lot and have some features that are ahead of many other languages.

In this article, we’ll look at some good parts of JavaScript, including expressions, literals, and functions.

Expressions

Expressions are basic building blocks of JavaScript. They’re different from statements in that they return a value.

The simplest expressions are literal values, a variable, or built-in values.

Invocation of constructors with the new keyword are also expressions.

An expression can be wrapped in parentheses, preceded by a prefix operator, or it can be followed by the following thing:

  • infix operator and another expression
  • ? ternary operator followed by another expression
  • invocation
  • refinement

The ternary operator takes 3 operands. The first is the condition before the question mark.

Then the expression that’s returned when the condition is truthy, followed by a colon. Then that’s followed by an expression if the condition is falsy.

Operators are evaluated in the following order:

  • . [] () (refinement and invocation)
  • delete new typeof + — ! (unary operators)
  • * / % (multiplication, division, and remainder)
  • + 0 (addition / concatenation and subtraction)
  • >= <= > < (inequality)
  • && (logical and)
  • || (logical or)
  • ?: (ternary)

The typeof operator can return 'number' , 'string' , 'boolean' , 'undefined' , 'function' , and 'object' .

If the operand is an array of null , then 'object' is retuned.

This is wrong.

If the operand of ! is truthy, then false is returned. Otherwise, true is returned.

The + can add or concatenate. If we want to add, then make sure both operands are numbers.

The / operator can return noninteger results even if both operands are integers.

The && operator returns the value of the first operand if the first operand is falsy.

Otherwise, it returns the value of the 2nd operand.

The || operator returns the value of the first operand if the first operand is truthy.

Otherwise, it produces the value of the 2nd operand.

Invocation causes the execution of the function value. The operator is a pair of parentheses that follow the function value.

Arguments can be contained in the parentheses.

For instance, the following:

const sum  = add(1, 2, 3);

The parentheses after the add is the invocation operator. and 1, 2, and 3 are the arguments.

The refinement operator is used to specify a property or element of an object or an array.

For instance, if we have:

const arr = [1, 2, 3];

Then we can use the refinement operator as follows:

const first = arr[0];

The square brackets form the refinement operator.

Likewise, we can access the property of an object with the refinement operator as follows:

const foo = obj['foo'];

We can get the foo property from obj .

It’s the only way to get a property of an object if the property name isn’t a valid identifier.

Literals

Object literals are great for specifying new objects.

We can specify properties as names or strings.

They’re treated as literal names and not variable names.

Therefore, the names of properties must be known at compile time.

But string property names can be added or removed at run time.

Array literals are great for specifying new arrays.

Functions

We can define functions with function literals.

It can have a name, which is optional. With it, we can call it recursively.

The body can include variable definitions and statements.

There’re 2 ways to define functions. We can define an arrow function or a traditional function with the function keyword.

To define an arrow function, we can write:

(a, b) => {
  // do something with a and b
}

To create a named arrow function, we can write:

const foo = (a, b) => {
  // do something with a and b
}

Then we can call it by writing foo(1, 2) .

To create traditional functions, we can use the function keyword.

For instance, we can write:

function foo(a, b){
  // do something with a and b
}

We can also create an anonymous function by writing:

function (a, b){
  // do something with a and b
}

Conclusion

Functions are useful for storing statements and variables which we can run multiple times.

Expressions are code that returns a value. It can have various operators to produce the values that we need.

Object literals are used for creating objects in a convenient way. It’s used for creating one-off objects.

Categories
JavaScript

Good Parts of JavaScript — Coding Best Practices

JavaScript is one of the most popular programming languages in the world. It can do a lot and have some features that are ahead of many other languages.

In this article, we’ll take the good parts of JavaScript code styling for formatting, and look at other good features of JavaScript.

Code Styling

We should avoid features that are occasionally hazardous but are useful.

If we do that, we can avoid a large class of errors.

If we communicate clearly with our code, then it’s less likely to break in the future.

Blocks

Consistent styles should be used so that we can understand them easily.

For instance, we should make indentations and put each statement on their own line.

We should always use blocks to surround any statements.

For instance, instead of writing:

if (a)
  b( );

We write:

if (a){
   b( );
}

If we have:

if (a)
  b( );
  c( );

Then it looks like:

if (a) {
  b( );
  c( );
}

But it means:

if (a) {
  b( );
}
c( );

Therefore, we should use curly braces to surround blocks even if we don’t have to.

JavaScript have block-scoped variables, so we should declare them before they’re first used.

Things That Look Like Mistakes

Other things that look like mistakes include using assignment in if statement:

if (a = b) { ... }

We probably want to write:

if (a === b) { ... }

Switch Statements

We should never forget to add a break to the end of each case in a switch statement.

Letting them fall through is just a bad idea.

Sometimes we may want to do that intentionally, but most of the time, we probably don’t.

So we should always write:

switch (val) {
  case 1: {
    //...
    break;
  }
  case 2: {
    //...
    break;
  }
  //..
}

Global Variables

Global variables should be avoided as much as possible.

We can use the existing ones that are built into the JavaScript standard library.

However, we shouldn’t define new ones or override the existing ones by replacing or adding new methods to them.

If we declare variables in scripts, we can declare them in blocks or closures.

Also, we can consider using modules to make variables private.

Beautiful Features

There’re some great features to simplify writing programs in JavaScript.

They include functions being first-class objects. They can be passed in as arguments to other functions and be assigned to variables.

Also, they can have their own properties.

This allows them to be used as callbacks.

Dynamic objects can be used to our benefit.

We can define one-off objects we object literals. Therefore we can use them as dictionaries.

Objects can inherit members from other objects directly.

Likewise, array literals are also very handy for defining arrays.

We can just define arrays without using any classes or constructors.

Having pi its own constant is also a great feature.

In JavaScript, a word can’t be used as a reserved word, a parameter, or a function name at the same time.

This makes our code easier to understand since they can’t have multiple meanings.

With let and const , we have block-scoped variables. This way, they’re always confined to the block.

All these features allow us to make our code simple, which is good.

Conclusion

There are many good parts of JavaScript.

Therefore, we should use them as much as possible.

They include object and array literals, block-scoped variables, indentation, and curly braces for blocks.

Using functions like any other object is another great feature that we should take advantage of.

Categories
JavaScript

Good Parts of JavaScript — Callbacks, Closure, and Modules

JavaScript is one of the most popular programming languages in the world. It can do a lot and have some features that are ahead of many other languages.

In this article, we’ll look at ways to define and use callbacks, closures, modules in JavaScript apps.

Callbacks

Functions make dealing with discontinuous events easier.

We can use them to run some code after a fixed amount of time for instance.

Callbacks are functions that are passed into another function and called either synchronously or asynchronously.

An example of a synchronous callback call is the callbacks that we pass into array methods.

For instance, we can write:

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

The function a => a ** 3 is called synchronously as soon as map is called.

Callbacks can also be asynchronous. Async callbacks aren’t run until the code some amount of time after the function is called.

An example of an asynchronous callback is a callback we pass into the setTimeout function.

For example, we can write:

setTimeout(() => {
  console.log('foo');
}, 100)

The code above calls the callback after 100ms.

Async callbacks are used in many places since JavaScript programs run in a single thread, so we run as much code asynchronously as possible to avoid blocking the program thread.

Module

Before JavaScript have modules official, we used to put private code inside closures to avoid exposing to the public.

For instance, we can write:

const module = (() => {
  let value = 0;
  return {
    getValue() {
      return value;
    }
  }
})()

In the code above, we created an IIFE which returns an object.

The object has the getValue method which returns the value of value , which is kept private.

We can’t access value , but we can call getValue() .

However, now that we have modules, we can use them instead.

For instance, we can define one as follows:

module.js

export const foo = 1;
const bar = 2;
export const getBar = () => bar;

index.js

import { getBar } from "./module";
console.log(getBar());

We export foo and getBar in module.js so that we can use them in index.js .

getBar can then be called in index.js .

We kept bar private but we that we can expose them if we want to.

Also, we can the whole one thing in a module as a default export.

For instance, we can write:

module.js

const bar = 2;

export default {
  getBar: () => bar
};

With default exports, we export one thing and we import it by writing:

import module from "./module";
console.log(module.getBar());

If we import default exports, we don’t put the curly braces.

Cascade

We can chain methods that return this in the method.

For instance, we can write:

const box = {
  setHeight(height) {
    this.height = height;
    return this;
  },
  setWidth(width) {
    this.width = width;
    return this;
  },
  setLength(length) {
    this.length = length;
    return this;
  },
}

Then when we call the methods as follows:

box.setHeight(100).setWidth(200).setLength(150);

We get:

{
  "height": 100,
  "width": 200,
  "length": 150
}

As we can see, if we return this , then we can set update this the way we wish to and return it.

Then we can chain the methods in an object.

This lets us produce interfaces that are expressive.

We can do a little bit in each method and chain all the little actions together.

Curry

Curry functions allow us to produce a new function by combining a function and an argument.

We can create a curry function to return a function that has some arguments applied and let us apply the remaining arguments by writing the following:

const curry = (fn, ...args) => {
  return (...moreArgs) => {
    return fn.apply(null, [...args, ...moreArgs]);
  };
}

In the code above, we have the curry function, which takes a function fn and some arguments args after it.

Inside it, we return a function that returns fn with all the arguments from both functions applied to it.

This way, we first apply the arguments in args , then we apply the arguments in moreArgs to fn .

Now if we call it as follows:

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

const curried = curry(add, 1);
const result = curried(2, 3);

We first get a function with 1 applied to add in curried .

Then we get the final sum by applying 2 and 3 to curried .

Therefore, result is 6.

Conclusion

Callbacks are frequently used in JavaScript. There can be synchronously or asynchronously called.

We can define modules with official modules or IIFEs that return an object.

Currying functions let us return a function that have arguments partially applied and can apply more arguments later.

Categories
JavaScript

Good Parts of JavaScript —String Methods

JavaScript is one of the most popular programming languages in the world. It can do a lot and have some features that are ahead of many other languages.

In this article, we’ll look at some useful string methods.

String

Various string methods are also very useful for manipulating strings.

string.indexOf(searchString, position)

The indexOf method lets us search for the first occurrence of a substring.

We can choose to start from a given position if we wish.

For instance, we can write:

console.log('foobar'.indexOf('bar', 4));

and get -1 because we started searching at index 4.

On the other hand, if we writeL

console.log('foobar'.indexOf('bar'));

We get 3 since bar starts at index 3.

string.lastIndexOf(searchString, position)

lastIndexOf searches for the index of the last occurrence of a given substring.

For instance, we can write:

console.log('foobarbar'.lastIndexOf('bar'));

and get 6 because the last 'bar' starts in index 6.

string.localeCompare(that)

localeCompare lets us compare 2 strings in a way that’s locale-specific.

For instance, we can write:

const m = ['FOO', 'foo'];
m.sort((a, b) => a.localeCompare(b));

Then we get that m is [“foo”, “FOO”] since the string order of 'foo' is before 'FOO' .

string.match(regexp)

We can use the match method to get all the matches of a given regex in a string.

If the regex has the g flag, then all instances of the match will be returned.

The capturing groups will be excluded.

For instance, we can write:

console.log('foobarbar'.match(/bar/g));

Then we get [“bar”, “bar”] logged in the console.

string.replace(searchValue, replaceValue)

We can use the replace method to replace a substring of a string with another substring.

A new string with the replaced substring is returned.

For instance, we can write:

const str = 'foo'
const bar = str.replace('foo', 'bar');

Then bar is 'bar' .

We can also use a regex instead of a string for searchValue .

For instance, we can write:

const str = '555-1212'
const phone = str.replace(/d{3}/, '000');

console.log(phone);

Then we get ‘000–1212’ as the value of phone . We searched for the part of a string with 3 digits and replaced it with ‘000’.

The replace method also can take a few string tokens that does various replacements as the value of replaceValue .

For instance, '$$' represents the dollar sign.

'$&' represents the matched text.

$number represents the capture group text.

$` represents the text preceding the match.

$’ represents the text following the match.

For instance, if we have:

const str = '555-1212'
const phone = str.replace(/d{3}/, '$&-123');

Then phone is ‘555–123–1212’ because we get the substring with 3 digits and added '-123' after it.

string.search(regexp)

The search method lets us search for the string with the given regex and return the index of the first occurrence that matches a given pattern.

For instance, we can write:

const str = '555-1212'
const index = str.search(/d{3}/);

Then we get 0 for index since the first occurrence of a part of the string with 3 digits is at the start of the string.

string.slice(start,end)

slice leys us make a new string by taking the part with the start index to end index minus 1 and return it.

For instance, we can write:

const str = '555-1212'
const phone = str.slice(0, 3);

and we get '555' for phone .

end is optional and the indexes can be negative, in which case the count will start from the end of the string.

If we have:

const str = '555-1212'
const phone = str.slice(-3);

Then phone is '212' because we start from -3 , which is the 3rd last index of the string.

string.split(separator, limit)

The split method splits a string by the separator . limit sets the maximum number of pieces that will be returned.

For instance, we can write:

const str = '5551212'
const arr = str.split('', 5);

Then we get [“5”, “5”, “5”, “1”, “2”] as the value of arr since we stop at 5 pieces.

string.substring(start,end)

substring is the same as slice but doesn’t work with negative indexes.

Conclusion

There are many useful JavaScript string methods in the standard library of JavaScript.

To make our lives easier, we should use them as much as possible.

Categories
JavaScript

Good Parts of JavaScript — Flow Control

JavaScript is one of the most popular programming languages in the world. It can do a lot and have some features that are ahead of many other languages.

In this article, we’ll look at some good parts of JavaScript, including flow control.

Falsy Values

Falsy values in JavaScript will prevent an if or else if block from running.

Falsy values are the following:

  • false
  • null
  • undefined
  • empty string ‘’
  • 0
  • NaN

Everything else is truthy.

Switch Statements

switch statements perform multiway branching.

It compares an expression with the specified cases.

A case can be a statement or a block. A case statement or block can contain one or more expressions.

The case expressions don’t have to be constants.

While Statement

A while statement performs a simple loop. The loop will stop running if the condition that’s after while is falsy.

Otherwise, the loop body will run.

For Statement

A for statement is more complex than a while loop.

It may contain 3 optional clauses, which is the initialization code, the condition, while the loop runs, and the increment statement.

First, the initialization code is run.

Then the condition is evaluated at each iteration. If the condition is truthy, then the loop will run.

Otherwise, the loop will break.

Then the increment statement runs. The statement updates the index variable.

The for loop looks like:

for (let i = 0; i < MAX; i++) {  
  //...  
}

The loop runs from i is 0 from i is one less than MAX .

For-In Loop

The for-in loop loops through the keys of an object, including any inherited properties.

The order that the keys are looped depends on how the browser implements the for-in loop.

This means that we can’t depend on the order that the keys are being looped through.

To check if the property is inherited or not, we can use the hasOwnProperty method that comes with objects.

We can do that by writing the following code:

for (const key in obj) {  
  if (obj.hasOwnProperty(key)) {  
    //..  
  }  
}

In the code above, we have the key that we looped through in obj , including inherited properties.

Therefore, we’ve to call obj.hasOwnProperty(key) if we only want to deal with keys that are in obj itself.

For-Of Loop

The for-of loop loops through the items that are in any iterable object.

This includes things like arrays, NodeLists, sets, maps, generators, and anything else we create.

For instance, we can write:

for (const a in arr) {  
  //..  
}

This means looping through items easier than with a while or for loop since we don’t have to specify any conditions.

It just loops through all the entries that are in the iterable object.

Try Statement

The try statement runs a block of code and catches an exception that was thrown in the block.

The catch clauses go after the try clause and receive the exception object.

It looks like:

try {  
  //...  
} catch (ex) {  
  //...  
}

Throw Statement

The throw statement is used to throw exceptions, which can be caught with the try...catch block.

For instance, we can write:

throw new Error('error');

We can throw anything with the throw statement, but the error object has information like stack traces and line number of where the error occurred that aren’t available anywhere else.

Return Statement

The return statement lets us end a function wherever we want inside the function block.

JavaScript doesn’t allow a line between the return and expression that it’s returning.

Break Statement

break statements are for ending loops or terminating the switch statement.

We can also add a label to end a labeled statement.

break and the label has to be the same line.

Expressions Statement

An expression statement can either assign variables or one or more variables or members.

It can also run a method or delete property from an object.

The = operator is used for assignment, which we shouldn’t confuse with the === operator.

The += operator can add or concatenate.

Conclusion

break statements are used for ending loops and switch cases.

return is used for ending functions anywhere in our code.

The throw statement is used to throw any object as an error which can then be caught by the catch block.