0 ratings 0% found this document useful (0 votes) 14K views 199 pages Javascript On-Demand Dictionary
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content,
claim it here .
Available Formats
Download as PDF or read online on Scribd
Go to previous items Go to next items
Save Javascript On-Demand Dictionary For Later JS
Deco eae cee ss
ultimate reference guide that unlocks the
complex world of JavaScript programming,
Pee ed ere
develapers, this book provides a comprehensive
Pe ee ee eee ae!
terminologies, and essential concepts in
JavaScript, presented in an accessible and easy-
Pen eC Raa
CoC Sead
DU eat
JAVASCRIPT
ON-DEMAND
DICTIONARY
The uitirmate reference guide thot unlocks the complex
eerContents
1
audience: who is this book for 1
how to read this book 1
special thanks 1
technical editor 1
the author 2
what this book is about 2
what this book is not 2
debug 3
comments 3
operators 3
parenthesis 4
brackets 4
references 5
variables 5
constants 6
types 6
invoke 8function declaration VS function expression 8
named function expressions 9
scope 10
private and nested scope 10
context 11
global context 12
method context 13
invoking a function via call or apply 14
explicit context 15
arguments 16
Array and generic collections iteration 18
for loop 18
incremental++operator 19
Array methods 21
array.forEach(callback, context) 21
array.map(callback, context) > newArray 22
array.filter(callback, context) - newArray 23
array.some(callback, context) + boolean 23
array.every(callback, context) > boolean 24
array.indexOf(value, fromIndex) = number 24
prototype and prototypal inheritance 25
genericA.isPrototypeOf(genericB) > boolean 26Object.prototype 27
object.toString() > string 28
native 29
class 30
constructor 31
instance 32
inheritance 33
the in operator 34
for/in loop 34
enumerable 35
object.propertyIsEnumerable(name) > boolean 35
object-hasOwnProperty(name) > boolean 36
shared properties 36
getters and setters 38
descriptors 40
Object.defineProperty(obj, name, descriptor) > obj
40
try catch finally 42
which descriptor for what 43
common property descriptor 43
common class and native method descriptor 44
common defensive method descriptor 44common lazy property descriptor 44
Object.getOwnPropertyDescriptor(obj, name) -
desc 45
Object.defineProperties(obj, descriptors) > obj 46
delete 46
Object.getOwnPropertyNames(obj) > arrayOfAll-
Names 47
Object.keys(obj) > arrayOfOwnEnumerableNames
47
public and public static 47
extends 49
super 50
implements 51
interfaces 51
trait and mixin 52
if else switch and conditional logic 53
conditional statement 53
ternary operator 54
switch statement(zead as oR) 95
logical|joperator 55
logical&&operator(tead as AND) 5
truthy and falsy values 57antipattern 57
DOM 57
tree 58
Web IDL 59
EventTarget registration interface 59
void 60
DOMString 60
EventListener 60
EventListener using a function 62
function bind 63
Event 64
browser events 65
bubbling and capturing 65
event.stopPropagation() 66
event.preventDefault() 67
CustomEvent 67
EventEmitter 68
signature 68
parameters 69
node.js events 69
WeakMap 70
Symbol 71primitives 71
Object.getOwnPropertySymbols(obj) > arrayOf-
Symbols 72
shared Symbols 72
special Symbols 73
for/of loop 73
fat arrow 73
generator 74
yield 75
generator.next(value) > {done:boolean, value:any}
76
generator.throw(error) 77
Promises 77
promise.then(resolved, rejected) > newPromise 79
promise.then(resolved).catch(anyError) > new-
Promise 79
promise.then(fn).then(fn).then(fn) > newPromise
80
Promise.all(arrayOfPromises) > newPromise 80
Promise.resolve(value) > newPromise 81
Generators and Promises 82
Timers 84setTimeout(fn, delay, arg1, arg2, argN) ~ timerlden-
tifier 84
clearTimeout(timerlidentifier) 84
setInterval(fn, delay, arg1, arg2, argN) > timerIden-
tifier 84
clearInterval(timerIdentifier) 85
requestAnimationFrame(fn) ~ rafIdentifier 85
process.nextTick(fn) 86
requestIdleCallback(fn, waitExpiresIn) > ricIdenti-
fier 86
template strings 87
tagged template strings 87
regular expression 88
JSON 89
Math 89
parselnt(string, base) > integerNumber 89
parseFloat(string) > floatNumber 89
Recent ECMAScript features 90
let declaration 90
rest parameters 91
spread operator 91Map 91
Set, and WeakSet 92
Proxy 92
destructuring 92
JavaScript F.A.Q. on demand 93 Useful links 94
audience: who is this book for
For absolute beginners or more advanced develop-
ers, this book explains the most common terms used
in JavaScript programming, client or server, through
examples.
If you cannot understand technical articles, this
book will explain each term. If you are looking to re-
fresh and update your knowledge about modern ter-
minology, patterns, and their applications, this book
will also help you.how to read this book
This book could somehow be compared to a wa-
terfall: it starts quietly, by describing simple basic
terms, and then accelerates until it covers most
modern features towards the end.
Being a compact book I recommend you do a quick
read-through first, and once completed, go back to
any specific words, so that every term is clear.
special thanks
To every person that believed in me and helped me
with this idea.
In particular: Robert Woloschanowski, Stoyan Ste-
fanov, Arianna De Mario, Cinzia Giammarchi, Maria
Teresa Sardella, Luca Vavassori, every member of the
TC39 and the ECMAScript Mailing List who in allthese years has been patient enough to deal with my
questions and rants.
technical editor
A special thanks goes to Stoyan Stefanov, who is the
author of JavaScript Patterns, Web Performance Day-
book Volume 2, JavaScript for PHP Developers and
others O’REILLY best sellers, helped me reviewing
content as well as code and examples.
the author
Andrea Giammarchi is an experienced Web and Mo-
bile Development consultant, formerly a Senior Soft-
ware Engineer at Twitter, previously at Facebook,
NOKIA, and others.
what this book is about
Many online articles, as well as many other books,take for granted that the reader knows the meaning
of every single term used to describe generic soft-
ware related topics.
The truth is that there are many people that would
like to understand “what the heck” is all this pro-
gramming about, the same people that might stop
reading the article, or feel confused, the very mo-
ment they come across terms such as variable,ref-
erence,context,scope,object, and so on. While I can
instantly assure everyone that programming is not
always trivial, and it’s surely not something you
can possibly learn overnight, or maybe just reading
a couple of books, I also strongly believe one really
shouldn't need a degree in Computer Science to un-
derstand basic articles that, for example, simply use
some JavaScript to click a button to show analert...
... and “what is an alert?“ It’s a modal window witha
warning message and an OK button.
... and “what does modal mean?” It means it blocks
the interaction with the program.Do you see how many questions already? And the
more we describe, the more we understand, the
more other terms come up, needing more answers
and more explanations.
Well, this is why I’ve written this “JavaScript glossary
on demand”, hoping that you won't feel disoriented
ever again while reading online articles, or other
more advanced books.
what this book is not
Every single term in this book could require a
book of its own to describe all its glory, history, or
“gotchas”. JavaScript (JS) has been around for more
than 20 years now, and while I’ve tried to keep
things as simple as possible, the aim is to explain
modern JS first, since it’s daily JS that you want to
learn, and not the one from the 90’s. My apologies in
advance if some descriptions are not absolutely per-
fect. You are the one in charge of any deeper investi-
gation if needed. So ... shall we?debug
It’s the basis, because it’s what we need whenever
we write code and we want to know if such code
succeeded or failed. This verification procedure is
known as “debugging”, for the simple reason that it’s
usually performed through a “debugger”, which is a
developer’s helper tool that most modern browsers
provide.
Just try to “right click” on any webpage, and see if
there is “inspect element” as the last option of the
menu. This is how you can test all examples in this
book: click “inspect element” and then the button or
tab called “console”, and start writing in it pieces
of code, also known as “snippets”, while we walk
through the examples.
As an alternative, you could also use the node.js
command line interface, since most examples are en-vironment agnostic, which means these will work in
every browsers as well as servers.
Every code example contains some grayed out com-
ments, I strongly suggest you read all of them at least
once, and focus on the actual programming after-
wards.
comments
In programming, comments are meaningful de-
scriptions of the code itself. They are ignored during
code execution, and can be// single line, ending when
a new line is encountered, or/* multi line */
operators
If you take a calculator, you can see numbers and
arithmetic operations on it.
In programming it’s basically the same, there
are arithmetic, comparison, assignment,conditionaland other operations. We can use them right away in
any console.
// let's do some math
1+ 2;// shows 3
3*5;// shows 15
1-2;// shows -1
While in a calculator the sign =-means “show the re-
sult”, in JavaScript it means “assign the result”. You
can use the=sign to hold some results to be reused
later on.
var result = 3 * 7; result; // shows 21
If you want to compare two different values, you can
use the triple equal operator===
2 2; // true > of course, same number, it's identical to
itself 2 === 3; // false > well, 2 is different from 3 so it cannot
be the same
To verify that two values are different, you can use
the “not” version.
2!==2;// false > 2 is 2 so these cannot be different 2 !==3;//
true > of course 2 is different from 3. It's 2!The!”not” operator can be used to negate some log-
ical condition, by inverting its value. For instance,!
true === falseand vice-versa.
If you want to state that different values are in fact
the same, you can use logical operators.
(4+ 5)===(5 + 4) && (2 x 3) === (3 x 2); // true > commuta-
tive property
There is an entire section about these operations fur-
ther in the book so let’s keep focusing on terminol-
ogy for now.
parenthesis
It is possible to group different sequences of opera-
tions via parenthesis. These become instantly more
readable, making the developer’s intent clear.
As an example, if one read an operation such as 2* 3
+ 4one would think that the result is 10. Instead, you
actually meant to multiply the sum of3and4byz2, and
to make it clear to both your eyes and the JavaScriptprogram interpreter, you should write2 « (3 + 4),
which drops all doubts about the result.
Often referenced as parens for short, parenthesis are
also used as part of functions syntax, which is de-
scribed later on.
brackets
In JavaScript there are curly brackets {}, or braces for
short, and square brackets[]. These can be used to
create objects and, in the square brackets case, also to
access their values.
var obj = fhello: 'world'};// generic reference to an object
var arr = ['a', 'b', 'c']; // generic reference to an Array object
arr[0]; // shows the letter ‘a’
obj-hello; // "world"
// * could be accessed via obj["hello'] too
references
A reference is like a symbolic link that points to aspecific value. Think of a selfie, the photo can be con-
sidered as a reference to a generic person: you don’t
need to have this person present in the room to see
what she looks like or what she is doing, the photo is
enough.
variables
A variable is usually a meaningful name used to ref-
erence a generic value. Back to the example of the
selfie,var myPhoto = new Selfie();creates a reference to
my selfie whose name is myPhoto. I can keep it for
me, send it around as a postcard, receive other selfies
from other people, and reassign its value at any time.
// create a variable that references my selfie var myAvatar =
new SelfieQ);
// ... 5 years later ...
// save the old picture
// by using a new variable name var oldMe = myAvatar;// then shoot a new selfie
// simply reassigning it to the same variable my Avatar = new
Selfie();
Acommon JavaScript convention for variable names
is var camelCase = anyValue;starting always with the
lower case, and eventually putting together multiple
words through uppercase letters.
If the composite variable name contains single char-
acters or acronyms in it, it is OK to put together mul-
tiple uppercase letters.
// common naming conventions examples var thisIsAGood-
NameForAVariable = anyValue; var result = loadSDK();
object.genericProperty = genericValue;
constants
A constant is like a variable but can only be created,
and assigned, once. In modern JavaScript engines, it
can be explicitly created through the keyword const.// instead of var MY_CONSTANT = 'staticValue'; const MY_
CONSTANT = 'staticValue'’;
// it does not change its value MY_CONSTANT = 'nope';
MY_CONSTANT; // shows "staticValue"
Their common naming convention in most popular
programming languages is the following:EVERY-
THING_IN_UPPER_CASE_WITH_UNDERSCORE_BE-
TWEEN_WORDS
These kind of variables are frequently, but not ex-
clusively, used to describe data which do not ever
change and have a fixed value (usually well known),
such as the force of gravity or the temperature at
which water boils (see the example below).
if (room.temperature >= WATER_TEMPERA-
TURE_RIGHT_BEFORE_STEAM) { console.log('too hot’);
} else if (room.temperature <= WATER_TEMPERA-
TURE_RIGHT_BEFORE_ICE) { console.log('too cold’);
}
types
When a variable that references a value is created,it can be assumed that this value has a type. Back
to thevar myPhoto = new Selfie();example, you could
say that the type of the variable myPhotowould be
“photo”, which describes more or less what one can
do with it: look at it, share it, trash it, draw creepy
things on top of it via some photo editor, etc. In
JavaScript the “photo” type doesn’t exist, but there
are few others you can consider.
To obtain the type of a generic reference you can
write:typeof myReferencedVar
boolean represented by two possible values:trueand-
false.
number represented by integers such aso,1,2,-30r
floats likeo.9,1.2,-11.7 and a few special cases such as-
InfinityandNan *
*NaN means ”Not a Number”, but how could a number be considered not
a number? Think about the result of 0/0
string represented by anything within single or
double quotes:'I am a string' and "so am I'are indeed
both valid strings. Most modern JavaScript engines
support also backtick enclosed strings such as * thisone’ which is also a string but with some special
powers.
undefined represented by the absence of a value. By
default, there is a global reference to such absence
named undefined. Its absent value is the exact equiva-
lent of a variable declaration that does not reference
to any value:
var novalYet;
console.log(noValYet === undefined); // shows true
Please bear in mind that JavaScript has a value that
explicitly represents nothing. Such value is actu-
ally a reserved, constant-like, keyword namednull.
Thenullvalue is also the implicit root of every JS ob-
ject and its type is “object”.
object represented mostly by curly {} or square []
brackets. Objects are containers for key/value pairs
(also described as properties where each key would
be a property name and each value would be a prop-
erty value). When it comes to square brackets [],
the object can also be called Array and its propertynames are commonly represented by integer indexes
(indices).
// create two variables, one Object and one Array
var obj = {aKey: 'a value’, bKey: 123};// typeof obj === 'object'
var arr = ['some value', 456]; // typeof arr === ‘object’
// read an Object property
console.log(obj.aKey); // ‘a value’ // read an Array element by
its index console.log(arr[0]); // ‘some value’
function represented byfunction name(a,b) { return; }
syntax, or in modern engines by()=>{}. Functions are
special objects that can be “invoked”. symbol only in
modern JS engines, it can be used as special “object”
property.
invoke
In JavaScript, this term is related to a specific opera-
tion: executing any sort of function reference using
parenthesis:
// declaring a function function tellMeSomething() { con-
sole.log('something’); }// tellMeSomething is the reference name
// of the function we have just declared
tellMeSomething; // nothing happens (just shows the func-
tion itself)
// to “execute” this function
// we need to invoke it using parenthesis tellMeSome-
thing(); // logs ‘something’
If you look carefully, you can see that even the oper-
ation console.log('something’); is invoking a function.
However, in such a case the log function is invoked
through aconsoleobject reference instead of directly,
and it’s accessed using a “dot notation”.
Every time a function is invoked after a dot, that
function can be considered a “method”.
function declaration VS function expression
There are a few ways to define a function and each
might be more or less convenient.
A function declaration, for example, creates a refer-ence available everywhere within the “scope” it has
been declared, even if invoked before.
// invoke it even before it's declared readyJack(); // works as
expected
function readyJack() {
console.log('I was born ready’);
}
This can help you organize code in separate blocks.
But it can also be confusing if there are many dec-
larations in various different parts. Since it’s a good
practice to declare all needed variables together,
function expressions might be a better fit.
var name = ‘Jack’;
// function expression referenced via readyJack variable var
readyJack = function () {
console.log(name + ' was just an expression’); };
Just like every single variable declaration should end
with a semicolon, when assigned to a variable func-
tion, expressions should also end with a semicolon.
Semicolons are not needed when it comes to func-tion declarations, as shown in the previous example.
Remember: function expressions cannot be exe-
cuted before they are defined.
named function expressions
To simplify our own debugging, it’s a good practice
to give functions a name, even if there is a function
expression and a reference to it.
var anonymous = function () {};
var named = function helloThere() {};
console.log(anonymous.name); // empty string con-
sole.log(named.name); // logs 'helloThere'
It must be said that modern debuggers are smart
enough to tell the reference name anyway, but it’s
good to know that you can create function expres-
sions with a name at runtime.
This is particularly handy when you want to imme-
diately invoke the function itself
* procedure also known as IIFE: Immediately Invoked Function Expres-sion
(function areWeThereYet(tenSteps) {
if (tenSteps === 0) {
console.log(‘finally arrived’);
Jelse {
console.log(‘yet another step’);
// use the function name to invoke itself // passing the de-
creased count
areWeThereYet(tenSteps — 1);
}
}(10)); // the count in this case starts at 10
scope
This term indicates the boundaries in which the
code is executed. Think of it as the Universe is every
galaxy’s scope, the Milky Way is our solar system’s
scope, the solar system is planet Earth’s scope, planet
Earth is all continents’ scope, and for each continent
we are going to have countries, regions, cities, coun-
cils and finally your own house, which is your ownscope while you are inside it, while the rest of the
city will be your scope when you get out.
In JavaScript, by default there is a global scope in
which you can define functions and variables. How-
ever, back to the house metaphor, you don’t want
each neighbour to know about every single thing
you do in your place: your home is your place, and
functions, in JavaScript, are the way to define your
very own place without interfering, or being dis-
turbed, by everything that happens in the middle of
the street, or anywhere else, including other houses.
// global scope starts before JS code is executed (it's already
there) // function ‘myHouse* scope starts here
function myHouse(sco, ped, args) {
// defining a variable inside ‘myHouse* makes it available
only here var myMess = 'my own room';
} // function *myHouse’ scope ends here
typeof myHouse; // is the ‘function’ * myHouse~
typeof myMess; // is 'undefined' because it's unknown in this
scopeprivate and nested scope
Since it is possible to create functions inside other
functions, it is also possible to have a private scope
within a function that is already private, like a room
within the house.
To create a private scope, we can use the previously
seen JJFE approach without naming our function ex-
pression.
// anonymous IIFE
(function () {
var myPrivateScope = 'a string value’;
console.log(typeof myPrivateScope); // ‘string’
30);
console.log(typeof myPrivateScope); // ‘undefined’
By having an anonymous function expression that
invokes itself, you can be absolutely sure that no-
body outside that function can be able to interferewith your code. Moreover, you can define other func-
tions in it, and create nested scopes.
(function (){
var who ='Iam';
var nestedExpression - function () { // nested function ex-
pression scope
var nested = who + ‘expression’; return nested;
hi
function nestedDeclaration() { var nested = who + 'declara-
tion’; return nested;
}
console.log(nestedExpression());
console.log(nestedDeclaration()); }());
// nested function declaration scope
//'Tam an expression' // ‘Iam a declaration'
It is important to remember that nested scopes can
always access their outer scope variables or refer-
ences but never vice-versa. This is why it is possible,
for both function expression and declaration in the
previous example, to use the who reference while ex-ecuting. However, it wouldn't be possible for the pri-
vate outer scope to reach the nested variable defined
inside each nested function: these are reachable only
via their own function scope. The reason we want
to use private scopes when defining our own vari-
ables, and the reason we create functions at all, is to
prevent conflicts with any other variable name that
could possibly be already present in our application.
It is also a way to automatically clean up or free
memory once we have completed the task the func-
tion is supposed to solve.
context
Every time a function is invoked, it is possible to
reference its current execution context through the
automatically availablethisreference, which has one
of the following values:
+ the global program context, called windowin
browsers andglobalon server
+ the genericobjobject that invoked the functionthrough the dot notation: obj.method()
+ an arbitrary explicit value, includingundefined,
when invoked via function methods like.callor.apply
global context
If you open your browser console, or start node
js, you can inspect the global context writingcon-
sole.log(this);or simplythis.
Whenever you define a variable or declare a function
globally, you are also able to reference these vari-
ables through the global context, since it is just like
an object.
// create a variable directly in the global scope var globally-
DefinedVariable = 'can everyone access me?'; // it's accessi-
ble through the global object
console.log(this.globallyDefinedVariable);
// the same when you create a function function globallyDe-
claredFunction() { return globallyDefinedVariable; }
console.log(globallyDeclaredFunction());It is also possible to define global variables inside a
generic function by accident, by simply omitting the
varkeyword before assigning a value to a reference.
console.log(typeof a); // ‘undefined’
function myScope() {
a= 123; // instead of var a= 123;
}
myScope();
console.log(typeof a); // ‘number'
console.log(a); // 123
To prevent accidental global scope and context pol-
lution, the 5th version of the ECMAScript specifica-
tion (the standard that defines JavaScript semantics,
syntax and behavior) introduces a special"use stric-
tydirective.
This string, if placed at the beginning of a function,
will guard the global context and switch into a more
strict behavior. If you try the previous code again,
you will see an Error instead of the number 123.console.log(typeof a); // ‘undefined’
function myScope() {'use strict’; // switch local scope to strict
modea= 123;
}
myScope(); // shows an Error
console.log(typeof a); // still ‘undefined’
Not only it’s impossible to define variables in the
global scope by accident, but when this directive
is used, the execution context will also beundefined,
unless explicitly provided.
// defined in the global scope
function wholsThis() f'use strict’; return this;}
wholsThis(); // undefined
this.wholsThis(); // the global context
method context
In JavaScript objects can have properties of any kind
and functions are no exception.// create an empty object
var obj = {};
// define a property as function expression
obj.somePropertyName = function () {
return this ;
hb
// what would be that returned context value? // let's figure
it out by invoking obj.somePropertyName obj.someProperty-
Name(); // exactly the obj itself
When a function is invoked through an object, it im-
plicitly uses this object as its current execution con-
text. It is important to remember that any function
can be attached to any object at any time, even if it is
not directly defined as a property of that object.
// generic function defined here or somewhere else function
sayTheName() { console.log(this.name); } // generic object
var me = {};
// with a name property and 'Andrea' as value me.name =
‘Andrea’;// function sayTheName attached as 'whoAmI' property
me.whoAml = sayTheName;
// so we can invoke it as method me.whoAml(); // ‘Andrea’
Even though it is not such a good idea to attach
methods at runtime, the fact that we can borrow
functions of any kind and use them as methods in
different objects is nonetheless an amazing feature.
“Why would we need that” is more than a legit ques-
tion, and the answer is that, for example, each collec-
tion of items does not necessarily have all methods
like a regular Array. Online it is indeed possible to
find some code examples similar to the following:
// COUNTEREXAMPLE
var allNodes = document.querySelectorAll(™); // borrow
the forEach method from an empty Array allNodes.forEach =
[|.forEach;
// iterate over all nodes using the method allNodes.forEach(
function (node) {
console.log(node.nodeName);
DsAs already mentioned, modifying objects one didn’t
create is a very dirty approach, even if it is possi-
ble. As an example, if we take someone for a ride in
our shiny new car, we don’t want them to leave food
crumbs and dirt all around. It wasn’t there when
they got in, why should it be now!
Good news: there are better and cleaner ways to in-
voke a function by providing a context.
invoking a function via call or apply
As described in the types paragraph, functions are
special objects that can be executed. Just like any ob-
ject, functions can also have properties, hence meth-
ods.
The most commonly used methods of any function
are .call(and .apply(), which only differ in that while.
callaccepts an arbitrary amount of arguments to
pass along,.applyaccepts only an Array to be used as
invocation arguments.// three functions that log some information
function fnwithNoArguments() { console.log(‘nothing to
do here’); } function fnWithOneArgument(first) { con-
sole.log(‘received', first); } function fnWithTwoArgu-
ments(a, b) { console.log(‘received', a, b); }// using call and
ignoring the first context value for now, using nullW fnWith-
NoArguments.call(null);
fnWithOneArgument.call(null, ‘some value’);
fnWithTwoArguments.call(null, ‘first value’, ‘second
value’);
// to use ‘apply’, you need one or more Arrays Var empt-
yaArray = [];
var arrayWithOneArgument = ['any value']; var array-
WithTwoArguments = ['1st','2nd'];
// same result as you logged already via .call fnWithNoArgu-
ments.apply(null, emptyArray);
fnWithOneArgument.apply(null, arrayWithOneArgu-
ment); fnWithTwoArguments.apply(null, arrayWithT-
woArguments);Tip to remember the difference
between .calland .apply: the word “apply” starts with
“a”, and so doesArray;-)
explicit context
Now that the difference between these two meth-
ods is clear, it’s time to understand what’s powerful
about them.
Do you remember the collection in the previous
page?
var allNodes = document.querySelectorAll(™); // a dirty
and not always possible approach // allNodes.forEach =
[]} forEach;
// this is one way to borrow and invoke the Array forEach
method
[]-forEach.call(allNodes, function (node) {
console.log(node.nodeName);
D;Invoke the following function through its.callmethod pass-
ing, as first context argument, any sort of value that will be
returned asthis.
function wholsIt() {'use strict'; return this;} wholslt.cal-
l(null);
wholslIt.call(123);
wholslit.call(['a’, 'b’, 'c']);arguments
Every time a function is invoked, it might receive
from zero to many arguments, each of which is also
the name of the special object that gets created each
time a function is executed.
function contextAndThreeArguments(a, b, c) { con-
sole.log(this, a, b, c);
}
var me = {name: 'Andrea’};
contextAndThreeArguments.call(me, 1, 2, 3);
Not only the objectmewill be the execution context,
you'll also log in the console three different argu-
ments:1,2, and3.
The fact that you have named your arguments a, b,
and c, means that you expect a maximum of 3 of
them and no more. But what if you don’t know up-
front how many arguments you expect?function contextAndArguments() { // no specific amount of
args expected console.log(this, arguments);
}
var me = {name: 'Andrea’};
contextAndArguments.call(me, 1, 2, 3);
contextAndArguments.call(me, 4);
contextAndArguments.call(me, 5, 6,7, 8,9, 10);
The output in the console will be quite different
this time. You will see a list of values enclosed in
square brackets such as [1, 2, 3Jand [4Jor [5, 6, 7, 8,
9, 10], Which represent the collection of items the
currentargumentsobject contains for each different
function execution. Please note thatargumentsis not
actually anarray, even if its structure looks similar:
you access its properties using integers and it has
alengthproperty.
function argumentsVSArray() {
// almost every object has a toString method
// it usually describes what kind of object you are dealing with
console.log(arguments.toString());
// you create a collection of 3 elements
var arr = [arguments[ 0], // access arguments value at property 'O' ar-
guments[1], // access arguments value at property '1' argu-
ments[2] // access arguments value at property '2'
i;
// Array has a special toString method that joins all elements
instead console.log(arr.toString());
}
argumentsVSArray(‘a’, 'b’, 'c');
As argumentsis not anArray, you see the string'[object
Arguments]'instead of ['a','b’,'c'].
In this example you access all indexes manually, but
what if there were more than 3 arguments?
Array and generic collections iteration
When talking about iteration we describe the
process that accesses every property, hence every
value, of a generic object. If we are dealing with an
Array or a generic list, such process is represented
by a loop that accesses every index betweeno, andthe length of the collection itself, which is available
through the special property length
var list = ['a', 'b’, 'c'];
var index = 0;
var sizeOfTheGenericList = list.length;
// awhile loop executes what's inside its curly brackets // until
acondition is satisfied
// while (condition) { do something and update the condi-
tion } // in this case the condition is:
// "the ‘index* is less than * sizeOfTheGenericList ‘"
while (index < sizeOfTheGenericList) {
console.log(list[index]);
// update the index so that we can get out of the while loop //
whenever index is no longer less than * sizeOfTheGenericList ~
index = index + 1;
The very first time the condition is satisfied, the
index variable has the value o
which is less than thesizeOfTheGenericList, whosevalue is3, since there are 3
items in thelist.
In the console you see the letter 'a', then you in-
crement theindexby 1, and you check the condition
again. At this point index has the value1, which is
still less than 3. Then you need to log the value
atindex1, which this time shows the letter'b'and then
you need to do the same again for theindex2 and the
letter'c'. After that, the condition is no longer sat-
isfied so whatever is inside the loop won't execute
anymore.
for loop
Similarly to the previous while(condition){...}example,
the forloop also executes until its condition is no
longer satisfied. However, its logical order is slightly
different and described as such:
( please note the following is not valid JavaScript code, just a textual de-
scription )for (
[1] one or more variable declarations, comma-separated ;
first semicolon ——
[2] condition to satisfy ; < second semicolon
[4] changes to update the condition
MM
[3] do something with the current value. Please note this is
actually the third part of a for loop flow. The 4th one comes
after this one }
Taking into consideration the previous whileloop as
an example, you can do exactly the same process
within the followingforloop:
for (var index = 0, size = list.length; index < size; index =
index + 1) { console.log(list[index]);
}
It is very important to note that if the condition is
not satisfied, neither the 34 nor the 4thpart of the-
forloop is executed.// empty list, its length is 0
var list = [];
for (var
i=0;
i newArray
If instead you want to create a new array based on
some value found during the iteration, map()is the
right way to go. Its usage is basically the same as for
theforEachone, but its invoked function should re-
turn some value for each iterated index.
var single = [1, 2, 3];
var doubled = single.:map(function (num, i, arr) { return
num + num; // returning a new value for index i });
console.log(single); // /1, 2, 3] console.log(doubled); // /2,
4,6]
The main use case for map is to create a new list of
items after somehow extracting, changing, or trans-
forming the initial values of a collection.var people = [{name: 'Andrea’}, {name: 'Robert'}];
var allNames - people.map(function (obj) { return obj.
name; }); console.log(allNames); // ‘Andrea’, ‘Robert!
array.filter(callback, context) > newArray
In case you want to work only with items that sat-
isfy a specific condition, you can use the filtermethod
which creates a new array containing only those
items that pass the check.
var smallerThan10 = [1, 5, 8, 12, 16].filter(function (num)
{return num < 10;
D
console.log(smallerThan10); ///1, 5, 8]
One should never confuse the meaning of the
returned value in .mapQwith the one returned
in .filter(), because while the former will use as value
for that index whatever value you decide to return,
including undefined in case no value is specified, fil-
ter()returned value will be just the condition indicat-ingif the value at the current index should be kept or
not in the new array.
array.some(callback, context) ~ boolean
You now know how to iterate, how to transform and
how to filter; but how do you look for a specific con-
dition inside a collection?
Well, in this case.some()is your best friend as it stops
iterating as soon as the returned value satisfies the
condition.
var people = [{name: 'Andrea’}, {name: 'Robert'}];
function isThereAny(name) {
return people.some(function (user) {
// as soon as this is true it will stop iterating return user.
Name === name;
Ds
}
console.log(isThereAny(‘Andrea')); // true console.log(is-
ThereAny(‘Jack')); // falsearray.every(callback, context) > boolean
To the contrary of.some(), the following method
stops iterating as soon as the condition is not satis-
fied:
var people = [{name: 'Andrea', age: 37}, {name: ‘Robert’, age:
173);
function canEveryoneDrink() {
return people.every(function (person) { return person.age
>= 18;
Ds
}
console.log(canEveryoneDrink()); // false, Robert is too
young
array.indexOf( value, fromIndex) > number
As its name suggests,.indexoffinds the index, if any,
that holds a specific value within an array.
var alphabet = ['a’, 'b’, 'c', 'd’, '...', '2']; var index = alphabet.in-
dexOf('c'); // index === 2 alphabet[index]; // 'c'// if not found, returns -1
alphabet.indexOf(123); //-1
In the latest specifications,array.includes(value, fro-
mIndex)returns aboolean indicating the value is
present or not.
There are actually dozens of array methods. All of
them are described with many examples and uses
in the Mozilla Developer Network, under the section
Array.prototype!, which is the object containing all
methods and behaviors inherited by every array.
lnttps://developer.mozilla.org/en/docs/Web/JavaScript/Reference/
Global_Objects/Array/prototype
prototype and prototypal inheritance
When a new variable has the value of an object,
an array, or a function, it comes by default with
methods that nobody explicitly assigned: these are
already part of the core functionality; they are prop-
erties, and methods, inherited from another object.There are two mechanisms to inherit from other
objects: via direct link or via special functions used
to initialize objects and setup their inheritance. The
first direct link way to explicitly inherit properties
between objects, is the following:
// generic object referenced as a “ person’ // it has two proper-
ties: ‘name’ and ‘age’ // and a method in charge of increas-
ing the age Var person = {
name :'anonymous',
age: 0,
birthday: function () {
this.age++;
}
i
// this is just me, inheriting
// properties and methods
// from the “person object
// using a method of the globally always available // ~Ob-
ject’ “constructor” (described later on) var me = Object.cre-
ate(person);me.name = ‘Andrea’;
console.log(me); // {name: ‘Andrea'}
console.log(person); // {name: ‘anonymous’, age: O}
Usually the browser console will only show objects
“own” properties, ignoring the inherited ones.
That is why logging the variable me, you see only the
nameproperty, even if there’s more in there.
genericA.isPrototypeOf(genericB) > boolean
In JavaScript, one of the methods available by de-
fault is.isPrototypeOf(), which reveals possible inheri-
tance information between two objects.
If you consider the previous variables personand
meas an example, you can assume the result of thep-
erson.isPrototypeOf(me)invocation will be true. But
what does it mean, exactly?
// how does the console show me?
console.log(me); // fname: '‘Andrea'}
// but does me have an ‘ age~ too?
me.age; // 0 > Yes, ‘age* is inherited from * person’
// and does me have a * birthday‘ method too?typeof me.birthday; // ‘function’ > Yes, inherited from ‘per-
son*
// what happens if we invoke the ‘birthday’ as method of
“me? me.birthday();
// how did * birthday* invocation affect me?
console.log(me); // {name: "Andrea", age: 1}
// and suddenly, « “the wild age appears” // did me birthday
affect person one?
console.log(person); // {name: "anonymous", age: 0} + Nope,
all good
A little recap of the method context chapter: when
we invoke a function through the dot notation from
a generic object, that object will temporarily become
the execution context of such function.
This does not mean that both personand mehave a
birthdaymethod, but it means that me will tempo-
rarily execute person.birthday as if it was its own
method.
// root” is an object with a method that // simply returns the
current execution context var root = {method: function () {return this;
ih
// ‘child* is an object that inherits from *root* var child =
Object.create(root);
// if you execute ‘root.method* via “root* it will return
“root * itself // since it's the implicit execution context
console.log(root.method() === root); // true > because
“this* is ‘root’ here
// but when you invoke the inherited method through the
“child* reference // it returns the current execution context
which is * child*, not ‘root’ console.log(child.method() ===
child);// true > since ‘this* is now * child*
// and that is because we are implicitly doing the following:
root.method.call(child); // which will use ‘child’ as * this*
indeed
Once you understand that a method does not need
to be directly attached or assigned as an object prop-
erty, and that it can be simply inherited, what the
prototypal inheritance is about becomes clearer: it isan implicit, “invisible”, chain between different ob-
jects.
Object.prototype
By default, every JavaScript object inherits proper-
ties from the Object.prototype, which is also simply an
object, in fact the one that provides basic methods to
all the others.
// create an empty object var justEmpty = {};
// can this object be represented as a string?
console.log(justEmpty.toString()); // [object Object]'
// but who put that * toString’ method into your empty ob-
Ject? console.log(justEmpty.toString === Object.prototype.
toString); // true
// is that because there is a prototypal chain between these
two objects? _console.log(Object.prototype.isPrototype-
Of(justEmpty)); // true
Since every object has in its root a.toString()method,
you might think it will behave in the same way, re-
gardless of which variable you use, right?Well, no. Inheriting some property or method
doesn’t prevent possible “overrides”, therefore a
method could have been redefined in the middle of
some inheritance chain.
For instance Array.prototypealso inherits fromobjec-
tprototype, and you could always perform anar-
ray.isPrototypeOf(anotherObject)check. But thetostring
method is not the inherited one. It’s redefined to re-
turn its comma-separated values that are also “con-
verted” into a string.
// create a generic Array containing 3 numbers var arr = [7,
11, 2];
// the arr.toString method is inherited by Array.prototype
// and not by Object.prototype. The following check is in-
deed false console.log(arr.toString === Object.prototype.
toString); // false
// but other methods are inherited from the root
console.log(arr.isPrototypeOf === Object.prototype.isPro-
totypeOf); // true// how different is it?
console.log(arr.toString()); // it's the string '[7,11,2]!
object.toString() > string
Being at the root of the prototypal chain has some
advantages. For instance, even if array inherits a
differenttoStringmethod, you can temporarily bor-
row the method at the root and see how different the
result is.
var arr = ['a','b', 'c', 'd'];
console.log(
// the inherited method is the one from Array.prototype,
Array.prototype.toString.call(arr), // ‘a,b,c,d°
// which is indeed the equivalent of the following operation
arr.toString(), // ‘a,b,c,d"
// but Array.prototype inherits from Object.prototype
// and what happens when you use the original method in-
stead?
Object.prototype.toString.call(arr) // ‘object Array]' );
The Object.prototype.toStringmethod is a very special
one: it can tell you if you are dealing with somegeneric object or a “native” one.
As in the previous example, using an array asObjec-
t.prototype.toStringexecution context will return the
string'[object Array], very differently compared to'ob-
ject Object]'which is the default string returned for
every object in our program.
native
In JavaScript, this term means all variables, ob-
jects, functions, methods, classes or constructors
that have been provided by the environment and
not by a library. Objects derived from native classes
in JavaScript expose their “class” name once they
are used as context of theObject.prototype.toString-
method.
// being lazy and for demo purposes // let's reference the
method directly var toString = Object.prototype.toString;
// so that it is possible to easily invoke it multiple times con-
sole.log(
toString.call({}),toString.call((]),
toString.call("),
toString.call(0),
toString.call(true),
toString.call(null),
toString.call(undefined),
toString.call(function () {}),
toString.call(JSON),
toString.call(Math),
toString.call(new Date),
// [object Object]' // [object Array‘ // [object String]' // '[ob-
ject Number] // 'fobject Boolean|' //'fobject Null'
// [object Undefined|' // '[object Function|' // [object JSON|'
// [object Math]
// [object Date]'
toString.call(this.window || global) // ‘object global)');
Historically, unlike many other cases, the Object.pro-
totype.toString method has been implemented in a
consistent and reliable way across platforms.class
In most modern JavaScript implementations, classis
a very specific keyword used to define the behavior
of each object that will be created through its name.
Following there is an example of modern JS syntax *
* which might not work in older browsers or JS engines
// define a generic Rectangle behavior
class Rectangle {
// this method will implicitly be invoked every time
// anew Rectangle(w, h) is created
constructor(width, height) {
// the * this’ invocation context will be
// the freshly created new object
// you assign the received arguments to use them later on
this.width = width;
this-height = height;
} // © note that a class definition doesn't need a comma be-
tween methods// the definition includes an * .area()* method
// that will be inherited by each ‘new Rectangle*
area() {
// the execution context will be the ‘Rectangle’ instance //
that is invoking the area method. Every instance
// will have ‘width’ and ‘height’ properties, assigned when
created return this.width * this.height;
}
} // note: no comma required here either
// a Rectangle* instance example
var myDesk = new Rectangle(5, 3);
console.log(myDesk.area()); // 15 as 5 * 3 // another refer-
ence
var myTV = new Rectangle(16, 9);
console.log(myTV.area()); // 144
Whenever in JavaScript the special keyword newis
used, the engine expects a class or a “constructor”
right afternewin order to create an object linked to
the constructor’s ownprototype.constructor
Whenever you declare a function, the engine will au-
tomatically provide its prototypeobject.
function justAFunction() { /* and it could do anything it
wants */}
console.log(
// who put this object here?
justAFunction.prototype, // {} // is that inherited from
the global Function? justAFunction.prototype === Func-
tion.prototype // false
Generally speaking, every JavaScript function can be
used to create objects linked to their own prototype,
which is an object that contains only one property:
the constructor
function linkMe(Q) {} // simple function
// linkMe becomes special the moment we invoke it via new
var obj = new linkMe();console.log(
// we have created a prototypal chain
linkMe.prototype.isPrototypeOf(obj), // true // by default
we also have inherited the constructor // which is nothing
else but the function linkMe obj.constructor === linkMe, //
true // and such constructor is actually inherited // since it is
indeed part of linkMe.prototype itself linkMe.prototype.con-
structor === linkMe // true
Going back to the Object.create(fromAnotherObjec-
tymechanism you saw previously, you can use func-
tions to create new instances, as in the following
operation:
function Shape() {} // dummy function used only to inherit
its prototype
// creating a chain using the Shape.prototype var oneShape =
Object.create(Shape.prototype);
// is the same as creating a new Shape var anotherShape =
new Shape();