Categories
JavaScript

Good Parts of JavaScript — Function

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

Function Objects

In JavaScript, functions are objects. And like any other object, it has key-value pairs and has prototypes of its own.

Functions are linked to Function.prototype , which is linked to Object.prototype .

All functions have 2 additional properties, which are the function’s context and the code that implements its behavior, which is the function’s body.

Each function is created with a prototype property, which is an object with the constructor property whose value is a function.

This is distinct from Function.prototype .

Function.prototype is the parent object of function, and the prototype property is a property of the function itself.

Since functions are just objects, they can be stored in variables, objects, and arrays.

Functions can be passed as arguments to functions and functions can be returned from another function.

Since functions are objects, they can have methods of their own.

Function Literal

We can create JavaScript functions as function literals.

For instance, we can write the following:

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

or we can write:

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

Functions can have up to 4 parts.

For traditional functions, we have the function keyword, the name of the function, parameters, and the body.

For arrow functions, we have the function keyword, parameters, and the body.

Parameters of a function are wrapped in parentheses.

It has a set of zero or more parameter names, separated by commas.

The names will be defined as variables in a function.

Parameters are set to the argument that’s passed in as the value. They’re set depending on the position.

So the first parameter’s value will be the first argument, the second parameter’s value will be the 2nd argument, and so on.

Functions parameters can also have default values set to them.

If we assign it a default value, then when we omit the parameter or pass in undefined , then the parameter’s value will be set to the default value when we call it.

This way, we don’t have to worry about parameters not having a value.

We can also have rest parameters, where all the arguments that aren’t set to a parameter are put into an array.

A function created by a function literal that contains a link to the outer function’s context is called a closure.

To add default parameters, we can write:

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

Now if we don’t pass in a value for b when we call add, b will be set to 1.

To add a rest parameter, we can write the following:

const add = (a, b, ...rest) => {  
  //...  
};

The rest will be an array that has arguments that are after the 2nd argument.

We can create a closure by writing:

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

The returned function can have access to the outer function’s variable.

These are useful because we can put private variables in the outer function that isn’t accessible to the outside.

However, we can use those variables in the returned function.

This is a good way to hold private variables since there’re no way to hold them in classes.

The only alternative to hold private variables is in modules.

Invocation

Invoking a function ends the execution of the current function, and pass control to parameters of the new function.

Every function have this and arguments as the variables in addition to the parameters.

this is very important since it holds the object that it’s in or the instance of a constructor.

The invocation operator is a pair of parentheses that surround arguments.

For instance, we can write:

add(1, 2);

to call the add function with 1 and 2 as arguments.

Conclusion

In JavaScript, functions are objects. There’re a few parts to a function. It includes the function keyword, parameters, the body, and the name.

Not all functions will have all the parts.

There are 2 kinds of functions. They include arrow functions and traditional functions.

Functions can have default and rest parameters.

Categories
JavaScript

Good Parts of JavaScript — Array Methods and Nested 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 manipulate JavaScript arrays with methods and nested arrays.

Array and Object Confusion

It may be easy to confuse arrays and objects.

Objects may have numerical keys and the length property.

However, they aren’t arrays.

The typeof operator doesn’t help with checking arrays. This is because using typeof on an array will just return 'object' .

To check if something is an array, we can use the Array.isArray method.

Methods

JavaScript arrays have lots of methods.

There’re methods to map items in an array to different values.

Also, we can combine them in different ways.

There are also a few methods that help to search for items.

For instance, we can use the map method to map the items of an array to different values as follows:

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

Now we return a new array with entries of arr that are cubed.

So we get [1, 8, 27] as the value of arr .

To combine all entries of an array in some way, we can use the reduce or reduceRight methods.

For instance, we can write:

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

The code above combines the items in arr by adding them together. The intermediate result is assigned to ac and entry is the array entry being incorporated.

0 is the initial value of the combined result.

reduce combines entries from left to right.

To combine values from right to left, we can write:

const arr = [1, 2, 3];
const sum = arr.reduceRight((acc, entry) => acc + entry, 0);

reduceRight starts from the end of arr to the start. So acc starts with 3, then 2 is added to 3 to get 5, 5 is added to 1 to get 6.

The find and findIndex methods get the first instance of an object.

find returns the first instance of something that matches the criteria that we get.

findIndex returns the index of the first instance of something that’s been found.

So we can write:

const arr = [1, 2, 3];
const result = arr.find(x => x === 1);

and result is 1.

or we can use findIndex :

const arr = [1, 2, 3];
const result = arr.findIndex(x => x === 1);

and get that result is 0, which is the index of 1.

The filter method returns an array that has the entries that meet a given condition.

For instance, we can write:

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

Then result is [1, 3] since we specified x % 2 === 1 . The condition that we specified is to return all the odd numbers.

Dimensions

There’re no multidimensional arrays in JavaScript.

However, we can have arrays of arrays.

