JavaScript Guide – Basic JavaScript Concepts with Code Examples

JavaScript Guide – Basic JavaScript Concepts with Code Examples from Coding compiler. Pareto Guide: 20% of the language you need in 80% of cases. Only basic javascript concepts with code examples. Since the advent of JavaScript 20 years ago, it has come a long way from a modest tool for simple animations to the top ten of the Tiobe rating. It is a language with a high level of abstraction, which allows you to focus on the code, and not on the low-level implementation of the program. It has weak dynamic typing and supports various programming paradigms.

Javascript Versions and Standards

The JavaScript language implements the ECMAScript standard, so the name of its versions starts with the letters ES : ES6, ES2016, ES2018, and so on. Versions have a serial number, and are numbered by the year of release. At the moment, the latest approved version is ES2017, aka ES8.

TC39 is responsible for language development . Each new feature must go through several stages from the proposal to the standard.

JavaScript Style Guides

In order for the JavaScript code to be clean and neat , you should develop a system of agreements and strictly adhere to them. It is convenient to use ready-made style guides, for example, from Google or AirBnb .

JavaScript Variables

Names of variables and functions in JavaScript must begin with a letter $ or underscore. They may even contain emoji or hieroglyphs! Identifiers are case-sensitive: something and SomeThingare different variables.

You cannot use the reserved words of the language as names:

break
do
instanceof
typeof
case
else
new
var
catch
finally
return
void
continue
for
switch
while
debugger
function
this
with
default
if
throw
delete
in
try
class
enum
extends
super
const
export
import
implements
let
private
public
interface
package
protected
static
yield

To create a variable, use one of the three keywords: var, let or const.

// before ES6 there were only var variables
var a = 'variable'
var b = 1, c = 2

// let-variables can be changed
let x = 10
x = 20

// const variables cannot be changed
const y = 10
y = 20 // mistake
  • var- variables have context scope and possess the property of hosting (lifting) .
  • We let and const the visibility of the block, and they do not rise.
  • immutability const – variables widely used to ensure immunity .

JavaScript Expressions

Expressions are structural units of code that can be calculated and converted to value.

// arithmetic expressions are converted to number
1 / 2
i++
i -= 2
i * 2

// string - to string
"hello," + "world"
'hello, ' += 'world'

// logical - to boolean value
a && b
a || b
!a

// literals, variables, constants are expressions too
2
0.02
'something'
true
false
this
undefined
i

// like some keywords
function
class
function*
yield
/pattern/i
() // group brackets

// create and initialize expressions
[]
{a: 1, b: 2}
new Person()
function() {}
a => a

// call expressions of functions and methods
Math.paw(2, 3)
window.resize()

JavaScript Primitive Data Types

Numbers in JavaScript

All numbers in JavaScript (even integers) are of type float (floating point number). We have prepared a separate detailed article about the features of numbers and mathematical methods in JavaScript .

Strings in JavaScript

Strings are a sequence of characters in single or double quotes. There is no fundamental difference between them.

'One line'
"Another line"

// quotes inside strings must be escaped
// double if the string is in double quotes
"Restaurant \ "At the end of the universe \""
// single if single
'I\'m Groot'

// strings may contain escape sequences
"First line \ nSecond line"

For string concatenation, use the operator +:

"Hello, " + "world"

The string can be filled with characters up to a certain length (from the beginning or from the end):

padStart(targetLength [, padString])
padEnd(targetLength [, padString])

'test'.padStart(7) // ' test'
'test'.padStart(7, 'a') // 'aaatest'
'test'.padStart(7, 'abcd') // 'abctest'

'test'.padEnd(7) // 'test '
'test'.padEnd(7, 'a') // 'testaaa'
'test'.padEnd(7, 'abcd') // 'testabc'

In ES6, a new syntax for creating strings has been added, allowing interpolation of expressions and multi-lines:

// For quoted strings, backquotes are used.
let str = `pattern string`

let answer = 42
let a = `The answer to the main question of life, the universe and all that - $ {answer}`
let b = `Twice two equals $ {2 * 2}`
let c = `something ${ foo() ? 'x' : 'y' }`

let multiline = First line
second line

third line

JavaScript Boolean values

Logical values true and false are used in comparisons, conditions and cycles. All other data types can be converted to a logical value.

// reduced to false in a logical context
0
-0
NaN
undefined
null
'' // empty line

