Categories
JavaScript

Good Parts of JavaScript — Arrays

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 arrays.

Array Literals

Array literals are the easiest way to define arrays.

We can create one by writing:

const arr = ['foo', 'bar', 'baz'];

Then we can access the content its index:

arr[1]

That’ll return 'bar' since the index of the first entry is 0.

Arrays also has the length property to check the size of an array.

We can write:

arr.length

to get the length of arr , which would be 3.

Object literals with numeric keys are similar to arrays, but we can’t iterate through an object that has numeric keys and the length property.

JavaScript array entries don’t have to be the same type, so we can write:

const arr = ['foo', 1, 'baz'];

And that is a valid array.

Length

Arrays have the length property. JavaScript arrays don’t use length as an upper bound.

We can access any index of an array as long as it’s a non-negative integer.

However, if the array index isn’t associated with any entry, then we get undefined .

We can set the length property explicitly.

Making the length larger doesn’t allocate more space for the array.

However, making the length smaller will cause properties with an index greater than or equal to the next length will be deleted.

Because we can access any index, we can add a new element to an array by writing:

arr[arr.length] = 'baz';

2 other convenient ways to add items to the end of the array are either to use the push method or the spread operator.

To use the push method, we write:

arr.push('baz');

push adds an entry to arr in place.

To use the spread operator, we can write:

arr = [...arr, 'baz'];

arr is spread into a new array and then we add 'baz' to the end of it and then assign it back to arr .

Delete

Since JavaScript arrays are objects, we can use the delete operator to remove an element with the given index.

For instance, we can write:

delete arr[2];

to remove 'baz' from the arr given that arr is:

const arr = ['foo', 1, 'baz'];

However, that will leave a hole in the array.

What we want to do usually to remove the item along with the slot.

We can make this easy by using the splice method.

To remove an array item with the splice method we can write:

arr.splice(1, 1);

The code above will remove one entry from starting from index 1.

Therefore, the only item with index 1 is removed.

splice removed the item in place, so that we remove the item from arr without leaving an empty slot.

Enumeration

We can use the for-in loop to loop through array entries since we can loop through the array indexes as we do with keys.

However, since the order isn’t guaranteed, we can’t use this to loop through the items reliably.

Also, for-in loops through the items in the array’s prototype, which we probably don’t want.

Therefore, it’s not good for looping through arrays.

Instead, we can use the for loop or for-of loop to loop through the items.

For instance, we can write:

for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

We initialize i to the starring index and we loop through the array’s length minus 1.

To use the for-of loop, we write:

for (const a of arr) {
  console.log(arr);
}

They’re both very convenient choices.

Conclusion

We can create arrays and loop through them easily.

The most convenient way to create an array is to use the array literal notation.

JavaScript array can have any kind of content in it.

To add items to an array, we can use the push method or the spread operator.

To remove an item, we can use the splice method.

To loop through arrays, we can use the for loop or the for-of loop.

They’re both better than the for-in loop for looping through arrays.

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.