Categories
TypeScript

Great New Features Released with TypeScript 3.5

TypeScript is improving every day. We keep getting new features with every release. In this article, we’ll look at the new stuff that was released with TypeScript 3.5.

New features include speed improvements to incremental builds, new Omit helper type, better excess property checks in union types, and type inference for the composition of constructors.

Speed Improvements

With the --incremental build mode, subsequent builds are faster because of the caching of references, file locations, and other build related data.

Omit Helper Type

The Omit helper type was introduced in TypeScript 3.5 to let us create a new type from existing types by excluding some properties from the original.

For example, given the Person type defined in the following code:

type Person = {
    name: string;
    age: number;
    address: string;
};

We can create a new type without the address property by using Omit:

type NewPerson = Omit<Person, "address">;

Which is the same as:

type NewPerson = {
    name: string;
    age: number;
}

Better Excess Property Checks in Union Types

Before TypeScript 3.5, excess property checks didn’t catch properties in some cases. If we have a union type, then TypeScript versions before 3.5 allows a property with the same name as the type of a union type but with a different type than what’s specified in the type definition.

For example, if we have:

type Person = {
    name: string;
    age: number;
};

type Address = {
    address: string;
}

const person: Person | Address = {
    name: 'Joe',
    age: 1,
    address: true
};

We can set address to something that’s not a string, which isn’t something that should be allowed.

This has been fixed in TypeScript 3.5. Now address has to be a string since it’s specified to be a string.

The --allowUmdGlobalAccess Flag

UMD global declarations files can now be referenced in TypeScript 3.5 using the new --allowUmdGlobalAccess flag.

It adds more flexibility for mixing and matching 3rd party libraries. Now the globals that libraries declare can be consumed, even from within modules.

Smarter Union Type Checking

We would get an error with the following union type definition and variable assignment before TypeScript 3.5:

type Foo = { done: boolean, value: string }
type Bar =
    | { done: false, value: string }
    | { done: true, value: string };

declare let source: Foo;
declare let target: Bar;

target = source;

Before 3.5, done would be recognized as having a literal type with the value instead of the boolean type.

Now it recognizes the type for the done field as being boolean. This now works boolean can only be true or false .

Higher-Order Type Inference From Generic Constructors

When we compose generic constructors as we do in the following function:

function composeConstructors<T, U, V>(
    F: new (x: T) => U, G: new (y: U) => V): (x: T) => V {
    return x => new G(new F(x))
}

TypeScript 3.5 can infer the type T , U , and V by inferring the chain of types that are formed from the composition.

If we have the following code:

class Foo<T> {
    value: T;
    constructor(value: T) {
        this.value = value;
    }
}

class Bar<U> {
    value: U;
    constructor(value: U) {
        this.value = value;
    }
}

let f = composeConstructors(Foo, Bar);
let a = f('foo');

Now we’ll get that a has the type Bar<Foo<string>> . Versions before 3.5 has the type Bar<{}> for a .

TypeScript 3.5 is smarter now. It can infer types formed by the composition of constructors.

With TypeScript 3.5, it’s smarter and faster. It can infer types formed by the composition of constructors by going through the chain of composition.

Excess property checks are checked for union types, which didn’t happen in earlier versions.

Also, we have the -- allowUmdGlobalAccess flag to run access global variables from UMD modules.

Finally, we have the Omit type for creating a new type from existing types with some properties removed.

Categories
HTML JavaScript

Introducing the Page Visibility API

Since most modern browsers are tabbed, it’s possible that a webpage may reside in a tab that stays in the background and not visible to the user.

The Page Visibility API can provide us with insight as to whether a page is visible to the user.

In this article, we’ll look at the Page Visibility API, its use cases, and how to use it.

Visibility Change Event

When a user minimizes the window or switches to another tab, the Page Visibility API sends a visibilitychange event to let listeners know that the state of the page has changed.

We can handle the event when it’s triggered and do something according to the visibility state. For example, we can pause the video when the page is hidden from view.

The visibility state of an iframe is the same as the parent document that the iframe is in. Hiding an iframe with CSS doesn’t trigger visibility events or change the state of the document contained within the iframe .

Use Cases

There’re many use cases for using the API. Some of them include the following:

  • pausing an image carousel when the page is hidden
  • stop polling the server for information when the page is hidden
  • prerendering a page to keep an accurate count of page views
  • switch off the sound when the page is not being viewed