// other values ​​are true

Null in JavaScript

null means no variable value. This concept of JavaScript has counterparts in other programming languages, for example,  nil or None.

Undefined in JavaScript

undefined means that the variable is uninitialized and does not matter.

Functions without a directive return return exactly undefined. Uninitialized function parameters are also undefined.

JavaScript Functions

A function is an independent block of JavaScript code that can be reused in a program. The peculiarity of the functions is that they can be called, pass arguments to them and get some new value.

function dosomething(foo) {
 return foo * 2
}

const dosomething = function(foo) {
 return foo * 2
}

In the concept of JavaScript, functions are objects, which means they can have their own properties and methods.

A function can be an argument or a return value of another function, and also be placed in a variable.

JavaScript Options

Since ES6, the functions support default parameters:

const foo = function(index = 0, testing = true) { /* … */ }
foo()

And in the parameter list you can leave a trailing comma:

const doSomething = (var1, var2,) => {
 //...
}
doSomething('test2', 'test2',)

Return Value in JavaScript

By default, all functions return undefined, but with the help of a directive return you can return a single value of any type.

JavaScript Closures

The effect of closures is based on the fact that in the JavaScript concept, scope is limited to functions. This is a complex topic that, nevertheless, must be understood in order to succeed.

this in JavaScript

If a function is defined as a property of some object, it is called its method and can refer to the object itself through a keyword this.

const car = {
 brand: 'Ford',
 model: 'Fiesta',
 start: function() {
   console.log(`Started ${this.brand} ${this.model}`)
 }
}
car.start() // Started Ford Fiesta

this can be set artificially using methods call, apply and bind:

const car1 = {
 maker: 'Ford',
 model: 'Fiesta',
 drive() {
   console.log(`Driving a ${this.maker} ${this.model} car!`)
 }
}
const anotherCar = {
 maker: 'Audi',
 model: 'A4'
}
car1.drive.bind(anotherCar)()
//Driving a Audi A4 car!

const car2 = {
 maker: 'Ford',
 model: 'Fiesta'
}
const drive = function(kmh) {
 console.log(`Driving a ${this.maker} ${this.model} car at ${kmh} km/h!`)
}
drive.call(car2, 100)
//Driving a Ford Fiesta car at 100 km/h!
drive.apply(car2, [100])
//Driving a Ford Fiesta car at 100 km/h!

If the function is not called in the context of the object, it this is equal to undefined.

Arrow functions in JavaScript

In ES6, a new kind of function appeared that completely changed the look of the JS code. At first glance, they are very simple:

const foo1 = () => {
 //...
}

// can even be in one line
const foo2 = () => doSomething()

// with parameter passing
const foo3 = param => doSomething(param)


// implicit return value
const foo4 = param => param * 2
foo4(5) // 10

However, there are a number of subtleties, for example, switch functions do not have their own this, but receive it from the creation context.

const a = {
 method: () => {
   console.log(this);
 }
}

a.method() // undefined

IIFE in JavaScript

Immediately Invoked Function Expressions – functions that are executed immediately after the announcement.

(function () {
 console.log('executed')
})()

// executed

JavaScript Generators

Special features that you can pause using keywords yield and resume later. This allows you to use completely new concepts of JavaScript programming.

// generating function generator
function *calculator(input) {
   var doubleThat = 2 * (yield (input / 2))
   var another = yield (doubleThat)
   return (input * doubleThat * another)
}

// initialization with a value of 10
const calc = calculator(10)

// launch calculator
calc.next()

// возвращает { done: false, value: 5 },
// where value is the result of the input / 2 expression

//continue with the new value
// it replaces the first yield
calc.next(7)

// returns {done: false, value: 14},
// where value is the calculated value of doubleThat

// continue with the new value
// it replaces the second yield
calc.next(100)

// function works to the end and returns
// { done: true, value: 14000 }
// where value = 10 * 14 * 100

To better understand generators and their relationship with other language concepts, take a look here.

Arrays in JavaScript

JavaScript Arrays allow you to organize several different elements into a collection and provide many convenient methods for working with them.

JavaScript Objects

In ES2015, object literals have new features:

  • Simplify syntax for including variables.
// before ES2015
const something = 'y'
const x = {
 something: something
}

// ES2015
const something = 'y'
const x = {
 something
}
  • Prototypes and keyword super.
