Categories
JavaScript

How to Check If a JavaScript String Contains a Substring

Checking if a JavaScript string contains a substring is easy. We can either use the includes method or we can use the indexOf method.

includes

To use the includes method, we can do that by writing the following code:

const hasFoo = 'foo bar'.includes('foo');

In the code above, we called the includes method on the string literal. It takes the substring to seacrh for in the first argument.

The 2nd argument, which is optional, is the position in the string to start the search from.

It returns true if the substring is found in the string that it’s called on and false otherwise.

In our example, we skipped the 2nd argument, so it’ll start searching from the beginning.

Therefore, hasFoo is true since 'foo' is in the string.

To search from a given index of the string that it’s called on, we can call it as follows:

const hasFoo = 'foo bar'.includes('foo', 5);

In the code above, it’ll start searching from index 5, which is past where 'foo' is. Therefore, it’ll return false and hasFoo is false.

indexOf

indexOf is another method that we can use to check if a substring is in a string. It takes the same arguments as includes but it returns the index of the first instance of the substring. If the substring isn’t found, then -1 is returned.

We can use it as follows:

const index = 'foo bar'.indexOf('foo');

We search for the 'foo' substring in the code above. Then indexOf returns 0 since 'foo' is at the beginning of the string.

Also, we can set the index to start searching from as follows:

const index= 'foo bar'.indexOf('foo', 5);

Then we get -1 for index since 'foo' is not found in any index from 5 or beyond.

Conclusion

We can call includes and index to check if a JavaScript string contains a given substring.

Categories
JavaScript

Why it’s time to ditch the for…in Loop in JavaScript?

Since ES5.1, we have new features for iterating through the properties of an object. In the past, we only had the for...in loop to accomplish this.

In this article, we’ll look at why the new ways to loop through the properties of an object are much better than the for...in loop. This includes the Object.keys method, which is available since ES5.1, but updated in ES6 to support Symbols, and the Object.entries and Object.values methods new to ES2017. To loop through Symbol keys, we have the Reflect.ownKeys method.

Characteristics of the for…in Loop

The for...in loop lets us iterate over the non-Symbol, enumerable properties of an object.

It will iterate over the properties of an object in arbitrary order. Therefore, we can’t depend on the order of which the keys of an object are iterated over.

The properties that are deleted with the delete keyword won’t be iterated over. If a property is modified during iteration, then the value when it’s visited later will be the value after the change is done.

Modifying an object’s properties during iteration is a bad idea since it creates confusion because of the characteristics mentioned above.

Some people also use it for iterating through arrays since the for...in will get the indexes of an array like the keys of an object. However, this is again a bad idea since the order isn’t guaranteed.

Also, it iterates over its own properties and its prototype’s properties. For example, if we have:

const person = {  
  name: 'Joe'  
};  
const employee = {  
  title: 'waiter'  
};

employee.__proto__ = person;  
for (let prop in employee) {  
  console.log(prop);}

Then we see both name and title logged from the console.log in the for...in loop.

We might not want this, so we have to use the hasOwnProperty method from an object’s prototype to check if the property is actually an object’s own property as follows:

const person = {  
  name: 'Joe'  
};  
const employee = {  
  title: 'waiter'  
};

employee.__proto__ = person;  
for (let prop in employee) {  
  if (employee.hasOwnProperty(prop)) {  
    console.log(prop);  
  }  
}

As we can see, without hasOwnProperty, the for...in loop loops through all the own and inherited properties of an object.

This isn’t very convenient since it’s often not what we want.

Also, since the for...in loop was introduced before ES6 and was never updated, it’s not aware of Symbol property keys, so if we have the following object:

const foo = {  
  [Symbol('foo')]: 'Joe'  
};

When we try to loop through the foo object as follows:

for (let prop in foo) {  
  console.log(prop);  
}

We get nothing.

for…in Loop’s Performance

The for...in loop is also slow. This is because the loop has to check if each property is enumerable all the way up the prototype chain and then return the name of each enumerable property.

Getting it to work with arbitrary objects is tough because the structure isn’t constant. It has to check each key and its prototype’s keys to do this for each property. Therefore, a lot more computation is involved than a simple for loop.

Of course, the bigger the array or object, the bigger this issue is, but this is still something to keep in mind for those situations.

New Ways to Iterate Through Properties of an Object

Object.keys

Since ES5.1, we have the Object.keys method to get the keys of an object and return them as an array.

The keys are returned in the following order. First are keys with integer indexes in ascending numeric order. Then all other string keys in the order which they’re added to the object.