Without the Page Visibility API, developers resort to imperfect solutions like listening to the blur or focus events of the window to help detect whether the page is visible or not.

They don’t tell if they’re hidden or not, just whether they’re in focus or not.

Policies that Help Background Page Performance

Most browsers do a few things to help save resources when a page isn’t in view.

requestAnimationFrame callback won’t be called to improve performance and battery life when a page is in the background.

setTimeout and other timers are throttles in the background or inactive tabs to improve performance.

Throttling is also done in browsers to limit CPU usage by background tabs.

Each background tab has its own time budget between -150ms and 50ms.

Browser windows are subjected to throttling after 30 seconds in Firefox and 10 seconds in Chrome.

Timer tasks are only permitted when the time budget is non-negative.

Once the timer’s code finishes running, the duration it takes to execute is subtracted from the time budget.

The budget regenerates at a rate of 10ms per second in both Firefox and Chrome.

Some processes ate exempt from throttling behavior. Tabs that are playing audio are considered foreground tabs and aren’t subject to throttling.

Code that uses real-time network connections goes unthrottled to prevent the closing of these connections.

IndexedDB processes are also left unthrottled to avoid timeouts.

The Page Visibility API can let us stop these things manually if we want to do so.

Using the Page Visibility API

The Page Visibility API is part of the document object.

We can use it by checking the document.hidden property or the document.visibilityState property. They’re both read-only.

To watch for changes in both, we can listen to the visibilitychange event.

To do this we can use the following example. Our example will pause a video when we switch to a different tab. First, we add the HTML code for the video as follows:

<video controls src='[https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4'](https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4%27)></video>

Then in our JavaScript code, we can listen to the visibilitychange event as follows:

const video = document.querySelector('video');

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState !== 'visible') {
    video.pause();
  }
})

In our event listener callback, we pause the video when the visibilityState isn’t ‘visible’ , which means the user can’t see the tab either by navigating away from the tab or window, minimizing the window, or turned the screen off.

The alternative to this is to set the event handler to the onvisibilitychange property of document.

document.visibilityState can take on these 3 values:

  • visible — the page is visible to the user as a foreground tab
  • hidden — the page isn’t visible to the user, either because it’s in the background, or the minimized or the device’s screen is off.
  • prerender — the page is being prerendered and isn’t visible to the user. A document may start in this state, but will never switch to this state from any other state since it can only prerender once. Not all browsers support prerendering.
  • unloaded — the page is being unloaded from memory. Not all browsers support this.

Compatibility

This API has been supported for a while. Chrome since version 33 supports this API. Edge, Firefox, IE 10 or later, and Safari 7 or later all support this API. Mobile versions of these browsers also support this API.

The Page Visibility API is useful for detecting the visibility state of the page. We can listen to the visibilitychange event and then get the visibility state with document.visibilityState and so what we want with it.

Categories
JavaScript Basics

Introduction to JavaScript Symbols

In ES2015, a new primitive type called Symbol is introduced. It is a unique and immutable identifier. Once you have created it, it cannot be copied.

Every time you create a new symbol, it’s a unique one. Symbols are mainly used for unique identifiers in an object. That’s a symbol’s only purpose.

There are also special symbols that we can use to implement various operations or override the default behavior of some operations.


Defining Symbols

There are some static properties and methods of its own that expose the global symbol registry. It is like a built-in object, but it doesn’t have a constructor, so we can’t write new Symbol to construct a symbol object with the new keyword.

To create new symbols, we can write:

const fooSymbol = Symbol('foo')

Note that each time we call the Symbol function, we get a new symbol, so if we write:

Symbol('sym') === Symbol('sym')

The expression above would be false. This is because every symbol is unique.


Built-In Symbols

There are built-in Symbols that are used as identifiers for various methods and values. Methods with some symbols are called when some operators are being used.

Symbol.hasInstance

Symbol.hasInstance is a method that checks if an object is an instance of a given constructor. This method is called when the instanceof operator is invoked.

We can override the Symbol.hasInstance method as follows:

class Foo {
  static [Symbol.hasInstance](instance) {
    return typeof instance.foo != 'undefined';
  }
}
console.log({ foo: 'abc' } instanceof Foo);