const anObject = { y: 'y', test: () => 'zoo' }
const x = {
 __proto__: anObject,
 test() {
   return super.test() + 'x'
 }
}
x.test() //zoox
  • Dynamic property names.
const x = {
 ['a' + '_' + 'b']: 'z'
}
x.a_b //z

Retrieving object keys and values in JavaScript

// array of values ​​of the object's own properties
const person = { name: 'Fred', age: 87 }
Object.values(person) // ['Fred', 87]

const people = ['Fred', 'Tony']
Object.values(people) // ['Fred', 'Tony']

// array of own properties of the object in the form of pairs [key, value]
const person = { name: 'Fred', age: 87 }
Object.entries(person) // [['name', 'Fred'], ['age', 87]]

const people = ['Fred', 'Tony']
Object.entries(people) // [['0', 'Fred'], ['1', 'Tony']]

// a set of descriptors for all of the object's own properties
Object.getOwnPropertyDescriptors(object)

JavaScript Cycles

for in JavaScript

const list = ['a', 'b', 'c']
for (let i = 0; i < list.length; i++) {
 console.log(list[i]) //value
 console.log(i) //index
}

for-each in JavaScript

const list = ['a', 'b', 'c']
list.forEach((item, index) => {
 console.log(item) //value
 console.log(index) //index
})
//index is optional
list.forEach(item => console.log(item))

do-while in JavaScript

const list = ['a', 'b', 'c']
let i = 0
do {
 console.log(list[i]) //value
 console.log(i) //index
 i = i + 1
} while (i < list.length)

while in JavaScript

const list = ['a', 'b', 'c']
let i = 0
while (i < list.length) {
 console.log(list[i]) //value
 console.log(i) //index
 i = i + 1
}

for-in in JavaScript

for (let property in object) {
 console.log(property) //property name
 console.log(object[property]) //property value
}

for-of in JavaScript

Combines the conciseness of the array method forEach with the ability to interrupt the loop.

for (const v of ['a', 'b', 'c']) {
 console.log(v);
}

for (const [i, v] of ['a', 'b', 'c'].entries()) {
 console.log(i, v);
}

Destructuring in JavaScript

Spread operator in JavaScript

It allows you to expand an array, object or string into elements:

const a = [1, 2, 3]

// simple union of arrays
const b = [...a, 4, 5, 6]

// simple array copying
const c = [...a]

// works with objects
const newObj = { ...oldObj }

// and with strings
const hey = 'hey'
const arrayized = [...hey] // ['h', 'e', 'y']

// allows you to pass parameters as arrays
const f = (foo, bar) => {}
const a = [1, 2]
f(...a)

Destructuring assignment in JavaScript

It makes it possible to extract the necessary values ​​from an object and put them into named variables:

const person = {
 firstName: 'Tom',
 lastName: 'Cruise',
 actor: true,
 age: 54,
}
const {firstName: name, age} = person

// works with arrays
const a = [1,2,3,4,5]
[first, second, , , fifth] = a

JavaScript OOP Concept

In the OOP concept of JavaScript, prototypes dominate.

JavaScript Prototype Inheritance

Each object has a property prototype that stores a reference to its prototype — a kind of storage of methods and properties. The prototype, in turn, has its own prototype, to which the object also has access “by chain”.

 // array creation
const list = []

// its prototype is the prototype of the Array object
Array.isPrototypeOf(list) //true
list.__proto__ == Array.prototype // true

JavaScript Classes

Prototype inheritance is very peculiar, so the ES2015 standard introduced syntactic sugar for classes, so now JavaScript is very similar to other object-oriented languages.

 class Person {
 // constructor method is used to initialize an instance
 constructor(name) {
   this.name = name
 }
 hello() {
   return 'Hello, I am ' + this.name + '.'
 }
}

// class inheritance
class Actor extends Person {
 hello() {
   // super allows you to reference parent class methods
   return super.hello() + ' I am an actor.'
 }
}
var tomCruise = new Actor('Tom Cruise')
tomCruise.hello() // "Hello, I am Tom Cruise. I am an actor."

For class properties, you can create getters and setters:

class Person {
 get fullName() {
   return `${this.firstName} ${this.lastName}`
 }

 set age(years) {
   this.theAge = years
 }
}

JavaScript Exceptions

If an unexpected problem occurs while executing the code, JavaScript throws an exception. You can create exceptions yourself using the keyword throw:

throw value 

