Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — String and Math

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at the String and Math objects.

String Object Methods

Strings have various methods we can call to do stuff with.

The toUpperCase method lets us return the upper case version of the string.

For instance, if we have:

const s = 'foo';

Then:

s.toUpperCase();

returns 'FOO' .

The toLowerCase method converts a string to all lower case.

For example:

s.toLowerCase()

returns 'foo' .

The charAt method returns the character found at the position we specify.

For instance, if we have:

s.charAt(0);

then we get 'f' .

We can just write s[0] for short.

If we pass in a non-existent position to charAt , we get an empty string.

The indexOf method lets us search for a substring within a string.

For instance, if we have:

s.indexOf('o');

we get 1.

Also, we can optionally specify the position to start the search with indexOf .

For instance, we can write:

s.indexOf('o', 2);

and we get 2.

The lastIndexOf method starts the search from the end of the string.

For instance, if we write:

s.lastIndexOf('o');

we get 2.

We can also search for a series of characters.

For example, if we have:

const str = 'foobar';
str.indexOf('bar');

we get 3.

They can be combined together.

So we can write:

s.toLowerCase().indexOf('foo'.toLowerCase());

The slice() and substring() methods return a piece of the string when we specify the start and end position.

If we have:

const str = 'foobar';
str.slice(1, 3);
str.substring(1, 3);

and we get 'oo' .

The split method lets us split a string by a separator.

For instance, we can write:

const s = 'foo bar';
const arr = s.split(" ");

console.log(arr);

Then arr is [“foo”, “bar”] since we split by a space.

The join method joins an array of strings into one with a separator between them.

So if we have:

["foo", "bar"].join(' ')

We get:

"foo bar"

The concatr method appends a string into an existing string.

So if we have:

'foo'.concat("bar")

We get:

"foobar"

Math

The Math object isn’t a function.

It’s an object that has various constants and methods.

Constants that it includes are:

  • Math.PI — pi
  • Math.SQRT2 — the square root of 2
  • Math.E — Euler’s constant
  • Math.LN2 — natural log of 2
  • Math.LN10 — nature log of 10

We can generate a random number of between 0 and 1 with Math.random() .

We can use the expression:

((max - min) * Math.random()) + min

to generate a random number between min and max .

Math has various methods to round numbers.

floor() rounds down.

ceil() rounds up.

And round() rounds to the nearest integer.

We can use them by passing in a number:

Math.floor(9.1)
Math.ceil(9.1)
Math.`round`(9.1)

Math.pow raises a base to an exponent.

For instance, kf we have:

Math.pow(2, 3);

then we get 8. 2 is the base and 3 is the exponent.

The Math.sqrt method returns the square root of a number.

For instance, we can write:

Math.sqrt(9);

and we get 3.

Conclusion

Strings have various methods to let us manipulate them.

The Math object lets us do various operations and provides us with some constants.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — RegExp

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at the RegExp object.

RegExp

The RegExp constructor lets us search and manipulate text.

JavaScript uses the Perl 5 syntax for defining regex.

A regex consists of a pattern to use and match the text.

It can optionally contain zero or more modifiers to provide more instructions on how the pattern should be used.

For instance, we can use the RegExp constructor by writing:

const re = new RegExp("c.*t");

We have a regex that matches a word with some letters in between c and t .

. means any character.

* means preceding whatever comes after.

We can add some modifiers called flags to change the regex.

Some flags include:

  • g for global.
  • i for ignoring case
  • m for multiline

So if we have:

const re = new RegExp("c.*t", 'gmi');

We can check that it does global match with the global property.

So re.global should return true .

The property can’t be set, so assigning a value to it won’t change the value.

RegExp Methods

RegExp instances have some methods.

They include the test and exec method.

test checks whether a string matches the regex pattern.

And exec returns the string the matches the regex.

We can call test by running;

/c.*t/.test("CoffeeScript");

then we get false .

But we call:

/c.*t/i.test("CoffeeScript");

then we get true because of the case-insensitive match.

To call exec , we can write:

/c.*t/i.exec("CoffeesScript")[0];

Then we get:

"CoffeesScript"

String Methods that Accept Regex as Arguments

Some string methods accept regex as arguments.

They include:

  • match — returns an array of matches
  • search — returns the position of the first search
  • replace — substitute matched text with another string
  • split — accepts a regex when splitting string into an array of elements

We can pass in a regex to search and match .

For instance, we can write:

'JavaScript'.match(/a/);

then we get ['a'] .

If we have”

'JavaScript'.match(/a/g);

Then we get:

["a", "a"]

If we write:

'JavaScript'.match(/J.*a/g);

then we get:

["Java"]

If we call search :

'JavaScript'.search(/J.*a/g);

then we get the position of the matched string, which is 0.

The replace method lets us replace the matched text with some other string.

For instance, we can remove all lowercase letters by writing:

'JavaScript'.replace(/[a-z]/g, '')

Then we get:

"JS"

We can also use the $& placeholder to let us add something to matches.

For instance, we can write:

'JavaScript'.replace(/[A-Z]/g, '-$&')

Then we get:

"-Java-Script"

replace can take a callback that lets us return the matches manipulated our way.

For instance, we can write:

'JavaScript'.replace(/[A-Z]/g, (match) => {
  return `-${match.toLowerCase()}`;
})

Then we get:

"-java-script"

We replaced the upper case characters with lower case and add a dash before it.

The first parameter of the callback is the match.

The last is the string being searched.

The one before last is the position of the match .

And the rest of the parameters have any strings matched by any group in our regex pattern.

The split method lets us split a string.

It takes a regex with the [pattern to split by.

For instance, we write:

const csv = 'one, two,three ,four'.split(/s*,s*/);

Then we get:

["one", "two", "three", "four"]

We split the string by the whitespace to get that.

Conclusion

The RegExp constructor lets us find patterns in a string and work with them.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Prototypes, Call, and Apply

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at prototypes, call , and apply .

Function Prototypes

Functions have a special prototype property that has items that are shared between all instances of the constructor function.

For instance, we can write:

function F() {}

F.prototype = {
  name: 'james',
  say() {
    return `I am ${this.nam}`;
  }
};

Then if we create 2 instances of F :

const foo = new F();
const bar = new F();
console.log(foo, bar);

We see that both foo and bar have the same properties.

The say method also does the same thing.

Methods of Function Objects

Function objects have their own methods.

For instance, functions have the toString method to return the string with the code of the function.

So if we have:

function add(a, b, c) {
  return a + b + c;
}

console.log(add.toString());

We get:

"function add(a, b, c) {
  return a + b + c;
}"

logged.

Call and Apply

Functions have the call and apply method to let us run functions, set the value of this and pass arguments to it.

For instance, if we have:

const obj = {
  name: 'james',
  say(who) {
    return `${this.name} is ${who}`;
  }
};

Then we can call say with call by writing:

const a = obj.say.call({
  name: 'mary'
}, 'female');

Then a is 'mary is female’ .

We set this to:

{
  name: 'mary'
}

so this.name is 'mary' .

The 2nd argument is the argument for say , so who is 'female' .

We can also call apply by doing the same thing, except that the arguments of the function are in the array.

For instance, we can write:

const obj = {
  name: 'james',
  say(who) {
    return `${this.name} is ${who}`;
  }
};

const a = obj.say.apply({
  name: 'mary'
}, ['female']);

and we get the same thing.

Lexical this in Arrow Functions

this is a dynamic object that changes according to its context.

Arrow functions don’t bind to its own value of this .

So if we have:

const obj = {
  prefix: "Hello",
  greet(names) {
    names.forEach(function(name) {
      console.log(`${this.prefix} ${name}`);
    })
  }
}

We’ll get an error with the greet method since this is the callback function, so it doesn’t have the prefix property.

But if we use an arrow function:

const obj = {
  prefix: "Hello",
  greet(names) {
    names.forEach((name) => {
      console.log(`${this.prefix} ${name}`);
    })
  }
}

Then the function works properly since it doesn’t bind to its own value of this .

Inferring Object Types

The toString method of Object.prototype gives us the class name that’s used to create an object.

For instance, we can write:

Object.prototype.toString.call({});

And get:

"[object Object]"

And if we write:

Object.prototype.toString.call([]);

We get:

"[object Array]"

We can use call with the toString method by writing:

Array.prototype.toString.call([1, 2, 3]);

We get:

"1,2,3"

This is the same as:

[1, 2, 3].toString()

Conclusion

The call and apply methods let us call functions with different values of this and arguments.

Also, the prototype has properties that are shared between all constructor instances.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Parameters and Built-in Functions

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at various kinds of functions and parameters.

Default Parameters

We can set default parameters in a function.

To do that, we just assign a value to a parameter.

We can write:

function render(fogLevel = 0, sparkLevel = 100) {
  console.log(`Fog Level: ${fogLevel} and spark level:
${sparkLevel}`)
}

We have a render function with the fogLevel and sparkLevel parameters.

And we set their default to 0 and 100 respectively.

Then if we have:

render()

Then we get:

'Fog Level: 0 and spark level: 100'

Default parameters have their own scope.

The scope is sandwich between the outer functina and the inner function scope.

So if we have:

let scope = "outer";

function scoper(val = scope) {
  let scope = "inner";
  console.log(val);
}
scoper();

Then val would be 'outer' since it takes scope from outside of the function.

Rest Parameters

Rest parameters let us get an arbitrary number of arguments from a function.

For instance, we can write:

function getTodos(...todos) {
  console.log(Array.isArray(todos));
  console.log(todos)
}

Then we get the first console log is true .

And the 2nd is [“eat”, “drink”, “sleep”] .

todos is an array because we have a rest operator before it.

This makes it gets the arguments and put them all in the todos array.

And we get all of them with the 2nd console log.

Spread Operators

The spread operator lets us spread array entries as arguments of a function.

We can also use it to spread values in an array.