In the code above, we defined that an object is an instance of the Foo class if there’s a value for the foo property. Therefore, { foo: ‘abc’ } instanceof Foo should return true since it has the foo property set to 'abc'.

Symbol.isConcatSpreadable

Symbol.isConcatSpreadable is a boolean value that indicates whether an object should be flattened in an array by the array concat method.

We can use it as in the following code:

The first console.log should output:

["a", "b", "c", true, false]

And the second one should output:

["a", "b", "c", Array(2)]

This is because before the second concat call, we set arr2[Symbol.isConcatSpreadable] to false, which prevents the content of arr2 from being spread into the new array that’s returned by the concat method.

Symbol.iterator

This is a method that’s called when we want to return an iterator for the spread operator or the for...of loop. It’s called when the for...of loop is run.

For example, given that we have the following code:

const obj = {
  0: 1,
  1: 2,
  2: 3
};
console.log(obj[0]);

If you try to loop through an array with the for...of loop or the forEach function, or try to use the spread operator with it, the example with the obj object will result in an error since it’s not an iterable object.

We can make it iterable by adding a generator function with the Symbol Symbol.iterator to it like in the following code:

Then, when we iterate the obj object with the for...of loop like the code below:

for (let num of obj) {
  console.log(num);
}

We get back the entries of the new obj object that we made iterable.

The spread operator would also work. If we have the following code:

console.log([...obj]);

We get [1, 2, 3] from the console.log output.

Symbol.match

A boolean property that’s part of a regular expression instance that replaced the matched substring of a string. It’s called by the string’s replace method.

For example, we can use it to let us call the startsWith and endsWith methods with the regular expression strings:

const regexpFoo = /foo/;
regexpFoo[Symbol.match] = false;
console.log('/foo/'.startsWith(regexpFoo));
console.log('/baz/'.endsWith(regexpFoo));

The important part is that we set regexpFoo[Symbol.match] to false, which indicates that the string we called startsWith and endsWith with aren’t regular expression objects since the isRegExp check will indicate that the '/foo/' and '/baz/' strings aren’t regular expression objects.

Otherwise, they’ll be considered regular expression objects even though they’re strings and we’ll get the following error:

Uncaught TypeError: First argument to String.prototype.startsWith must not be a regular expression

Symbol.replace

A regular expression method that replaces matched substrings of a string. Called by the String.prototype.replace method.

We can create our own replace method for our object as follows by using the Symbol.replace symbol as an identifier for the method:

The Replacer class has a constructor that takes a value that can be used to replace the current string instance.

When we run the last line, we should get ‘bar’ since string has the value 'foo' and we call the replace method to replace itself with whatever we passed into the constructor of Replacer.

Symbol.search

A regular expression method that returns the index within a string that matches the regular expression. Called by the String.prototype.search method.

For example, we can implement our own Symbol.search method as we do in the following code:

In the code above, our Symbol.search method looks up if the string, which is the string that we call search on, has whatever we pass into the this.value field which we assign when we call the constructor.

Therefore, we get true from the console.log output since 'bar' is in ‘foobar'. On the other hand, if we call:

console.log('foobar'.search(new Searcher('baz')));

Then we get the value false since ‘baz’ isn’t in 'foobar'.

Symbol.species

A property that has a function as its value that is the constructor function which is used to create derived objects.

Symbol.split

A method that’s part of the regular expression object that splits a string according to the indexes that match the regular expression. It’s called by the string’s split method.

Symbol.toPrimitive

A method that converts an object to a corresponding primitive value. It’s called when the + unary operator is used or converting an object to a primitive string.

For example, we can write our own Symbol.toPrimitive method to convert various values to a primitive value:

Then we get:

10
hello
true
false

From the console.log statements at the bottom of our code.

Symbol.toString

A method that returns a string representation of an object. It’s called whenever an object’s toString method is called.

Symbol.unscopables

An object whose own property names are property names that are excluded from the with environment bindings of the associated objects.


Conclusion

Symbols are a new type of data that was introduced with ES6. They are used to identify the properties of an object. They’re immutable and every instance is considered different, even though they may have the same content.

We can implement various methods identified by special symbols to implement certain operations like instanceof, converting objects to primitive values, and searching for substrings, in our own code.

Categories
HTML JavaScript

Introduction to HTML Canvas

One way to display graphics is to use the img element in HTML. However, that only displays static images with a fixed URL. To draw and display dynamic graphics, we can use the HTML canvas element.