For instance, we can create an array of arrays by writing:

const arr = [];
arr[0] = [1, 2, 3];
arr[1] = [4, 5, 6];

Now we can loop through them by writing:

const arr = [];
arr[0] = [1, 2, 3];
arr[1] = [4, 5, 6];

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

We looped through the items in the top-level array.

Then in the loop body, we loop through the item of each array.

If we run the loop, we get:

1
2
3
4
5
6

from the console log.

Also, we can use the for-of loop to make this clearer. For instance, we can write:

const arr = [];
arr[0] = [1, 2, 3];
arr[1] = [4, 5, 6];

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

And we get the same result. We just used the for-of loop to make our iteration code cleaner.

Conclusion

Array methods will make our lives easier. We can call the find and findIndex methods to find items.

map will map array entries from one value to another.

reduce and reduceRight let us combine array entries to a single value.

We can create JavaScript nested arrays and use them as multidimensional arrays.

Categories
JavaScript

Good Parts of JavaScript — Objects Types and Structure

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 objects, including looking at the type and structure.

Getting Types of Property Values

We can use the typeof operator to get the value of a property.

For instance, given the following object:

const obj = {  
  'foo': 1,  
  'bar': {  
    'baz': 2  
  }  
}

We can write the following by writing:

typeof obj.foo

Then we should get 'number' .

However, we want to be careful with this operator because properties up the prototype chain can also return a value.

For instance, we can write:

typeof obj.toString

and we’ll see 'function' returned.

Therefore, if we don’t want to get the types of an object’s prototypes by accident, we should use the hasOwnProperty method to check if the property is in the object first.

For instance, we can write:

obj.hasOwnProperty('foo')

to check if 'foo' is a property of obj itself.

Then that returns true since it’s defined in obj itself.

On the other hand, if we write:

obj.hasOwnProperty('toString')

Then we should get false returned since it’s part of obj ‘s prototype.

Enumeration

There’re a few ways to enumerate object properties in JavaScript.

We can use the for-in loop to loop through an object’s properties.

However, there are 2 catches. The order of the enumeration isn’t guaranteed. Also, for-in loops through all the properties of all of an object’s prototype up the prototype chain.

For instance, we can write:

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

to loop through the keys of obj and its prototypes keys.

To prevent us from looping through an object’s prototypes’ properties, we can use the hasOwnProperty method again to check if the property is an own property or not.

For instance, we can write:

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

Object.keys

If we only want to loop through an object’s own keys, we can use the Object.keys method to get them.

It returns an array of keys to the own enumerable properties of an object.

Only string keys are returned.

For instance, we can write:

for (const key of Object.keys(obj)) {  
  //...  
}

We use the for-of instead of the for-in loop to loop through the own keys of obj .

Reflect.ownKeys

Reflect.ownKeys does is very similar to Object.keys . It returns an array of own keys of the given object.

The difference is that both string and symbols keys are returned.

For instance, we can write:

for (const key of `Reflect.ownKeys`(obj)) {  
  //...  
}

Delete

The delete operator is used to removing a property from an object.

If an object has the given property, then it’ll be removed if we use the delete operator.

For instance, given the following object:

const obj = {  
  'foo': 1,  
  'bar': {  
    'baz': 2  
  }  
}

We can use:

delete obj.foo;

to remove the foo property from obj .

Global Abatement

One bad part of JavaScript is that it’s too easy to define global variables.

This makes our program less robust with namespace collisions and makes errors hard to trace.

We can minimize the use of global variables in a few ways.

We can out our local code in objects. We can put them in blocks, or we can put them in modules.

If we create an object:

const obj = {  
  'foo': 1,  
  'bar': {  
    'baz': 2  
  }  
}

Then obj.foo isn’t a global object.

We should also never attach anything like a property of window or global in Node apps.

Also, if we put them in blocks, then we can use let and const to declare block-scoped variables and constants.

They won’t be available globally.

Items in modules also aren’t available globally.

Conclusion

We can get the types of property values by using the typeof operator.

Enumeration can be done with the for-in, for-of, Object.keys or Reflect.ownKeys methods.

The delete operator can be used to remove properties from an object.

To reduce the use of global variables, we can put variables in blocks, modules, or objects.

Categories
JavaScript

Good Parts of JavaScript — Currying, Memoization, and Inheritance

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 curry functions, memoization, and inheritance.

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.

We can improve curry by replacing apply with the spread syntax:

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

This is cleaner and now fn can be arrow functions in addition to a traditional function.

Memoization

We can do memorization by keeping previously computed results that we need later.

For instance, if we have a function that computes a Fibonacci number, we can write:

const fib = (num) => {
  let a = 1,
    b = 1;
  for (let i = 1; i <= num; i++) {
    [a, b] = [b, a + b];
  }
  return a;
}

In the code above, we store the values of a and b .

We keep the values of a and b so that we can use it to create new Fibonacci numbers with them.

