Categories
JavaScript Tips

Useful JavaScript Tips — Operators

Like any kind of apps, JavaScript apps also have to be written well. Otherwise, we can 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.

Ternary Operator

The ternary lets us return expressions according to a condition. It takes 3 operands.

For instance, we can write:

const eating = true;
(eating) ? stop() : eat()

We check if eating is true and call stop() and return its value if it is. Otherwise, we call eat and return its value.

Logical Operators

JavaScript has a few logical operators. We have the and, or, and not operators. The and-operator returns true if both operands and true.

For instance, we write:

a && b > 10

It can also do checks on the first operand and evaluate the second operand if the first is truthy.

So we can write:

const color = dog && dog.color;

Then dog.color is evaluated only if dog is truth. The or operator returns true if at least one of the operands is true .

For instance, we can write:

a || b > 10

It’s also very useful for providing a default value. For example, we can write:

const color = dog.color || 'brown';

The expression evaluates dog.color and if it’s falsy, then 'brown' will be returned. The not operator is used to invert the value of a boolean.

For instance, we can write:

let foo = true
!foo

Then !foo is false since foo is true .

Return Values

Every JavaScript function returns a value. If a function doesn’t have an explicit return statement or have a return statement that doesn’t have an expression after it, then it returns undefined .

For instance, we can write:

const foo = () => {
  return 'bar';
}

Then it returns 'bar' . A return statement can only return one value. If a function return arrays then we can use destructuring syntax to decompose the entries into variables.

For instance, we can write:

const foo = () => {
  return ['james', 10];
}
const [name, age] = foo();

The returned array is decomposed into variables according to their position. Likewise, we can do the same thing if a function returns an object.

For instance, we can write:

const foo = () => {
  return { name: 'james', age: 10 };
}
const { name, age } = foo();

This way we decompose the returned object into variables by their property names.

Spread Operator

The spread operator is used to expand an array, object, or string,

For instance, we can use it to spread array entries into another array:

const a = [1, 2, 3];
const b = [...a, 4, 5];

Then b os [1, 2, 3, 4, 5] .

We can copy an array by writing:

const copy = [...a];

It also works with objects, we can clone an object by writing:

const copyObj = { ...obj };

We can spread a string into an array of characters using the spread operator:

const hello = 'hello';
const arr = [...hello];

Then arr is [“h”, “e”, “l”, “l”, “o”] . The spread operator can also be used to spread an array.

For instance, we can write:

const foo = (a, b) => {};
const a = [1, 2];
foo(...a);

We spread the a array into the arguments of foo , so a is 1 and 1bis 2.

The rest operator lets us get the array entries that haven’t been spread by writing:

const nums = [1, 2, 3, 4, 5];
const [one, two, ...rest] = nums;

The one is 1, two is 2, and rest has an array with the remaining nums entries. Likewise, we can do the same with objects.

For instance, we can write:

const {
  foo,
  bar,
  ...others
} = {
  foo: 1,
  bar: 2,
  a: 3,
  b: 4,
  baz: 5
}

We used the rest operator which has the object with the properties that haven’t been destructured. Also, we can use the spread operator to merge 2 objects together.

For instance, we can write:

const obj1 = {
  name: 'james'
}

const obj2 = {
  age: 15
}

const person = {...obj1, ...obj2 }

We combined obj1 and obj2 into a single person object using the spread operator.

Conclusion

There are many uses for the spread and rest operators with arrays and objects. The ternary operator can be used to replace short conditions. Functions always return some value either implicitly or explicitly.

Categories
JavaScript Tips

Useful JavaScript Tips — Object Properties and Copying

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.

Comparing 2 Objects with Object.is()

An alternative way to compare 2 objects is with the Object.is method.

It’s almost the same as the === operator.

However, NaN is the same as itself.

For instance, we can write:

Object.is(a, b)

Then we can compare 2 variables a and b .

Get the Prototype of an Object

We can get the prototype of an object with the Object.getPrototypeOf method.

For instance, we can get the prototype of an object as follows:

const animal = {
  name: 'james',
  age: 7
};

const dog = Object.create(animal);

We created a dog object with Object.create so that dog will inherit from animal .

So if we call Object.gerPrototypeOf with it:

const prot = Object.getPrototypeOf(dog);

Then:

prot === animal

would be true since animal is dog ‘s prototype.

Get the Non-inherited Symbols of an Object