Creating a New Canvas

To create a new canvas element:

<canvas style='width: 200px; height: 200px'>
</canvas>

It looks like the img element, but it has no src or alt attributes. This is because it’s not a fixed image element.

We can style with CSS as we did above, with width , height , margin, border , padding , etc.

Fallback content

For browsers that don’t support canvas, we can supply fallback content by putting something inside. For example, we can write:

<canvas style='widthL 200px; height: 200px'>
  Your browser doesn't support canvas.
</canvas>

The closing tag </canvas> is required for canvas elements. If it’s not present, the rest of the document will be considered fallback content.


Rendering Context

The canvas element creates a fixed-size drawing surface that exposes one or more rendering contexts — entities to create and manipulate the content drawn.

The most basic is the 2D rendering context. There’s also a 3D rendering context for WebGL and OpenGL ES.

A canvas is initially blank. We have to access the rendering context and draw on it to display something. To do this, we can use the getContext() method of the canvas element. For 2D graphics, we specify '2d' into the getContext() method.

We access the canvas rendering context as follows:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

Checking for Support

We can check for support for the canvas element by checking if the getContext method exists, as follows:

const canvas = document.querySelector('canvas');
if (canvas.getContext) {
  const ctx = canvas.getContext('2d');
}

This should be less of a concern these days since almost all modern browsers support the canvas element.


Basic Code

Put it together and we have the following code. The HTML:

<canvas>
  Your browser doesn't support canvas.
</canvas>

Then we can add the following CSS:

canvas {
  width: 200px;
  height: 200px;
  border: 1px solid black;
}

Finally, we have this JavaScript code:

const canvas = document.querySelector('canvas');
if (canvas.getContext) {
  const ctx = canvas.getContext('2d');
}

A Simple Drawing

The simple drawing is made up of basic 2D shapes, like rectangles. We create three rectangles with different background colors with the following code:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(100, 0, 0)';
ctx.fillRect(5, 5, 40, 40);

ctx.fillStyle = 'rgba(0, 20, 100, 0.5)';
ctx.fillRect(10, 10, 50, 50);

ctx.fillStyle = 'rgba(20, 0, 200)';
ctx.fillRect(25, 25, 95, 90);

It works as follows. After we get the rendering context, we set the background color of the shape with the fillStyle property by setting it a string with the color value. Then we create a rectangle with the coordinates (5, 5) for the top left corner and (40, 40) for the bottom right corner.

The first two arguments are the x and y coordinates of the top-left corner, the last two are the width and height.

The first rectangle is:

ctx.fillStyle = 'rgb(100, 0, 0)';
ctx.fillRect(5, 5, 40, 40);

The color value rgb(100, 0, 0) represents a brownish color.

Likewise, we have:

ctx.fillStyle = 'rgba(0, 20, 100, 0.5)';
ctx.fillRect(10, 10, 50, 50);

This rectangle is to the right and lower than the first. It has a grayish color.

Finally, we have:

ctx.fillStyle = 'rgba(20, 0, 200)';
ctx.fillRect(25, 25, 95, 90);

This one is again to the right and lower than the second rectangle, in blue.

In the end, we get the following:

The drawing is finished once the page with the canvas element has loaded. The coordinates can be outside or inside the rectangle’s dimensions. If it exceeds the dimensions, we won’t see the stuff that’s drawn.

The canvas is useful to draw graphics, whether static or dynamic. We can create a canvas element in HTML, then we can get the canvas element in JavaScript and get the rendering context so we can draw items on it.

We can draw basic shapes on it. We can change the colors of the background with the fillStyle property of the context, then can call the fillRect on it to draw a rectangle.

It takes four arguments: The x, y coordinates of the top left corner for the first two arguments and the x, y coordinates for the bottom right corner for the last two elements.

Categories
TypeScript

Introduction to JavaScript Inheritance

JavaScript is an object-oriented language. However, it’s different from many other OO languages in that it uses prototype-based inheritance instead of class-based inheritance.

Prototype-based inheritance means that objects inherit items from its prototype. A prototype is just another object, which can be inherited by other objects.

This is different from class-based inheritance in that classes are templates for creating new objects. Classes can inherit from other classes to reuse code from the class it’s inheriting from.

Old Syntax of Inheritance

Constructor Functions