Unlike the for...in loop, there’s some reasoning to the order in which the keys are returned. And since Object.keys returns an array, we can sort it however we like.

We can also use the for...of loop or forEach method to write a cleaner loop.

Also, we don’t have to use hasOwnProperty to check if an object’s properties are its own properties anymore.

Since Object.keys is released with ES6, Symbols are supported.

For example, given that we have the same inherited object as the above example:

const person = {  
  name: 'Joe'  
};  
const employee = {  
  title: 'waiter'  
};

employee.__proto__ = person;

We can loop through it as follows:

for (let prop of Object.keys(employee)) {  
  console.log(prop);  
}

We only get back 'title' from the loop above.

The ordering can be seen as follows. If we have the following object:

const foo = {  
  a: 1,  
  b: 2,  
  1: 'a',  
  2: 'b',  
  3: 'c',  
};

When we loop through the keys with:

for (let prop of Object.keys(foo)) {  
  console.log(prop);  
}

Then we get back:

1  
2  
3  
a  
b

Object.values

To get the values from an object’s without the inherited properties, we can use the Object.values() method.

The order of iteration is the same as Object.keys , but we get back the values instead of the keys.

For example, given the following objects:

const person = {  
  name: 'Joe'  
};  
const employee = {  
  title: 'waiter'  
};  
employee.__proto__ = person;

We can loop through the own values of employee without the person ‘s property values as follows:

for (let val of Object.values(employee)) {  
  console.log(val);  
}

We should only get 'waiter' from the console.log .

The Object.values method is new to ES2017.

Object.entries

To get the key-value pair in one loop, we can use the Object.entries method. It takes an object as an argument like the other methods we mentioned above.

The method returns an array that has the key-value pair of its own properties in an array.

For example, given that we have the following object:

const person = {  
  name: 'Joe'  
};  
const employee = {  
  title: 'waiter'  
};  
employee.__proto__ = person;

We can use the Object.entries method as follows:

for (let entry of Object.entries(employee)) {  
  console.log(entry);  
}

Then we get back:

["title", "waiter"]

That is the key and the value of the property in the employee respectively.

Reflect.ownKeys

None of the Object methods support Symbols. To loop through objects with Symbol keys, we can use the Reflect.ownKeys method. Like Object.keys , it gets the keys of an object’s own properties, but Symbol keys are also supported. And it also returns an array of keys. String keys are also supported like Object.keys.

For example, given that we have the following object:

const foo = {  
  [Symbol('foo')]: 'Joe'  
};

We can use Reflect.ownKeys:

for (let prop of Reflect.ownKeys(foo)) {  
  console.log(prop);  
}

Then we get back Symbol(foo) .

Getting values from Symbol keys also work if we write the following loop:

for (let prop of Reflect.ownKeys(foo)) {  
  console.log(foo[prop]);  
}

Then we get back 'Joe’ .

This method is new with ES6.

As we can see, since ES5.1 or later, we have many alternatives to using the for...in loop to loop through the properties of objects. The only feature that’s useful in the for...in loop is to loop through the inherited properties of an object.

Otherwise, we should use Object.keys , Object.entries , Object.values since they all return arrays of keys or values or both. Also, the order is predictable, unlike the for...in loop. Since arrays are returned, we can sort them and loop through the properties or values the way we like to.

If we need to loop through Symbol keys, we can use the Reflect.ownKeys method.

Categories
JavaScript

Why JavaScript Arrow Functions are Useful?

Since ES6, there are two types of general-purpose functions. One is the traditional function declared with the function keyword. The other is the newer arrow function introduced with ES6.

In this article, we’ll look at why arrow functions are useful and when we should use them.

Defining Arrow Functions

Arrow functions are functions that have the fat arrow. For example, we can declare them as follows:

const fn = () => 'foo';

The code above will define the fn function and return the string 'foo'.

Multi-line functions can be written as follows:

const add = (a, b) => {  
  return a + b;  
}

The code above adds two numbers together.


Syntactic Sugar

Arrow functions have a less verbose syntax than traditional functions. As we can see from the first example above, we can define functions in one line. Return is implicit if the function is one line.

Also, we don’t have to keep writing the function keyword to declare functions.


We Don’t Have to Worry About ‘this’

It doesn’t have its own this. This means that we don’t have to worry about the value of this inside it.

This is a good thing in most cases except when we want to write class methods or constructor function methods. In all other cases, we really don’t care about this if we use arrow functions instead of functions.

Also with traditional functions, if we want to access the value of this inside of the outer function in the inner function, we have to access the value as follows:

In the code above, we want to access this.bar from within the foobar function. We have to do it by writing:

var that = this;

And in the foobar function, we write:

console.log(that.bar);

This is a pain and it’s easy to forget.

If we use arrow functions, we can eliminate both lines and write:

This is much better since we need to write less code and we don’t have to worry about the value of this inside the arrow function.

In addition, we can’t use bind, apply, or call to change the value of this inside an arrow function since this can’t change inside an arrow function.

This is a nice characteristic for functions that don’t use this, as lots of confusion is removed.


Hoisting and Function Declaration vs. Expression

There are two ways to define traditional functions in JavaScript.

One is function declaration and the other is function expression. Function declarations are loaded before any code is run, while function expressions load when the JavaScript interpreter loads the code.

An example of a function declaration is below:

function foo() {  
  return 1;  
}

An example of a function expression is below:

const foo = function() {  
  return 1;  
}

Since function declarations are loaded before anything else runs, they can be referenced in any part of a code file with the function declaration. This is called hoisting.

Function expressions aren’t available until the code for defining the function is run.

This difference is often overlooked and it causes confusion easily. We can remove this confusion by using arrow functions since we don’t have to worry about hoisting, function declarations, and function expressions.

With arrow functions, we can only define the functions as we did above, and it’s never available before it’s declared.


Arguments Object

Arrow functions don’t have their own arguments object. The arguments object is an array-like object that has all the arguments that we pass into the function call.

arguments is an array-like object, so it has indexes, bracket notation for accessing its entries, and the length property. And, we can loop through the items with the for loop, but other than that, it’s nothing like an array.

This is another source of confusion since it’s kind of like an array but not really an array. With arrow functions, we can use the rest parameters instead, which does give us an array.

For instance, we can write:

const foo = (...args) => {  
  return args;  
}

Then when we call foo as follows:

foo(1, 2, 3, 4, 5)

We get:

[1, 2, 3, 4, 5]

Which is a real array, so we can use array methods and the spread operator with it. This is much better than the confusing arguments object that we had to use to get dynamic parameter values, before arrow functions and the rest operator existed.


Conclusion

As we can see, arrow functions are quite useful except for using them as class methods or constructor function methods. Lots of confusion is eliminated with this, hoisting, function declarations vs. expressions, etc.

Also, it’s much cleaner in terms of syntax since we don’t have to use the function keyword to declare functions and return is implicit in one-line functions.

Also, we don’t have to be confused about the arguments object anymore since arguments doesn’t bind to arrow functions.

Categories
JavaScript

How To Manipulate Strings in JavaScript

JavaScript has built-in functions and constructs to do most string operations. The ones that don’t can be done with a few simple function calls.


Combine Strings

Concatenation

There are two ways to do it. One way is to use the concat function.

For example:

const hello = "Hello ";  
const bob = "Bob!";  
const res = hello.concat(bob); // Hello Bob!

Another way is to use the + operator, like so:

const hello = "Hello ";  
const bob = "Bob!";  
const res = hello + bob; // Hello Bob!

Template strings

ES6 or later has template strings so you can include strings within another string, like this:

const hello = "Hello ";  
const bob = "Bob!";  
const res = `${hello} ${bob}`; // Hello Bob!

Array.join

If you have an array of strings, you can combine the entries with the same separator between them, with the join function, like this:

const arr = ['Hello', 'Bob'];  
const res = arr.join(' '); // 'Hello Bob'

Get Substring

String.substr

JavaScript strings have a substr function to get the substring of a string.

It takes a starting index as the first argument and a number of characters from the start index, and so on as the second argument.

It can be used like this:

const str = "Hello Bob";  
const res = str.substr(1, 4); // ello

String.substring

JavaScript strings also have a substring function that takes the start and end index as two arguments and returns a string with the ones between the start and end indices.

The start index is included but the end index is excluded.

Example:

const str = "Hello Bob";  
const res = str.substring(1, 3); // el

Changing Cases

String.toLocaleLowerCase()

Converts a string to lowercase, according to the locale of your browser. The new string is returned, instead of modifying the original string.

For example:

const str = "Hello Bob!";  
const res = str.toLocaleLowerCase(); // hello bob!

String.toLocaleUpperCase()

Converts a string to uppercase, according to the locale of your browser. The new string is returned, instead of modifying the original string.

For example:

const str = "Hello Bob!";  
const res = str.toLocaleUpperCase(); // 'HELLO BOB!'

String.toLowerCase()

Converts a string to lowercase. The new string is returned, instead of modifying the original string.

For example:

const str = "Hello Bob!";  
const res = str.toLocaleLowerCase(); // 'hello bob!'

String.toUpperCase()

Converts a string to uppercase. The new string is returned, instead of modifying the original string.

