Qualified


Identifiers and Reserved Words

* default, export, ...
* const, let, var, ...
* public, private, protected, ...
* this, class, static, null

JavaScript types

  • Number

    • 64-битные значения двойной точности формата IEEE754
    • Math объект
    • +/-Infinity, NaN, isNaN(), isFinite()
  • String

    • последовательности символов Unicode (UTF-16)
  • Boolean

    • логический тип данных с двумя значениями: true/false
    • false, 0, '', NaN, null, undefined преобразуются в false
    • все остальные преобразовываются в true
  • Undefined

    • указывающий на неинициализированное значение
  • Null

    • указывает на преднамеренное отсутствующее значение
  • Symbol

    • служит для создания уникальных идентификаторов
    • каждый Symbol уникален, cимволы с одинаковым именем не равны друг другу.
  • Object

    • Function, Array, Date, RegExp, Set, Map

Reference vs value

Primitives copied by value

Objects copied by reference


Property Attributes of an object

Each property of an object is more than just a name and value

const car = {
    brand: 'Toyota',
};

console.log(Object.getOwnPropertyDescriptor(car, 'brand'));
/*
Object {value: Toyota, writable: true, enumerable: true, configurable: true}
*/
  • writable

    indicates whether the property’s value can be changed

    Object.defineProperty(car, 'brand', { writable: false });
    
  • enumerable

    when set to false on a property will hide it when looping over all properties using for…in loop.

    Object.defineProperty(car, 'brand', { enumerable: false });
    
  • configurable

    Once configurable property is set to false, it locks down that property and prevents from modifying enumerable and even configurable. It also prevents from deleting that property

    Object.defineProperty(car, 'brand', { configurable: false });
    
  • set & get

    Object.defineProperty('car', 'brand', {
        get: function() { return 'Toyota' },
        set: function(value) { this.brand = value.toUpperCase() }
    })
    

Type conversion

typeof(value)

всего есть три типа преобразований: строковое, числовое, к логическому

  • to Number

    • Number('12')
    • parseInt(), parseFloat()
    • +"5"
    • (undefined => NaN, null => 0, true/false => 1/0)
    const str = '10.2abc';
    console.log(+str) // NaN + возвращает NaN если хоть один символ некоректен для числа
    console.log(parseInt(str)); // 10
    
  • to String

    • String(5)
    • +""
  • to Boolean

    • Boolean(234)
    • !!12

Преобразования объектов

=> String (если объект выводится через alert(obj))

  • Cтандартным строковым представлением пользовательского объекта является строка "[object Object]";
  • можно создать в объекте метод toString, который возвращает примитив

=> Number (при арифметических операциях, сравнении с примитивом)

  • используется метод valueOf, а если его нет – то toString
  • Метод valueOf обязан возвращать примитивное значение, иначе его результат будет проигнорирован. При этом – не обязательно числовое.
  • У большинства встроенных объектов такого valueOf нет, поэтому численное и строковое преобразования для них работают одинаково. (кроме Date)

=> Boolean (при if(obj) и других логических операциях)

  • Любой объект в логическом контексте – true, даже если это пустой массив [] или объект {}.

Increment and Decrement Operators

Инкремент ++ увеличивает на 1: Декремент -- уменьшает на 1:

  • i++ (постфиксная форма)
  • ++i (префиксная форма).

Variable Scoping

в JS область видимости - это текущий контекст в коде.

  • глобальная область видимости
  • локальная область видимости (функция)
  • блочная область видимости для переменных (let, const)

LexicalEnvironment

TIP

Все переменные внутри функции – это свойства специального внутреннего объекта LexicalEnvironment. При запуске функция создает объект LexicalEnvironment, записывает туда аргументы, функции и переменные.

  • Каждая функция при создании получает ссылку [[Scope]] на объект с переменными, в контексте которого была создана.
  • При запуске функции создаётся новый объект с переменными LexicalEnvironment. Он получает ссылку на внешний объект переменных из [[Scope]].
  • При поиске переменных он осуществляется сначала в текущем объекте переменных, а потом – по этой ссылке.

Context of calling

Context - это не scope, а то, куда ссылается this

- при вызове функции через new создается новый объект и ```this``` ссылается на него

this

Значение this называется контекстом вызова и будет определено в момент вызова функции.

  • this - текущий объект при вызове «через точку» и новый объект при конструировании через new.

  • Если одну и ту же функцию запускать в контексте разных объектов, она будет получать разный this

  • потеря контекста

    const user = {
      name: "Вася",
      hi: function() { alert(this.name); },
      bye: function() { alert("Пока"); }
    };
    
    user.hi(); // Вася (простой вызов работает)
    
    // а теперь вызовем user.hi или user.bye в зависимости от имени
    (user.name == "Вася" ? user.hi : user.bye)(); // undefined
    