The Object.getOwnPropertySymbols returns all the non-inherited symbol keys of an object.

If we have the follow object:

const name = Symbol('name')
const age = Symbol('age')
const dog = {
  [name]: 'james',
  [age]: 7
}

Then we can call getOwnPropertySymbols as follows:

const syms = Object.getOwnPropertySymbols(dog);

Then we get that syms is :

[Symbol(name), Symbol(age)]

Get Non-inherited String Keys of an Object

The Object.getOwnPropetyNames method lets us get an array of string keys of an object.

The keys return aren’t inherited from any prototypes.

For instance, we can write:

const dog = {
  breed: 'poodle'
}

const keys = Object.getOwnPropertyNames(dog);

Then we get [“breed”] as the value of keys .

Get Key-Value Pairs of an Object

The Object.entries method returns an array of key-value pairs of an object.

For example, we can write:

const person = { name: 'james', age: 18 }
const pairs = Object.entries(person);

Then pairs would be:

[
  [
    "name",
    "james"
  ],
  [
    "age",
    18
  ]
]

where the first entry of the inner arrays is the key name, and the 2nd is the value.

Add a Single Property to an Object

We can call Object.defineProperty on an object to create a new property.

For instance, we can write:

const dog = {};
Object.defineProperty(dog, 'breed', {
  value: 'poodle'
})

We added the breed property into dog using the defineProperty method.

Add Multiple Properties to an Object at Once

In addition to the Object.defineProperty , there’s also the Object.defineProperties method to add multiple properties to an object.

For instance, we can write:

const dog = {};
Object.defineProperty(dog, {
  breed: {
    value: 'poodle'
  },
  name: {
    value: 'james'
  },
})

Then dog would be {breed: “poodle”, name: “james”} .

It’s a convenient way to add multiple properties to an object at once.

Creating an Object with Object.create

Object.create lets us create an object with a prototype.

For instance, we can write:

const animal = {
  name: 'james',
  age: 7
};

const dog = Object.create(animal);

Then dog is has animal as its prototype.

It’ll inherit all the properties from animal .

So dog.name would be 'james' .

Copying and Combining Objects with Object.assign

Object.assign lets us combine multiple objects into one or copy them.

To make a copy of an object, we can write:

const copy = Object.assign({}, original)

We make a copy of the original object and assigned it to the copy variable.

{} should be the first argument so that we won’t modify any existing objects and copy them into an empty object.

To combine multiple objects, we can write:

const merged  = Object.assign({}, obj1, obj2)

We copy all the own string properties from obj1 and obj2 into the empty object in the first argument.

So merged would have all the own properties from both.

Conclusion

We can compare and copy objects with static Object methods.

Also, we can define properties on an object with them.

Also, we can copy and merge objects with the Object.assign method.

It does a shallow copy so that the top-level is copied.

Categories
JavaScript Tips

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

Looping Over Arrays

JavaScript provides many array methods that we can use to work with arrays in a concise manner.

while Loop

We can use the while loop to loop through arrays.

For instance, we can write:

let index = 0;
const arr = [1,2,3];

while (index < arr.length) {
  console.log(arr[index]);
  index++;
}

We update the index at each iterator to access the objects in arr .

Classical for Loop

There’s also the classical for loop for iterating overt items in an array.

It works by setting up the initial condition, the ending condition, and the array index update statement on the first line of the loo.

For instance, we write:

const arr = [1,2,3];
for (let index = 0; index < arr.length; index++) {
  console.log(arr[index]);
}

forEach

We can use the forEach method to loop through array entries.

It takes a callback that we can run code on each entry.

For instance, we can write:

const arr = [1,2,3];

arr.forEach((val, index, array) => {
  console.log(index, array, val);
});

We have arr which we called forEach on.

Then we get the array entry with val , the index of the entry with index , and the array itself with array .

map

map lets us map our array entries from one to the other.

For instance, we can write:

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

We have the cube function which we pass in as the callback for the map function.

x has the array entry’s value.

cubes has the new array with each entry of arr cubed.

reduce

The reduce method lets is combine the entries into a single value.

For instance, we can write:

const arr = [1,2,3];
const sum = (total, y) => total + y;
const sum = arr.reduce(sum, 0);

We have arr which we called reduce on by passing in the sum function as its callback.

The first parameter is the accumulate total so far and the second is the entry being added into the total .