For instance, we can write:

const min = Math.min(...[1, 2, 3]);

This replaces the old way, which is:

const min = Math.min.apply(undefined, [1, 2, 3]);

The spread operator is easier to understand and it’s shorter.

1, 2 and 3 are the arguments of Math.min .

We can also use the spread operator to merge array items into another array.

For instance, we can write:

const midweek = ['Wed', 'Thu'];
const weekend = ['Sat', 'Sun'];
const week = ['Mon', 'Tue', ...midweek, 'Fri', ...weekend]

Then week is:

["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]

Predefined Functions

There’s a number of predefined functions in JavaScript.

They’re:

  • parseInt()
  • parseFloat()
  • isNaN()
  • isFinite()
  • encodeURI()
  • decodeURI()
  • encodeURIComponent()
  • decodeURIComponent()
  • eval()

parseInt parses a non-number value to an integer.

For instance, we can use parseInt by writing:

parseInt('123')

parseFloat parses a non-number value to a floating-point number.

And we get 123 .

For instance, we can use parseFloatby writing:

parseFloat('123.45')

And we get 123.45 .

isNaN checks if a value is NaN .

So if we have:

isNaN(NaN)

We get true .

isFinite checks if a value is a finite number.

So we can write:

isFinite(Infinity)

and we get false .

We can encode a string to a URI with encodeURI .

For instance, if we have:

const url = 'http://www.example.com/foo?bar=this and that';
console.log(encodeURI(url));

and we get:

'http://www.example.com/foo?bar=this%20and%20that'

And we can decode a URI string with decodeURI .

encoudeURIComponent and decodeURIComponent can do the same thing for part of a URI.

If we write:

const url = 'http://www.example.com/foo?bar=this and that';
console.log(encodeURIComponent(url));

and we get:

'http%3A%2F%2Fwww.example.com%2Ffoo%3Fbar%3Dthis%20and%20that'

eval lets us run code from a string. This is one we shouldn’t use because anyone can pass in a malicious string to it.

And code in strings can’t be optimized.

Conclusion

Default parameters let us set default values for parameters if they aren’t set with arguments.

JavaScript comes with some predefined functions we can use.

The rest and spread operator are handy for handling arguments.

Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Objects and Constructors

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at objects and constructors.

Accessing an Object’s Properties

We can access an object’s properties by using the square bracket notation or the dot notation.

To use the square bracket notation, we can write:

dog['name']

This works for all property names, whether they’re valid identifiers or not.

We can also use them to access properties by passing in a property name dynamically with a string or symbol.

The dot notation can be used by writing:

dog.name

This is shorter but only works with valid identifiers.

An object can contain another object.

For instance, we can write:

const book = {
  name: 'javascript basics',
  published: 2020,
  author: {
    firstName: 'jane',
    lastName: 'smith'
  }
};

The author property has the firstName and lastName properties.

We can get nested properties by writing:

book['author']['firstName']

or

book.author.firstName

We can mix the square brackets and dot notation.

So we can write:

book['author'].firstName

Calling an Object’s Methods

We can call a method the same way we call any other function.

For instance, if we have the following object:

const dog = {
  name: 'james',
  gender: 'male',
  speak() {
    console.log('woof');
  }
};

Then we can call the speak method by writing:

dog.speak()

Altering Properties/Methods

We can change properties by assigning a value.

For instance, we can write:

dog.name = 'jane';
dog.gender = 'female';
dog.speak = function() {
  console.log('she barked');
}

We can delete a property from an object with the delete operator:

delete dog.name

Then when we try to get dog.name , we get undefined .

Using this Value

An object has its own this value.

We can use it in our object’s methods.

For instance, we can write:

const dog = {
  name: 'james',
  sayName() {
    return this.name;
  }
};

We return this.name , which should be 'james' .

Because this is the dog object within the sayName method.

Constructor Functions

We can create constructor functions to let us create objects with a fixed structure.

For instance, we can write:

function Person(name, occupation) {
  this.name = name;
  this.occupation = occupation;
  this.whoAreYou = function() {
    return `${this.name} ${this.occupation}`
  };
}

We have the instance properties name , occupation and the this.whoAreYou instance method.

They’re all returned when we create a new object with the constructor.

Then we can use the new operator to create a new Person instance:

const jane = new Person('jane', 'writer');

The value of this os set to the returned Person instance.

We should capitalize the first letter of the constructor so that we can tell them apart from other functions.

We shouldn’t call constructor functions without the new operator.

So we don’t write:

const jane = Person('jane', 'writer');

The value of this won’t be set to the returned Person instance this way.

The Global Object

The global object in the browser is the window object.

We can add properties to it with var at the top level:

var a = 1;

Then window.a would be 1.

Calling a constructor without new will return undefined .

So if we have:

const jane = Person('jane', 'writer');

then jane is undefined .

The built-in global functions are properties of the global object.

So parseInt is the same as window.parseInt .

Conclusion

We can access object properties in 2 ways.

Also, we can create constructor functions to create objects with a set structure.