call

func.call(context, arg1, arg2, ...)

  Array.prototype.slice.call(arguments);

apply

func.apply(context, [arg1, arg2])

bind

const wrapper = func.bind(context[, arg1, arg2...]);
  • wrapper – это обёртка, фиксирующая контекст и передающая вызовы в func

NOTE

Методы call/apply вызывают функцию с заданным контекстом и аргументами. А bind не вызывает функцию. Он только возвращает «обёртку», которую мы можем вызвать позже, и которая передаст вызов в исходную функцию, с привязанным контекстом.


Exception handling

  • try/catch/finally is JS exception handling mechanism.
try {
  // this code runs from the top of the block to the bottom without problems.
  // can sometimes throw an exception
}
catch (e) {
  // this block is executed if the try block throws an exception.
}
finally {
// This block contains statements that are always executed
}
  • multiple catch
try {
  // multiple exception types can be thrown here
  throw 1;
}
catch(e if e instanceof ReferenceError) {
  // Handle reference errors here
}
catch(e if e === "quit") {
  // Handle the thrown string "quit"
}
catch(e if typeof e === "string") {
  // Handle any other thrown strings here }
catch(e) {
  // Handle anything else here
}
finally {
  // The finally clause works as normal
}
  • window.onerror

event handler that is invoked when an uncaught exception propagates all the way up the call stack and an error message is about to be displayed in the browser’s JavaScript console.

window.onerror = function(message, url, line) {

} 

Loops

  • for (break, continue)

  • while (break, continue)

  • do...while (break, continue)

  • for...in (проходит по всем enumerable свойствам объекта)

    for(let key in object) {}
    
  • for...of (проходит по всем enumerable свойствам объекта, Array, Map, Set, arguments)

    for(let value in object) {}
    

Object - Date

  • Create:
new Date() // creates obj with current date & time
new Date(year, month, day, hours, minutes, seconds, milliseconds)
new Date(milliseconds) // 1553284301072 from January 01, 1970
new Date(dateString) // "October 13, 2014 11:13:00"
  • Date.parse() - convert dataString to milliseconds

  • Formats

    • ISO (default for JS)
  • get Date methods:

Method Description
getFullYear() get the year as a four digit number (yyyy)
getMonth() get the month as a number (0-11)
getDate() get the day as a number (1-31)
getHours() get the hour (0-23)
getMinutes() get the minute (0-59)
getSeconds() get the second (0-59)
getMilliseconds() get the millisecond (0-999)
getTime() get the time (milliseconds since January 1, 1970)
getDay() get the weekday as a number (0-6)
  • UTC Date methods: getUTCDate(), getUTCDay(), getUTCFullYear(), getUTCHours(), getUTCMilliseconds(), getUTCMinutes(), getUTCMonth(), getUTCSeconds()
  • set Date methods
Method Description
setDate() set the day as a number (1-31)
setFullYear() set the year (optionally month and day)
setHours() set the hour (0-23)
setMilliseconds() set the milliseconds (0-999)
setMinutes() set the minutes (0-59)
setMonth() set the month (0-11)
setSeconds() set the seconds (0-59)
setTime() set the time (milliseconds since January 1, 1970)

Object - Array

Arrays are a special type of objects. The typeof operator in JavaScript returns "object" for arrays.

  • length property
  • .push, .pop, .shift, .unshift
  • splice, slice(start, end),
  • concat
  • forEach, map, filter, some, every, reduce, reduceRight
  • indexOf, lastIndexOf, find, findIndex
  • sort, reverce
  • split, join
  • fill, copyWithin
  • Array.isArray, Array.from, Array.of

ES6: let and scope

let is block-scope variable

Variables and constants declared with let or const are not hoisted!


ES6: Arrow functions

  • отсутствие привязок (this, super, arguments, new.target) - берется у родительской

    • не вызываются с new
    • отсутствует прототип(.prototype)
    • отсутствует свой arguments, но есть доступ к родительскому
  • имеют методы call, apply, bind, но не затрагивают this (только для передачи аргументов)

    const sum = (a, b) => a + b;
    summ.call(null, 2, 3);
    summ.call(apply, [2, 3]);
    

Function hoisting

Hoisting is JavaScript's default behavior of moving declarations to the top.

  • Variables and constants declared with let or const are not hoisted!
  • function declaration, var - hoisted

Strict mode of javascript

An ECMAScript Script syntactic unit may be processed using either unrestricted or strict mode syntax and semantics. Code is interpreted as strict mode code in the following situations:

Global code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive (see 14.1.1).

Module code is always strict mode code.

All parts of a ClassDeclaration or a ClassExpression are strict mode code.

Eval code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive or if the call to eval is a direct eval (see 12.3.4.1) that is contained in strict mode code.

Function code is strict mode code if the associated FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition, or ArrowFunction is contained in strict mode code or if the code that produces the value of the function’s [[ECMAScriptCode]] internal slot begins with a Directive Prologue that contains a Use Strict Directive.

Function code that is supplied as the arguments to the built-in Function and Generator constructors is strict mode code if the last argument is a String that when processed is a FunctionBody that begins with a Directive Prologue that contains a Use Strict Directive.

ECMAScript code that is not strict mode code is called non-strict code.


Enhanced Object Literals

const name = 'Bohdan';
const objKey = 'key';

const obj = {
  name,
  sum(a, b) { return a + b },
  [objKey]: 5,
}

Default, Rest, Spread

Default params

(тут могут быть значения, функции, вызовы функций, значения предыдущих параметров function add(first, second = first){})

function makeRequest(url, timeout = 2000, callback = function(){}) {
  // some code
}

Rest parameter

  • может быть только 1 и записан только последним
  • не используется в методах записи свойств в литералах объектов
let obj = {
 set name(...value) {} // error
}

Spread operator

Math.max(a, b, c, d);

let numbers = [1, 23, 12, 345];
Math.max.apply(Math, numbers); // ES5
Math.max(...numbers); // ES6

Map + Set

Set

Set (множество) - упорядоченный список неповторяемых значений

сохранение объекта в экземпляре Set эквивалентно сохранинию в переменную, пока ссылка присутствует в таком экземпляре, сборщик мусора не удалит объект

Операции

// create
let set = new Set();

// add
set.add(5);
set.add('5');

// size
console.log(set.size) // 2

// только уникальные
let set = new Set([1,2,2,1,2,3]); // size 3

// проверить, есть ли зачение в множестве
set.has(5); // true or false

// удаление конкретного значения
set.delete(5);

// удаление всех значений
set.clear();

// Уникальные значения для массива
let arr2 = [...(new Set([1,2,2,2,3]))];
  • forEach для Set

    let set = new Set(['a', 2]);
    
    > set.forEach(function(value, key, ownerSet){
      console.log(value); // 'a'
      console.log(key); // 'a'
      console.log(ownerSet === set); // true
    }, this)
    

Map

Map (ассоциативный массив) - упорядоченный список пар ключ/значение, где ключ и значение могут быть любого типа. тут ключи не преобразуются в строки

  • Методы: has(key), delete(key), clear()

  • Свойства: size

let map = new Map();

map.set('title', 'ECMAScript2015');
map.set(5, 'a');

map.get('title'); // вернет значение или undefined

// инициализация
let map = new Map([['name', 'Bohdan'], [5: 'a']]);

// forEach()
map.forEach(function(value, key, ownerMap){

});
  • Итерация по Map

    • map.keys() – возвращает итерируемый объект для ключей,
    • map.values() – возвращает итерируемый объект для значений,
    • map.entries() – возвращает итерируемый объект для записей [ключ, значение], он используется по умолчанию в for..of.

TIP

Перебор идёт в том же порядке, что и вставка (в отличии от простых объектов)


Promises

Объект Promise служит хранилищем для результата асинхронной операции это специальный объект, который хранит своё состояние, текущий результат (если есть) и коллбэки.

  • до промисов:

    • модель события (addEventListener)
    • функции обратного вызова (callback)
  • внутренние состояния: pending, fulfilled, rejected

  • методы then, catch

  • new Promise()

    let fs = require('fs');
    
    function readFile(filename) {
      return new Promise((resolve, reject) => {
        fs.readFile(filename, { encoding: 'utf8' }, (err, content) => {
          if(err) {
            reject(err);
          }
          resolve(content);
        })
      });
    }
    
  • Promise.resolve()

Сразу возвращает объект Promise в состоянии "выполнено"

let promise = Promise.resolve(42);

promise
  .then(value => console.log(value)); // 42
  • Promise.reject()

Сразу возвращает объект Promise в состоянии "отклонено"

let promise = Promise.reject(42);

promise
  .catch(value => console.log(value)); // 42
  • Promise.all()

    Вызов Promise.all(iterable) получает массив (или другой итерируемый объект) промисов и возвращает промис, который ждёт, пока все переданные промисы завершатся, и переходит в состояние «выполнено» с массивом их результатов.

  • Promise.race()

Gереходит в fullfiled сразу после первого удачного выполнения

  • Global ErrorHandler

TIP

в спецификации нет глобальной обработки rejected Promises

  • nodeJS: unhandledRejection(), rejectionHandler()
  • браузеры: window.unhandledrejection, window.onrejecthandled