To handle native and custom exceptions, the construction is used try-catch-finally.

try {
 // code is executed here
} catch (e) {
 // exceptions are handled here if they appear
} finally {
 // this code is executed with any outcome
}

JavaScript Developments

In browser-based JavaScript, an event-based programming model operates. The desired event is monitored and processed using a special function.

Each event is represented by an object with many properties and is distributed on a web page in three stages:

  • Capture (capturing). The event descends from the root element to its immediate goal. At this stage it can be intercepted.
  • Trigger on target.
  • Ascent – the way back from the goal to the top.

You can install the handler in three ways:

// through html element attribute
<a href="site.com" onclick="dosomething();">Link</a>


// via on-property
window.onload = () => {
 //window loaded
}

// using the addEventListener method
window.addEventListener('load', () => {
 //window loaded
})

Event cycle in JavaScript

JavaScript code runs in single-threaded mode, that is, only one action occurs at a time, and the order of these actions is determined by the event loop. Its features are set by the runtime, but in general, the essence is the same: at each iteration, the synchronous code is first executed, and then the event handlers for the events that have occurred.

// simple program
const bar = () => console.log('bar')
const baz = () => console.log('baz')
const foo = () => {
 console.log('foo')
 bar()
 baz()
}
foo()

// conclusion:
// foo
// bar
// baz

JavaScript Asynchrony

Callbacks in JavaScript

Historically, asynchronous JavaScript has been provided using callbacks:

document.getElementById('button').addEventListener('click', () => {
 //item clicked
})

window.addEventListener('load', () => {
 //window loaded
})

setTimeout(() => {
 // runs after 2 seconds
}, 2000)

However, with a high level of nesting, the code turned into a real nightmare – hell callbacks.

window.addEventListener('load', () => {
 document.getElementById('button').addEventListener('click', () => {
   setTimeout(() => {
     items.forEach(item => {
       //your code here
     })
   }, 2000)
 })
})

Promises in JavaScript

Promises were created to get rid of this nesting. Here is what they can:

 // without promises
setTimeout(function() {
 console.log('I promised to run after 1s')
 setTimeout(function() {
   console.log('I promised to run after 2s')
 }, 1000)
}, 1000)

// with promises
const wait = () => new Promise((resolve, reject) => {
 setTimeout(resolve, 1000)
})
wait().then(() => {
 console.log('I promised to run after 1s')
 return wait()
})
.then(() => console.log('I promised to run after 2s'))

Basics of working with promises:

 // creature
let done = true
const isItDoneYet = new Promise(
 (resolve, reject) => {
   if (done) {
     const workDone = 'Here is the thing I built'
     resolve(workDone)
   } else {
     const why = 'Still working on something else'
     reject(why)
   }
 }
)

// chain of promises
const status = (response) => {
 if (response.status >= 200 && response.status < 300) {
   return Promise.resolve(response)
 }
 return Promise.reject(new Error(response.statusText))
}
const json = (response) => response.json()
fetch('/todos.json')
 .then(status)
 .then(json)
 .then((data) => { console.log('Request succeeded with JSON response', data) })
 .catch((error) => { console.log('Request failed', error) })

// perform several promises
const f1 = fetch('/something.json')
const f2 = fetch('/something2.json')
Promise.all([f1, f2]).then((res) => {
   console.log('Array of results', res)
})
.catch((err) => {
 console.error(err)
})

// performing the first of several promises
const first = new Promise((resolve, reject) => {
   setTimeout(resolve, 500, 'first')
})
const second = new Promise((resolve, reject) => {
   setTimeout(resolve, 100, 'second')
})
Promise.race([first, second]).then((result) => {
 console.log(result) // second
})

Asynchronous functions in JavaScript

The combination of promises and generators is an asynchronous abstraction of a higher level and simpler syntax.

function doSomethingAsync() {
   return new Promise((resolve) => {
       setTimeout(() => resolve('I did something'), 3000)
   })
}
async function doSomething() {
   console.log(await doSomethingAsync())
}
console.log('Before')
doSomething()
console.log('After')

// The output of the program:
// Before
// After
// I did something - after 3 seconds

Asynchronous functions are easy to chain together:

function promiseToDoSomething() {
   return new Promise((resolve)=>{
       setTimeout(() => resolve('I did something'), 10000)
   })
}
async function watchOverSomeoneDoingSomething() {
   const something = await promiseToDoSomething()
   return something + ' and I watched'
}
async function watchOverSomeoneWatchingSomeoneDoingSomething() {
   const something = await watchOverSomeoneDoingSomething()
   return something + ' and I watched as well'
}
watchOverSomeoneWatchingSomeoneDoingSomething().then((res) => {
   console.log(res)
})

JavaScript Timers

Timers – one of the methods of asynchronous code execution.

let timerId = setTimeout(() => {
 // will start in 2 seconds
}, 2000)
clearTimeout(timerId) // timeout clearing

let intervalId = setInterval(() => {
 // will run every 2 seconds
}, 2000)
clearInterval(intervalId ) // interval clearing

// recursive setTimeout
const myFunction = () => {
 // do something
 setTimeout(myFunction, 1000)
}
setTimeout(
 myFunction()
}, 1000)

JavaScript Modules

Before ES2015, there were at least three competing standard modules: AMD, RequireJS, and CommonJS, but now there is a single format.

The module file is uploaded to the page as a regular script with a special attribute. For browsers that do not support modules, use the fallback.

<script type="module" src="module.js"></script>
<script nomodule src="fallback.js"></script>

The module is imported using the directive import:

import * from 'mymodule'
import React from 'react'
import { React, Component } from 'react'
import React as MyLibrary from 'react'

And export using the word export:

export var foo = 2
export function bar() { /* ... */ }

The Node.js platform continues to use CommonJS modules.

Shared memory and atomic operations in JavaScript

In order to create multi-threaded programs in the browser, web workers and a special event messaging protocol are used. In ES2017, you can create an array of shared memory between web workers and their creator using the SharedArrayBuffer.

We do not know in advance how long it will take to write to shared memory, so atomic operations should be used.Details can be found in the proposal specification

ES2018

The ES2018 standard introduces several new language features.

Asynchronous iteration

The new loop  for-await-of allows you to iterate through the properties of the object being iterated asynchronously:

for await (const line of readLines(filePath)) {
 console.log(line)
}

This design can only be used inside asynchronous functions.

Promise.prototype.finally

Allows you to run a specific code regardless of the success or failure of the promise chain.

fetch('file.json')
 .then(data => data.json())
 .catch(error => console.error(error))
 .finally(() => console.log('finished'))

Regular expression enhancement

Lookahead and lookbehind checks

// ?= searches for a string followed by a specific string
/Roger(?=Waters)/
/Roger(?= Waters)/.test('Roger is my dog') //false
/Roger(?= Waters)/.test('Roger is my dog and Roger Waters is a famous musician') //true

// ?! performs the reverse operation
/Roger(?!Waters)/
/Roger(?! Waters)/.test('Roger is my dog') //true
/Roger(?! Waters)/.test('Roger Waters is a famous musician') //false

// ?<= searches for the line before which the specific line is
/(?<=Roger) Waters/
/(?<=Roger) Waters/.test('Pink Waters is my dog') //false
/(?<=Roger) Waters/.test('Roger is my dog and Roger Waters is a famous musician') //true

// ?<! performs the reverse operation
/(?<!Roger) Waters/
/(?<!Roger) Waters/.test('Pink Waters is my dog') //true
/(?<!Roger) Waters/.test('Roger is my dog and Roger Waters is a famous musician') //false

Patterns for Unicode characters (and its negation)

Any Unicode character has a set of properties that you can put in parentheses for verification.

/^\p{ASCII}+$/u.test('abc')   // true
/^\p{ASCII}+$/u.test('ABC@')  // true
/^\p{ASCII}+$/u.test('ABC') // false

You can read more about all the properties in the offer itself .

Named capture groups

const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const result = re.exec('2015-01-02')
// result.groups.year === '2015';
// result.groups.month === '01';
// result.groups.day === '02';

S flag

s- short for single line. Allows a character . (period) to match newline characters.

/hi.welcome/.test('hi\nwelcome') // false
/hi.welcome/s.test('hi\nwelcome') // true

And what features and concepts of JavaScript do you use most often? Do comment in the below comments box.

Related JavaScript Tutorials

JavaScript Introduction Tutorials
Introduction to JavaScript
Javascript Code editors
Javascript Reference and Specifications
Javascript Developer Console
Javascript Basics
JavaScript Hello World.!
External JavaScript Files
JavaScript Code Structure
Use Strict in JavaScript

Leave a Comment