JavaScript Notes
JavaScript (aka ECMAScript aka ES)
Versions, Revisions
- ES6 = ECMAScript 6 = ECMAScript 2015
- arrow functions
Crash Course
Terminology
- JavaScript runtime refers to where your javascript code is executed when you run it. That said, javascript can be executed on google chrome, in which case your javascript runtime is v8, if on mozilla - it is spidermonkey, if IE - then its chakra and if on node, again its v8. (stackoverflow comment under answer)
- I/O: In practice, the web browser or other runtime system provides JavaScript APIs for I/O.
Implementations
- Google V8
- see this discussion on stackoverflow
- see Terminology → “JavaScript runtime”
- from Wikipedia:
- developed by the Chromium Project for Google Chrome and Chromium web browsers
- V8 compiles ECMAScript directly to native machine code using just-in-time compilation before executing it
- JIT compilation aka dynamic compilation ( source )
- a method for improving the performance of interpreted programs
- During execution the program may be compiled into native code to improve its performance.
- Advantages:
- Dynamic compilation has some advantages over static compilation.
- When running
Java
orC#
applications, the runtime environment can profile the application while it is being run. - This allows for more optimized code to be generated.
- If the behavior of the application changes while it is running, the runtime environment can recompile the code.
- JIT compilation aka dynamic compilation ( source )
- The compiled code is additionally optimized (and re-optimized) dynamically at runtime, based on heuristics of the code’s execution profile.
- Optimization techniques used include
- inlining
- elision of expensive runtime properties
- inline caching.
- used in
- Chromium-based web browsers
- Firefox - parts of V8 ported to the browser for regular expressions parsing
- many more apps (see Wikipedia)
Repl (JavaScript on the Command Line)
Useful: Use <tab><tab>
to autocomplete commands.
$ node
Welcome to Node.js v19.6.0.
Type ".help" for more information.
>
Formatting, Syntax Highlighting
- Install
javascript
syntax highlighting usingnvim-treesitter
. - Install
javascript
formatting usingcoc-prettier
.
CDNs
CDN: A content delivery network, or content distribution network.
Common CDNs
Press ctrl + shift + E and roload the page in Firefox to see the used CDNs (in column “Domain”).
CDNs (by popularity):
- Google Hosted Libraries
- cdnjs
- e.g.
cdnjs.cloudflare.com
- e.g.
- jsDelivr
- e.g.
cdn.jsdelivr.net
- official CDN of Bootstrap
- e.g.
Syntax
Types
Strings
UTF-8
From Wikipedia:
- the dominant encoding for the World Wide Web (and internet technologies)
- accounting for 97.9% of all web pages
UTF-16
From Wikipedia:
- for security reasons browser applications should not use UTF-16
- UTF-16 is used by systems such as
- the Microsoft Windows API,
- the Java programming language and
- JavaScript/ECMAScript.
JavaScript can “display” data in different ways: w3schools
- Writing into an HTML element, using
innerHTML
. - Writing into the HTML output using
document.write()
. - Writing into an alert box, using
window.alert()
. - Writing into the browser console, using
console.log()
.
.constructor
property and .constructor.name
stackoverflow
- Check
this
bindings, etc
Variables
let
- only use this, if you know the variable will change, otherwise use
const
- makes the code more robust
const
- creates block-scoped constants
- The value of a constant
- can’t be changed through reassignment (i.e. by using the assignment operator
=
), and - it can’t be redeclared (i.e. through a variable declaration).
- can’t be changed through reassignment (i.e. by using the assignment operator
- However, if a constant is an object or array its properties or items can be updated or removed.
Types
Check types via typeof
operator
typeof Math.LN2 === "number";
typeof declaredButUndefinedVariable === "undefined";
typeof undeclaredVariable === "undefined";
typeof { a: 1 } === "object";
For objects use the .constructor
property and .constructor.name
stackoverflow
Numbers
Number.prototype.toLocaleString
const currencyOptions = {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
}
total.toLocaleString(undefined, currencyOptions)
- Convert
total
from a number to a string with two decimal places. - this will also convert the number to a string according to the numerical conventions that match the browser’s locale
- Use
undefined
as the first argument totoLocaleString
to use the system locale rather than specifying a locale
Arrays
Spread
I.e. ...
notation, e.g.
const cart = [...state.cart];
Use cases:
- instead of
const concatArray = array1.concat(array2)
useconst concatArray = [...array1, ...array2]
- both methods do not change the existing arrays, but instead return a new array
- instead of
const pushedArray = array1.push(array2[0])
(modifiesarray1
) useconst pushedArray = [...array1, array2]
(does not modifyarray1
) - shallow copying
- i.e. creating a new array from the existing one and adding a new item to the end without changing the existing one
In JavaScript, when you create an object or array and assign it to another variable, you are not actually creating a new object - you are passing a reference.
- Shallow Copy: spread allows to make a shallow copy of an array or object without changing the existing one
- i.e. any top level properties will be cloned, but nested objects will still be passed by reference
Array.prototype.slice
Get the last element:
var my_array = /* some array here */;
var last_element = my_array[my_array.length - 1];
- Do not use
my_array.slice(-1)[0]
, it is too slow.
Array.prototype.splice
return: An array containing the deleted elements.
The splice()
method changes the contents of an array by removing or replacing existing elements and/or adding new elements in place (i.e. splice()
modifies the original array).
- To access part of an array without modifying it, see
slice()
. - a mutating method: It may change the content of
this
. - Although strings are also array-like, this method is not suitable to be applied on them, as strings are immutable.
- Negative index counts back from the end of the array.
some_array.splice(start) # remove all elements after index "start"
some_array.splice(start, deleteCount) # remove "deleteCount" elements after index "start" and keep the rest
some_array.splice(start, deleteCount, item1)
some_array.splice(start, deleteCount, item1, item2, itemN)
Array.prototype.reduce
The reduce()
method executes a user-supplied “reducer” callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.
Initial value: The first time that the callback is run there is no “return value of the previous calculation”. If supplied, an initial value may be used in its place. Otherwise the array element at index 0 is used as the initial value and iteration starts from the next element (index 1 instead of index 0).
Example:
const array1 = [1, 2, 3, 4];
// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce(
(accumulator, currentValue) => accumulator + currentValue,
initialValue
);
console.log(sumWithInitial);
// Expected output: 10
Array.prototype.indexOf
array1.indexOf(x)
- index of the first instance of
x
in anarray1
- return
-1
ifx
is not present
Lists
In JavaScript:
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);
Functions
Define Functions
Ways to Define Functions:
- function declaration mdn
- function expressions mdn
- method definition mdn
- a shorter syntax for defining a function property in an object initializer. It can also be used in classes.
- examples
Anonymous Functions
From javascripttutorial.net:
An anonymous function is a function without a name.
(function () {
//...
});
An anonymous function is not accessible after its initial creation. Therefore, you often need to assign it to a variable:
let show = function () {
console.log('Anonymous function');
};
show();
In this example, the anonymous function has no name between the function
keyword and parentheses ()
.
In practice, you often pass anonymous functions as arguments to other functions. For example:
setTimeout(function() {
console.log('Execute later after 1 second')
}, 1000);
Arrow Function Notation
ES6 introduced arrow function expressions that provide a shorthand for declaring anonymous functions.
- incorrect, see comment under this stackoverflow answer
let show = () => console.log('Anonymous function');
From w3schools:
If you have only one parameter (here: val
), you can skip the parentheses as well:
hello = (val) => "Hello " + val;
// instead, you can use
hello = val => "Hello " + val;
Anonymous Functions as arguments
In practice, you often pass anonymous functions as arguments to other functions:
setTimeout(function() {
console.log('Execute later after 1 second')
}, 1000);
this
Context
context: In JavaScript, context refers to an object. Within an object, the keyword this
refers to that object (i.e. self
), and provides an interface to the properties and methods that are members of that object. When a function is executed, the keyword this
refers to the object that the function is executed in. source
In Arrow Functions
in an arrow function: You cannot rebind this
in an arrow function. It will always be defined as the context in which it was defined. If you require this
to be meaningful you should use a normal function. stackoverflow
w3schools (scroll down to section “What About this?”)
- In regular functions the
this
keyword represented the object that called the function, which could be the window, the document, a button or whatever. - With arrow functions the
this
keyword always represents the object that defined the arrow function.
Try these examples!!!
- example with normal function
- shows that for a regular function
this
will always be the caller
- shows that for a regular function
- example with arrow function
- shows that for an arrow function it does not matter who is the caller,
this
will always be the “definer”
- shows that for an arrow function it does not matter who is the caller,
- also modify the example above and try running Example 1 and 2 below (modified from digitalocean):
- Note:
- in Example 1:
document.write('\n')
does not work in the code below: In HTML, all whitespace (including newlines) is collapsed and treated as a single space. stackoverflow - in Example 1:
<br/>
is the XHTML version of<br>
. Since you’re not using XHTML, you would just use<br>
. (How do I know you’re not using XHTML? Because you’re usingdocument.write
, which you can’t use in XHTML.) stackoverflow
- in Example 1:
- Note:
Example 1: “this” in arrow functions
<script>
const whoAmI = {
name: 'Leslie Knope',
regularFunction: function() {
document.write(this.name + '<br/>')
},
regularFunction2: function() {
document.write(this.name + '<br/>')
},
arrowFunction: () => {
document.write(this)
},
}
whoAmI.regularFunction() // "Leslie Knope"
whoAmI.regularFunction2() // "Leslie Knope"
whoAmI.arrowFunction() // [object Window]
</script>
Example 2: event.currentTarget
, “this” in arrow functions
<script>
const button = document.createElement('button')
button.textContent = 'Click me'
document.body.append(button)
class Display {
constructor() {
this.displayString = 'New text'
// In an arrow function "this" always refers to the context (=object) in which the
// arrow function was defined, ie. here the "Display" class.
const changeText = event => {
event.target.textContent = this.displayString;
}
button.addEventListener('click', getText)
button.addEventListener('click', changeText)
// Here, "this" refers to the "event.currentTarget" object, ie. "button" which
// is outside of the "Display" class.
function getText(event) {
document.getElementById("demo").innerHTML += this.textContent
}
}
}
new Display()
</script>
Sidenote about Example 2:
- Why can we call
getText()
before it is defined? - Why can we not call
changeText()
before it is defined? - answer: see stackoverflow
Some Scenarios
- When a function executes in the global context,
this
refers to the global, orwindow
object - When a function is a method of an Object,
this
refers to that object (unless it is manually executed in the context of a different object) - When a function executes inside of another function (no matter how deeply nested),
this
refers to the object whose context within which it is executed - When you instantiate a constructor function, inside of the instance object,
this
refers to the instance object
TypeScript (Microsoft)
- a strict syntactical superset of JavaScript
- adds optional static typing to the language
- designed for the development of large applications
- transpiles to JavaScript
- As it is a superset of JavaScript, existing JavaScript programs are also valid TypeScript programs.
- developed and maintained by Microsoft
Web APIs
“Web APIs are typically used with JavaScript, although this doesn’t always have to be the case.”
“JavaScript has application programming interfaces (APIs) for working with text, dates, regular expressions, standard data structures, and the Document Object Model (DOM).” “JavaScript” Wikipedia
DOM
One Web API.
Interfaces
Element
Instance Properties
.innerHTML
gets or sets the HTML or XML markup contained within the element. mdn
Event
Syntax
HTML Events
<button onclick="activateLasers()">
Activate Lasers
</button>
JavaScript Events
- either:
object.onclick = function(){myScript};
- or:
object.addEventListener("click", myScript);
( see.addEventListener()
)
- React events are named using camelCase, rather than lowercase.
- With JSX you pass a function as the event handler, rather than a string.
- e.g.
<button onClick={function}>
event
Object
event
- One can access the current event through
window.event
. Just usingevent
is implicitly accessingwindow.event
. stackoverflow - a global variable
event.target
, event.currentTarget
.currentTarget
: doc- “always refers to the element to which the event handler has been attached, as opposed to
Event.target
, which identifies the element on which the event occurred and which may be its descendant.”
- “always refers to the element to which the event handler has been attached, as opposed to
.target
: doc- “a reference to the object onto which the event was dispatched.”
“We’re using event.target
to get the element that was the target of the event (that is, the innermost element). If we wanted to access the element that handled this event (in this case the container) we could use event.currentTarget
.” mdn: note below this section
“Here you can see we are including an event object, e
, in the function, and in the function setting a background color style on e.target
— which is the button itself. The target
property of the event object is always a reference to the element the event occurred upon. So, in this example, we are setting a random background color on the button, not the page.” mdn
- “Note: You can use any name you like for the event object — you just need to choose a name that you can then use to reference it inside the event handler function.
e
/evt
/event
is most commonly used by developers because they are short and easy to remember. It’s always good to be consistent - with yourself, and with others if possible.”
onClick (Event)
- in React notation:
<button onClick={function}>
Event Handler
some_element.addEventListener()
method- The
addEventListener()
method attaches an event handler to the specified element. - The
addEventListener()
method attaches an event handler to an element without overwriting existing event handlers. - You can add many event handlers to one element.
- You can add many event handlers of the same type to one element, i.e two “click” events.
- You can add event listeners to any DOM object not only HTML elements. i.e the window object.
- The
Performance
Minification
Tools for Minification:
- jsDelivr CDN can also minify any file in JavaScript, CSS, or SVG format, which can reduce loading times. (source)
“The process of removing all unnecessary characters from the source code of interpreted programming languages or markup languages without changing its functionality.”
“These unnecessary characters usually include white space characters, new line characters, comments, and sometimes block delimiters, which are used to add readability to the code but are not required for it to execute.”
“Minification reduces the size of the source code, making its transmission over a network (e.g. the Internet) more efficient.”