For example:

const str = "Hello Bob!";  
const res = str.toLocaleUpperCase(); // 'HELLO BOB!'

Removing Whitespace

String.trim()

Remove starting and ending white space from a string.

For example:

const str = "         Hello Bob!     ";  
const res = str.trim(); // 'Hello Bob!'

Remove all whitespaces from a string

There is no function to remove all whitespace from a string. We have to replace the spaces in the string with empty strings to do this.

For example:

const str = "         Hello Bob!     ";  
const res = str.replace(/ /g, ''); // 'HelloBob!'

Repeating Strings

There are a few ways to repeat a string in JavaScript. JavaScript strings have a built-in repeat() function.

You can also use a loop to do the same thing.

String.repeat Function

To use the repeat function, you pass in the number of times you want to repeat the string as an argument. It returns a new string.

For example:

const hello = "hello";  
const hello5 = A.repeat(5);  
console.log(hello5); // "hellohellohellohellohello"

Use a loop

You can use the for loop and while loop to perform repeatedly concatenate strings.

Using a for loop, you can do:

const hello = "hello";  
let hello5 = '';  
for (let i = 1; i <= 5; i++){  
  hello5 += hello;  
}  
console.log(hello5); // "hellohellohellohellohello"

With a while loop, you can do:

const hello = "hello";  
let hello5 = '';  
let i = 1;  
while(i <= 5){  
  hello5 += hello;  
  i++  
}  
console.log(hello5); // "hellohellohellohellohello"

They both involve increment indexes up to the maximum.


Search

There are a few ways to search for strings in JavaScript.

Strings have the startsWith, endsWith, indexOf, lastIndexOf, charAt, search, includes, and match functions.

startsWith

startsWith checks if a string starts with the substring you pass in.

For example:

const str = "Hello world.";  
const hasHello = str.startsWith("Hello"); // trueconst str2 = "Hello world.";  
const hasHello2 = str.startsWith("abc"); // false

endsWith

endsWith checks if a string ends with the substring you pass in.

For example:

const str = "Hello world.";  
const hasHello = str.endsWith("world."); // trueconst str2 = "Hello world.";  
const hasHello2 = str.endsWith("abc"); // false

indexOf

indexOf finds the index of the first occurrence of the substring. Returns -1 if not found.

For example:

const str = "Hello Hello.";  
const hasHello = str.indexOf("Hello"); // 0  
const hasHello2 = str.indexOf("abc"); // -1

lastIndexOf

lastIndexOf finds the index of the last occurrence of the substring. Returns -1 if not found.

For example:

const str = "Hello Hello.";  
const hasHello = str.lastIndexOf("Hello"); // 6  
const hasHello2 = str.lastIndexOf("abc"); // -1

charAt

charAt returns the character located at the index of the string.

For example:

const str = "Hello";  
const res = str.charAt(0); // 'H'

search

search gets the position of the substring passed into the function. It returns -1 if the substring is not found in the string.

Example:

const str = "Hello";  
const res = str.search('H'); // 0

includes

includes checks if the passed-in substring is in the string. Returns true if it is in the string, false otherwise.

const str = "Hello";  
const hasH = str.includes('H'); // true  
const hasW = str.includes('W'); // false

Replace

The replace() function, included with strings, is useful for replacing parts of strings with another. It returns a new string with the string after the substring is replaced.

Example:

const str = "Hello Bob";  
const res = str.replace("Bob", "James"); // 'Hello James'

replace() can also be used to replace all occurrences of a substring.

For example:

const str = "There are 2 chickens in fridge. I will eat chickens today.";  
const res = str.replace(/chickens/g, "ducks"); // "There are 2 chickens in fridge. I will eat chickens today."

If the first argument is a regular expression that searches globally, it will replace all occurrences of the substring.

Categories
JavaScript

Using the Javascript Conditional Operator

The JavaScript conditional operator is a basic building block of JavaScript programs.

The conditional operator is also called the ternary operator.

It lets us write expression that returns one thing if a given condition it truthy and return something else otherwise.

The conditional operator is denoted by the ? operator.

We can use it as follows:

const foo = condition ? 'foo' : 'bar';

In the code above, if condition is truthy, then 'foo' is returned. Otherwise, 'bar' is returned.

Then the returned value is assigned to the foo variable.

The code is above is short for:

if (condition) {
  return 'foo';
}
else {
  return 'bar';
}

As we can see, the code above is much longer than using the conditional operator.

Since it’s save so much typing and space on the page, we should use the conditional operator instead of using if statements if we want to write code that returns one thing if a given condition is truthy and something else otherwise.