Inheritance

JavaScript inheritance is done by using prototypical inheritance.

However, it has a syntax that resembles classical inheritance with the class syntax.

For instance, we can implement inheritance by writing the following code:

class Animal {
  speak() {
    //...
  }
}

class Dog extends Animal {}
class Cat extends Animal {}

In the code above, we used the class keyword to create constructors.

The extends keyword is used to inherit members from Animal in the Dog and Cat constructors.

Now if we create a new Dog instance:

const dog = new Dog();

We have the __proto__ property in Dog which is set to the Animal constructor.

The speak method is in the object that’s set as the value of the __proto__ property.

We can call the speak method by writing dog.speak() .

Prototypal Inheritance

If we have object literals, we can use the Object.create method to inherit items from another object.

We can use it as follows:

const parent = {
  foo() {
    //...
  }
}

const child = Object.create(parent);
console.log(child);

In the code above, we have the parent object with the foo method.

Then we can use the Object.create method to create an object with parent as the prototype.

If we log the child object’s content, we have the __proto__ property which has the prototype of child .

The __proto__ property has the foo method.

Like inherited methods from class/constructor instances, we can call foo as follows:

child.foo();

Conclusion

We can curry functions by returning a function that applies arguments to a function that hasn’t been applied yet.

Memoization can be done by storing values that will be used later so we can use them.

For inheritance, we can create constructors with the class syntax with the extends keyword.

We can also use the Object.create method for creating objects with our own prototypes.

This is a convenient way to create objects from a prototype object and inherit its properties.

Categories
JavaScript

Good Parts of JavaScript — Objects

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

JavaScript Objects

In JavaScript, the primitive types are their own types, and objects are object types.

Primitive types are numbers, booleans, strings, null , undefined , symbols and bigint.

Everything else is objects.

Objects in JavaScript are mutable kets collections. Also, arrays are objects.

Regular expressions are also objects. And objects are objects.

An object is a container of properties. Properties have names and values.

A property can be a string, including the empty string. A value can be any JavaScript value except for undefined .

There are no true classes in JavaScript. There are no constraints on how property keys and values are structured.

Objects can contain other objects, so we can use them to represent tree structures.

We can implement inheritance with prototypes.

A prototype is a template object that other objects can inherit properties from.

Object Literals

Object literals are a way convenient way for us to define objects.

We create one by adding curly braces and then add key-value pairs inside it.

Property keys can be strings and values can be anything.

We can use any string as property names, including an empty string.

If our name is a valid identifier name and it’s not a reserved word, then we don’t need quotes.

For instance, we can create an object literal by writing:

const obj = {
  'foo': 1,
  'bar': false
}

or we can write:

const obj = {
  foo: 1,
  bar: false
}

since foo and bar are valid identifier names.

Objects can be nested, we can write:

const obj = {
  'foo': 1,
  'bar': {
    'baz': 2
  }
}

Retrieval

We can get a property’s value either with the dot notation or the bracket notation.

The . notation is better because it’s shorter and easier to read.

For instance, we can write:

obj.foo

and get 1.

And we can write:

obj.bar.baz

to get 2.

The bracket notation is mainly used for accessing properties dynamically and also for getting properties that are invalid identifiers.

For instance, we can write:

obj["first-name"]

to get the 'first-name' property of obj .

If we try to get a property from something that’s undefined , then we’ll get a TypeError exception.

The prevent that from happening, we need to use the && operator as follows:

obj.bar && obj.bar.baz

Now obj.bar.baz is run only with obj.bar is defined.

Update

We can update object property values by using the assignment operator.

For instance, we can write:

obj['foo'] = 3;

or write:

obj.foo = 3;

Reference

Objects are always passed by reference. Therefore, if we modify an object’s property value as follows:

const obj = {
  'foo': 1,
  'bar': {
    'baz': 2
  }
}

const obj2 = obj;
obj.foo = 3;

Both obj.foo and obj2.foo are 3 instead of 1.

Prototype

Almost every object is linked to a prototype object from which inherit properties.

All objects by default are linked to Object.prototype .

The only exception is when we create an object as follows:

const obj = Object.create(null);

The argument for Object.create is the prototype of the object returned by Object.create.

Therefore, obj will have no prototype.

Otherwise, our object will have a prototype. For instance, if we create an empty object:

const obj = {};

We’ll see that the __proto__ property will have the properties of Object.prototype .

If we update a property, it’ll update the property on the object itself rather than its prototype.

The prototype link is only used for retrieval. If we get a value from an object and if it’s not in the object itself.

Then the JavaScript interpreter will get the value from the prototype.

If a property isn’t in the object itself or its prototypes, then undefined is returned.

This is called delegation.

Conclusion

JavaScript objects can be created with object literals.

Most objects have prototypes except for ones that are explicitly created without a prototype.

A prototype is an object where properties can be inherited from another object.