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.
JavaScript is a commonly referenced implementation of ECMAScript standard.
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>
For information on arrow functions, please view the Arrow Functions documentation.
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!
console.log(new Array(53)); // This array has 53 'undefined' elements!
That being said, you should always use []
when declaring an array:
console.log([53]); // Much better!
Objects are collections of key-value pairs, or properties. The keys can be String
s or Symbol
s, 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 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.
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.
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.
clz32
method is not supported in Internet Explorer or SafariWhen 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)Everything else is considered "truthy".
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.
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:
for(var i = 0; i < 5; i++){
console.log("a message");
}
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.
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.
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.
To check if the browser supports the Geolocation API:
if(navigator.geolocation){
// Horray! Support!
} else {
// No support...
}
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.
It is possible to pass a string containing JavaScript code (setTimeout("some..code", 1000)
) in place of the function (setTimeout(function(){some..code}, 1000)
). If the code is placed in a string, it will be later parsed using eval()
. String-style timeouts are not recommended for performance, clarity and sometimes security reasons, but you may see older code which uses this style. Passing functions has been supported since Netscape Navigator 4.0 and Internet Explorer 5.0.
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.
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:
If you want to find out more about the History API implementations and methods, please refer to the state of the HTML5 History API.
Strict mode is an option added in ECMAScript 5 to enable a few backwards-incompatible enhancements. Behaviour changes in "strict mode" code include:
window.undefined
) raises an error instead of executing silently;0777
) is unsupported;with
statement is unsupported;eval
cannot create variables in the surrounding scope;.caller
and .arguments
properties are unsupported;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.
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.
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).
To make these methods available in old browsers such as Internet Explorer 8, use Douglas Crockford's json2.js.
Typed Arrays were originally specified by a Khronos editor's draft, and later standardized in ECMAScript 6 §24 and §22.2.
Blobs are specified by the W3C File API working draft.
Template Literals were first specified by ECMAScript 6 §12.2.9.
The Web Storage API is specified in the WHATWG HTML Living Standard.
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.
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.
From MDN (emphasis added):
This feature is not implemented in any browsers natively at this time. It is implemented in many transpilers, such as the Traceur Compiler, Babel or Rollup.
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.
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.
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.
Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
49 | 13 | 45 | x | 36 | x |
(Last Updated - 2016/08/18)
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.
If we use the following HTML
<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;
We can fix this by explicitly converting freezingPoint
to a number.
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
).
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.
Chrome | Edge | Firefox | Internet Explorer | Opera | Opera Mini | Safari |
---|---|---|---|---|---|---|
29 | 14 | 46 | no support | 38 | no support | 9.1 |
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.
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.
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.
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.
In Maps NaN
is considered to be the same as NaN
, even though NaN !== NaN
. For example:
const map = new Map([[NaN, true]]);
console.log(map.get(NaN)); // true
In software engineering, a software design pattern is a general reusable solution to a commonly occurring problem within a given context in software design.
When it comes to animating DOM elements fluidly, we are limited to the following CSS transitions:
transform: translate (npx, npx);
transform: scale(n)
;transform: rotate(ndeg);
opacity: 0;
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.
To guarantee smooth-as-possible DOM animations, requestAnimationFrame must be used in conjunction with the above CSS transitions.
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 jank? | http://jankfree.org/ |
High Performance Animations | http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/. |
R.A.I.L. | https://developers.google.com/web/tools/chrome-devtools/profile/evaluate-performance/rail?hl=en |
Analyzing Critical Rendering Path | https://developers.google.com/web/fundamentals/performance/critical-rendering-path/analyzing-crp?hl=en |
Rendering Performance | https://developers.google.com/web/fundamentals/performance/rendering/?hl=en |
Analyzing Paint Times | https://developers.google.com/web/updates/2013/02/Profiling-Long-Paint-Times-with-DevTools-Continuous-Painting-Mode?hl=en |
Identifying Paint Bottlenecks | https://developers.google.com/web/fundamentals/performance/rendering/simplify-paint-complexity-and-reduce-paint-areas?hl=en |
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.
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):
In most current browsers, the JavaScript Console has been integrated as a tab within Developer Tools. The shortcut keys listed below will open Developer Tools, it might be necessary to switch to the right tab after that.
Opening the “Console” panel of Chrome’s DevTools:
Windows / Linux: any of the following options.
Mac OS: Cmd + Opt + J
Opening the “Console” panel in Firefox’s Developer Tools:
Windows / Linux: any of the following options.
Mac OS: Cmd + Opt + K
Opening the “Console” panel in the F12 Developer Tools:
Opening the “Console” panel in Safari’s Web Inspector you must first enable the develop menu in Safari's Preferences
Then you can either pick "Develop->Show Error Console" from the menus or press ⌘ + Option + C
Opening the “Console” in opera:
When using or emulating Internet Explorer 8 or earlier versions (e.g. through Compatibility View / Enterprise Mode) the console will only be defined when the Developer Tools are active, so console.log()
statements can cause an exception and prevent code from executing. To mitigate this, you can check to see if the console is available before you log:
if (typeof window.console !== 'undefined')
{
console.log("Hello World");
}
Or at the start of your script you can identify if the console is available and if not, define a null function to catch all of your references and prevent exceptions.
if (!window.console)
{
console = {log: function() {}};
}
Note this second example will stop all 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.
TCO is also known as PTC (Proper Tail Call) as it is referred to in the ES2015 specifications.
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.
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.
ECMAScript 2015 Specification 19.4 Symbols
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.
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 objects. Also, NaN and undefined can also be stored in a Set. NaN is considered the same as NaN (even though NaN !== NaN).
See also:
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.
What is Functional JavaScript
There has been a debate to call JavaScript a functional language or not.However we can absolutely use JavaScript as a functional due to its nature:
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.
MDN Documentation: Using data attributes.
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.
The Battery Status API is an Application Programming Interface for the client's battery status. It provides information on:
'chargingchange'
event and battery.charging
;'levelchange'
event and battery.level
;'chargingtimechange'
event and battery.chargingTime
;'dischargingtimechange'
event and battery.dischargingTime
.MDN Docs: https://developer.mozilla.org/en/docs/Web/API/Battery_status_API
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.
For more information on the Window object, please visit MDN.
The window.stop()
method is not supported in Internet Explorer.
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
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.
There is no public standard for the Navigator
object, however, all major browsers support it.
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:
In Internet Explorer, the navigator.geolocation
property is not supported in versions older than IE 8
The navigator.appCodeName
property returns Mozilla
for all modern browsers.
A full list of available "traps" can be found on MDN - Proxy - "Methods of the handler object".
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.
Chrome | Edge | Firefox | Internet Explorer | Opera | Opera Mini | Safari |
---|---|---|---|---|---|---|
45 | 12 | 22 | Currently unavailable | 32 | Currently unavailable | 10 |
For uses of WeakMap, see What are the actual uses of ES6 WeakMap?.
For uses of WeakSet see ECMAScript 6: what is WeakSet for?.
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.
"\H\e\l\l\o" === "Hello" // true
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
While escape sequences in JavaScript bear resemblance to other languages and formats, like C++, Java, JSON, etc. there will often be critical differences in the details. When in doubt, be sure to test that your code behaves as expected, and consider checking the language specification.
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.
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:
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.
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.
Chrome | Edge | Firefox | Internet Explorer | Opera | Opera Mini | Safari |
---|---|---|---|---|---|---|
30 | no support | 16 | no support | 17 | no support | no support |
"use strict";
'use strict';
Strict Mode makes JavaScript stricter to assure you the best habits. For example, assigning a variable:
"use strict"; // or 'use strict';
var syntax101 = "var is used when assigning a variable.";
uhOh = "This is an error!";
uhOh
is 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:
var myArray = [ "The following is an array", ["I'm an array"] ];
console.log(myArray[1]); // (1) ["I'm an array"]
console.log(myArray[1][0]); // "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
var myObject = {
firstObject: {
myVariable: "This is the first object"
}
secondObject: {
myVariable: "This is the second object"
}
}
console.log(myObject.firstObject.myVariable); // This is the first object.
console.log(myObject.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"
}
}
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