The 2nd argument of reduce is the initial value.

The combination of the entries is done from left to right.

There’s also a reduceRight method that combines entries from right to left.

filter

The filter method returns an array that meets the condition in the callback.

For instance, we can write:

const arr = [1,2,3];
const isEven = x => x % 2 === 0;
const evenArr = arr.filter(isEven);

We have isEven , which is a function that checks if an array entry x is evenly divisible by 2.

We call filter on arr with isEven passed in.

Then evenArr should have all the even entries in arr .

every

The every method checks if every entry in the array meet some given condition.

For instance, we can write:

const arr = [1,2,3];
const under10 = x => x < 10;
const allUnder10 = arr.every(under10);

We have under10 , which checks if every entry is under 10.

x is the array entry.

Then we called every with under10 as the callback.

allUnder10 should be true since all entries in arr are less than 10.

some

some checks if one or more elements in the array match the given condition.

For instance, we can write:

const arr = [1,2,3];
const under10 = x => x < 10;
const someUnder10 = arr.some(under10);

Then someUnder10 should be true since there’s at least one entry in arr that’s less than 10.

Closures

We can create an enclosed scope in loops by running:

for (let i = 0; i < 3; i++) {
  funcs[i] = ((value) => {
    console.log(value);
  })(i);
}

This way, we get the value of the index variable looped when we called the function in funcs .

Conclusion

We can use array methods to save us the effort of looping through entries and doing what we want.

Also, we should wrap our code in IIFEs to create a closure with the index variable value of a loop.

Categories
JavaScript Tips

Useful JavaScript Tips — Objects and Scopes

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.

Polluting Global Scope

We should never define global variables to declare the global scope.

To avoid this, we use let and const to declare variables.

For instance, we write:

ler x = 1;

or:

const y = 2;

We shouldn’t declare variables with var or without a keyword before it.

They both declare global variables, which we don’t want.

Likewise, we should not use function declarations.

Instead, we should use function expressions.

So instead of writing:

function foo() {}

We write:

const foo = () => {}

We can also enclose our variables within IIFEs to keep them private:

(() => {
  let  = 1;
})()

Now they are not accessible outside the function.

Use Strict Mode

We should use strict mode to disallow some bad constructs in our code.

For instance, we can’t assign things to reserved keywords like:

undefined = 1;

Also, we can’t accidentally define global variables by assigning to variables without declaring them.

So we can’t create global variables like:

foo = 1;

foo is a global variable since we declared it without a keyword.

Strict Equality

We shoild use the === or !== operators to compare values since data type conversions aren’t done before comparison with them.

For instance, instead of writing:

a == b

We write:

a === b

It’s much safer than the == operator.

Likewise, for inequality, we should use the !== operator.

So we can write:

a !== b

instead of:

a != b

Use && or || to Conditionally Evaluate Expressions

We should use the || operator to return the right operand if the left operand is falsy.

For instance, we can write:

const str = '' || 'foo';

to return 'foo' since empty string is falsy.

Similarly, we can use the && operator to evaluate the right expression if the left expression is truthy.

So we can write:

const baz = obj.foo && obj.foo.baz;

This way, obj.foo.baz is only returns only if obj.foo is truthy.

This can avoid lots of undefined errors when accessing nested properties.

Convert Value Types

We can convert strings to numbers by using the + operator.

For instance, we can write:

const foo = +'100'

to get 100 as the value of foo .

Also, we can use the !! operators to convert anything to a boolean.

For example, we can write:

!!0

to convert it to false since it’s falsy.

Follow Style Guides

There are many good style guides that we can follow to write good JavaScript code.

For instance, we can following the Google JavaScript Style Guide, airbnb/javascript guide, and others so that we can follow some good practices when writing JavaScript.

To automate the process of checking for bad good, we can use ESLint co check for them.

Creating Immutable Objects in JavaScript

We can create immutable objects in JavaScript with the Object.seal method.

For instance, we can write:

Object.seal(foo);

to make foo immutable.

It makes the object immutable and doesn’t return anything.

It prevents the modification of property descriptors.

There’s also the Object.preventExtensions for preventing adding properties to an object.

For instance, we can write:

Object.`preventExtensions`(foo);

Also, we can write:

`Object.freeze(`foo`);`

Then we can do all the things that seal and prevenExtensions does.

Creating Hash Maps without Side Effects

