Javascript: Objects, Functions, and Event Loops
by J Adrian Zimmer
Author's email: jazimmer@BonsaiReads.com.
Published by Bonsai Reads and distributed by Amazon.
Cover Design: J Adrian Zimmer
Copyright 2017 by J Adrian Zimmer
All rights reserved. Permission to copy is granted to the purchaser for personal use provided purchaser takes reasonable steps to prohibit further copying by others.
Edition: 1.0
There are two tables of contents. One is an annotated list of sections. The other has a listing for every major code segment.
Annotated List of Keywords
Javascript
For Javascript programmers who are ready to learn something more about how things work.
Objects
Javascript is object oriented, but not class oriented.
Functions
Javascript functions are callable objects.
Event
Events from outside the Javascript system cause handler functions to be queued for later execution.
Event Loop
Event loop processing chooses queued functions one by one for execution. Functions are usually, but not exclusively, queued as a response to an outside event.
Macrotask queue
Think of the macrotask queue as the event-handler queue.
Microtask queue
Think of the microtask queue as the me-first queue.
Promises
Promises handle asynchronous requests, sequencing follow up actions on the me-first queue.
Pseudo Classes
Javascript's clever use of new makes an object-based language look class-based.
Annotated List of Sections
A quick look at the role of prototypes in object inheritance chains.
Functions are callable objects which inherit their function characteristics.
A webpage template for our example scripts.
Making use of an event handler.
Setting up two independent repeating processes.
Eliminating setTimeout from repetitive processes.
Adding a state to writeMessage and setColor .
How promises decouple the steps of a process while making use of a me-first queue.
Independent repeating processes with promises.
Two examples in which promises manage responses to outside events.
Implementing the hesitating factory method.
How the new operator fakes classes.
Preface
Javascript: Objects, Functions, and Event Loops is not an introductory book nor does it go into lots of detail. Rather it goes into depth about a few concepts whose Javascript variations confuse many programmers, namely objects, functions, promises, event loop programming, and the way Javascript fakes classes. The intent is to provide a solid base on which to continue building your understanding of Javascript. To that end, each section contains a single exercise which you should attempt before paging ahead to the answer. Even if you do not finish the exercise, the attempt will make the answer more meaningful and later sections more intelligible.
It is assumed that you already know some Javascript and are familiar with class-based object orientation as found in languages such as Java and Python.
This ebook has a Github repository where you can find downloadable copies of the answers to exercises. It also contains two useful factory methods.
Be aware that the formatting of scripts and interactive sessions in this ebook is not meant to be exemplary. Rather it is meant to produce short lines so that the scripts can be read more easily on small screens.
You can recognize interactive sessions because they have lines beginning with > . They are transcribed from the Node.js interpreter but the transcriptions have many appearances of undefined removed. For example
> var x = 'hi'
undefined
> console.log(x)
hi
undefined
is transcribed merely as
> var x = 'hi'
> console.log(x)
hi
Both var and console.log actually return undefined but to see that in the transcript is confusing because we do not think of them as returning anything.
I. Object Inheritance
A counting object in Javascript might be defined this way
var counter = {
val: 0,
incr: function() {
this.val += 1;
return this.val
}
}
Do not confuse this with a class. It is an object. As you will see, it can inherit from other objects in much the same way that classes can inherit from other classes. But it is nevertheless an object.
Both val and incr are properties of the object. You can see that one represents an integer and the other a function. The property incr would normally be called a method. Methods can be assigned this way because functions can be assigned to variables and properties. They can be passed as arguments and can serve as return values. In other words they are first class . (Yep, the class in first class is different than the object-oriented class.)
Javascript has a built-in object named Object whose methods help programmers manipulate objects. Two example methods are getOwnPropertyNames and getPrototypeOf . When applied to counter these functions produce
> Object.getOwnPropertyNames(counter)
[ 'val', 'incr' ]
and
> var getP = Object.getPrototypeOf;
> getP(counter) === Object.prototype
true
To get own property names means to get the properties that are in the object itself and not those inherited from other objects.
The getPrototypeOf method returns the immediate predecessor of its argument in an inheritance chain. You can think of this as the super object. Often it is referred to as the [[Prototype]] of an object.
Many objects have a property named prototype . As you will see prototype s become [[Prototype]]s of other objects. They are not the [[Prototype]]s of the objects to which they belong. In some cases they may not be [[Prototype]]s of any object.
For example Object.prototype becomes the last object in the inheritance chains of most other objects. So most objects have access to a toString method because toString is present in Object.prototype .
There are other useful functions in Object . One I will make use of is Object.create which can create an empty object that has a designated [[Prototype]]. In particular this expression
Object.create{obj}
creates a new empty object whose [[Prototype]] is obj .
Question
Implement counter as above and then
- create counter2 which inherits from counter and adds a decr method which decrements val by 1.
- check to see what each of
Object.getOwnPropertyNames(counter2)
Object.getOwnPropertyNames(counter)
returns. The answer isn't completely apparent from what has been said, so experiment a bit.
Answer
Create counter2 this way
var counter2 = Object.create(counter);
counter2.decr = function() { this.var -= 1 }
The own properties of counter are of course
> Object.getOwnPropertyNames(counter)
[ 'val', 'incr' ]
However the order in which you see them will be depend on how the Javascript engine is implemented.
If you didn't get two different answers for the own properties of counter2 , you missed something. Things change when you execute incr or decr .
Upon creation
> Object.getOwnPropertyNames(counter2)
[ 'decr' ]
but after either of counter2.incr or counter2.decr has executed, you will get
> Object.getOwnPropertyNames(counter2)
[ 'decr', 'val' ]
The reason is that counter2 can fetch data values from counter through inheritance but it cannot alter them. When alteration is necessary a new property in counter2 is made. After that, fetching from counter2 will be of counter2 's property not its original in counter .
This means that counter can be used to give an initial value to any object for which it is a [[Prototype]].
II. Functions
Functions are callable objects which means:
- they are objects containing the function body (probably in compiled form).
Next page