Before ES6, we only have constructor functions to serve as templates to create new objects which are instances of the constructor.

For example, we can define a constructor function as follows:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Then we can create a new instance of Person by writing:

let person = new Person('Joe', 10);

To inherit items from other constructor functions in a constructor function, we have to call the parent constructor function that we want to inherit from with the call method, and then set our constructor’s prototype’s constructor property to the parent constructor function that we want to inherit from.

For example, if we want a Employee constructor function to inherit the properties of the Person constructor, we can write:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

function Employee(name, age, title) {
  this.title = title;
  Person.call(this, name, age);
  this.__proto__.constructor = Person;
}

let employee = new Employee('Joe', 20, 'waiter');
console.log(employee);

The call method takes the value of this we want to set, and the rest are arguments we pass into the function that the call method is called on.

If we look at the __proto__ property of the employee object, which has the prototype for it, we should get that __proto__.constructor of it should be the Person constructor like we set it to.

The properties and the values of the employee object should be what we passed into the Employee constructor when we called it.

Object.create()

The Object.create() method is another way to inherit from a prototype when we create an object.

The argument that it takes is the prototype object that we want the object returned from it to inherit from.

For example, we can use Object.create to create an object with a prototype as follows:

const person = {
  name: 'Joe',
  age: 20
}

let employee = Object.create(person);
employee.title = 'waiter';

console.log(employee);

If we look at the employee object, we’ll see that the __proto__ property will have the age and name properties set with values.

Setting the proto Property Directly

Setting the __proto__ property directly has been officially supported since ES6 and it’s an undocumented way to set the prototype of an object in various browsers before it like Firefox.

We can set an object to the __proto__ property directly, by writing something like:

const person = {
  name: 'Joe',
  age: 20
}

let employee = {
  title: 'waiter'
};

employee.__proto__ = person;
console.log(employee);

We should get the exact structure of the properties and values as we did when we created an object with the Object.create() method.

One thing we have to be careful about is that we don’t want to accidentally set it if we don’t want to change an object’s prototype. This may happen if we use JavaScript objects as maps. With ES6, we can use the Map object for this purpose.

Object.defineProperty

We can also use the defineProperty method to set the prototype of an object. For example, we can write:

const person = {
  name: 'Joe',
  age: 20
}

let employee = {
  title: 'waiter'
};

Object.defineProperty(employee, '__proto__', {
  value: person
});
console.log(employee.__proto__);

When we log the value of employee.__proto__ , we get back the person object.

Note that the prototype is in the value property of the 3rd argument of the defineProperty method call.

Photo by Chiara Daneluzzi on Unsplash

New Class Syntax

With the release of ES6, the new class syntax is introduced. On the surface, it looks like we have class-based inheritance, but underneath the surface, it’s exactly the same as before.

The class syntax is the same as constructor functions. For example,

function Person(name, age) {
  this.name = name;
  this.age = age;
}

is the same as:

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

We can instantiate both by writing:

const person = new Person('Joe', 10);

And we get the same object when we inspect its properties.

The class syntax also creates a clear and convenient way to do inheritance that looks like a traditional class-based inheritance.

We can create a super-class and a child class can inherit from it with the extends keyword. For example, we can write:

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

class Employee extends Person {
  constructor(name, age, title) {
    super(name, age);
    this.title = title;
  }
}

const employee = new Employee('Joe', 20, 'waiter');

In the code above, we have the extends keyword to indicate which class Employee inherits from. We can only inherit from one class.

The super method is called to call the parent constructor and set its’ properties. In this case, calling super will call the constructor method in the Person class.

this refers to the class that it’s inside in each class.

This is exactly the same as what we did before:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

function Employee(name, age, title) {
  this.title = title;
  Person.call(this, name, age);
  this.__proto__.constructor = Person;
}

let employee = new Employee('Joe', 20, 'waiter');
console.log(employee);

The only thing is that when we inspect the employee object, we get that the __proto__.constructor property shows class instead of function .

The class syntax makes inheritance much more clear than before. It’s much needed syntactic sugar for the prototypical inheritance model that’s in JavaScript since the beginning.

Also, with the class syntax, we don’t have to call the call method on the parent constructor object and set this.__proto__.constructor anymore.

It’s better than using the Object.create() or setting the __proto__ property directly. Setting the __proto__ property has its problems like accidentally setting the wrong prototype.