We can create a pure object without a prototype by using Object.create with the null argument.

For instance, we can write:

const map = Object.create(null);

Then the map object won’t have a prototype.

We can use it as a dictionary safely.

Cloning Immutable Objects

We can use the clone package to clone an object.

For instance, we can write:

const clone = require('clone');

const a = { foo: { bar: 1 } };
const b = clone(a);

Now we can clone a and make the clone a value of b so that we can us manipulate b without affecting a .

Conclusion

We can prevent objects from being modified with some Object methods.

Also, we can use the clone property to clone objects.

In addition, we can use && or || to do things other than creating boolean expressions.

Categories
JavaScript Tips

Useful JavaScript Tips — Numbers and String Whitespaces

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.

Check if a Number is Finite

The isFinite method lets us check if a value is a finite number or not.

For instance:

Number.isFinite(1)

returns true .

On the other hand:

Number.isFinite(1)

returns false .

Format a Decimal Number into a String

We can use the toFixed method to format a decimal number into a string.

For instance, we can write:

(20.22).toFixed()

and get '20' .

Also, we can pass in the number of decimal digits we want to keep by writing:

(20.22).toFixed(1)

and get “20.2” .

Format a Number into a Language Sensitive String

The toLocaleString method lets us get a string that has a number formatted according to the locale.

For instance, we can write:

(20.22).toLocaleString('fr-ca')

Then we get “20,22” .

Format a Number into Exponential Notation

The toExponential method lets us convert a number into a string that’s in exponential notation.

For instance, we can write:

(21.22).toExponential()

Then we get “2.122e+1” .

Change the Number of Decimal Digits of a Number

The toPrecision method formats a number into a string that has the given number of decimal digits.

For instance, we can write:

(21.21).toPrecision(5)

Then we get “21.210” .

We can also pass in a number that’s smaller than the number of decimal digits in the number.

Then we get a string with the number formatted into exponential notation.

For instance, we can write:

(21.21).toPrecision(1)

And we get “2e+1” .

Converting a Number to a String

The toString method converts a number to a string.

The argument it takes is the radix.

For instance, if we want to convert the decimal number 10 to binary, we can write:

(10).toString(2)

Then it returns “1010" .

Parsing a String into an Integer

We can parse a string into an integer with the parseInt method.

For instance, we can write:

Number.parseInt('10.00')

and we get back 10.

It also takes a second argument with the radix.

So if we want to convert it to a given base, we can do that by writing:

Number.parseInt('16', 16)

Then we get 22 since we converted '16' to a base 16 number.

Parsing a String into a Floating Point Number

There’s the Number.parseFloat method to convert a string into a floating-point number.

For instance, we can write:

Number.parseFloat('10.00')

and get 10.

It can also convert a string to a number if it starts with a number by removing the non-numerical parts and converting the rest to a number.

For example, we can write:

Number.parseFloat('36 bottles')

Then we get 36.

Check if a Number is Within a Safe Range

In JavaScript, a number is considered to be safe if it’s between -2 ** 53 and 2 ** 53 .

To check that, we can use the Number.isSafeInteger method.

For instance, we can write:

Number.isSafeInteger(2 ** 53)

which returns true , and:

Number.isSafeInteger(2 ** 53 + 1)

which is false .

Checking if a Value is NaN

Checking for NaN is tricky.

Therefore, we should use the Number.isNaN to do it since we can’t use === to do the comparison.

For instance, we can write:

Number.isNaN(NaN)

and that would return true .

Also:

Number.isNaN('foo' / 'bar')

returns true .

Check if a value is an Integer

The isInteger method lets us check if a value is an integer.

We can use it by writing:

Number.isInteger(1)

which returns true , or:

Number.isInteger(0.2)

which returns false .

Trimming the beginning of a String

We can remove whitespace from the beginning of a string with the trimStart method.

For instance, we can write:

'   foo'.trimStart()

Then it returns “foo” .

Trimming the End of a String

There’s also the trimEnd method to remove whitespace from the end of a string.

For example, we write:

'foo   '.trimStart()

Then it returns “foo” .

Trimming Both Ends of a String

The trim method will remove whitespace from both ends of a string.

For instance, we can write:

'   foo   '.trim()

Then it returns 'foo' .

Conclusion

There are various ways to parse and check numbers.

Also, JavaScript strings have methods to remove whitespaces.