Would you like to clone this notebook?

When you clone a notebook you are able to make changes without affecting the original notebook.

Cancel

javascript

node v9.11.2
version: 0.0.11
endpointsharetweet
(() => { 'use strict';    return 'example'; })();
1. КОНТЕКСТ ИСПОЛНЕНИЯ Каждый раз, когда происходит передача управления исполняемому коду, осуществляется вход в контекст исполнения (Execution Context). Совокупность контекстов исполнения представляет собой стек вызовов (Call Stack). На дне стека - глобальный контекст, верхушка - текущий активный контекст. Стек изменяется по мере перехода в различные контексты. Стек вызовов имеет предельный размер. С контекстом исполнения связано понятие тип кода. Различают глобальный код и код функции. Глобальный код исполняется на уровне всей программы в глобальном контексте, он не включает в себя кодов функций. Код функции не включает в себя кодов вложенных функций. При передаче управления функции стек пополняется контекстом функции, при возврате из функции контекст функции удаляется из стека. Брошенное, но не пойменное исключение способно завершить один и более контекстов.
eval может добавлять переменные в вызывающий контекст (Calling Context), однако уже при use strict eval-код запускается в песочнице и не может изменять вызывающий контекст.
(() => { var foo = 'исходное значение'; eval('var foo = \'значение изменилось без use strict\';'); console.log(foo); (() => { 'use strict'; var foo = 'исходное значение'; eval('var foo = \'не изменилось с use strict\';'); console.log(foo); })();    return 'КОНТЕКСТ ИСПОЛНЕНИЯ'; })();
2. ЦИКЛ СОБЫТИЙ Почти каждая среда исполнения Java Script имеет реализацию очереди событий (Event Queue). Очередь событий представляет собой список событий с привязанными к ним функциями обратного вызова (callback). Цикл событий отслеживает новые асинхронные события в замкнутом цикле. Событие обработается, когда стек вызовов будет пуст. Когда событие обрабатывается, происходит вызов функции. Событие должно быть полностью обработано, прежде чем начнет обрабатываться следующее. В большинстве реализаций существуют несколько типичных способов создания асинхронных событий: setTimeout, setInterval.
(() => { setTimeout(() => { console.log('коллбек из цикла событий'); }, 1000);    return 'ЦИКЛ СОБЫТИЙ'; })();
3. ЛЕКСИЧЕСКОЕ ОКРУЖЕНИЕ Область видимости - абстрактное понятие, она определяет доступность переменных в конкретной части программы. Различают глобальную и локальную области видимости. В JS локальная область видимости ограничена кодом функции или кодом блока (ES6). Лексическое окружение (Lexical Environment) является скрытым свойством контекста исполнения, которое перед исполнением кода функции заполняется параметрами, функциями и переменными из кода функции в виде его свойств. При создании функции в ее скрытое свойство [[Scope]] записывается ссылка на лексическое окружение родителя. В случае создания функции через new Function свойство [[Scope]] ссылается на глобальный объект. Цепь областей видимости (Scope) - свойство контекста исполнения, представляет собой цепь лексических окружений, собранную согласно [[Scope]]. По мере исполнения кода свойствам лексического окружения присваиваются значения. Значения берутся из цепи областей видимости: сначала ищутся в локальном лексическом окружении, затем в окружении родителя итд. до глобального объекта.
(() => { 'use strict'; let foo = 'foo из родителя'; function func() { console.log(foo); let bar = 'bar из функции'; (function func() { console.log(`${foo} и ${bar}`); })(); }; func(); foo = 'измененный foo из родителя'; func(); return 'ЛЕКСИЧЕСКОЕ ОКРУЖЕНИЕ'; })();
4. ЗАМЫКАНИЕ Замыканием (Closure) является функция, в коде которой имеются ссылки на переменные во внешнем лексическом окружении, лексические окружения такой функции и ее родителей гарантированно остаются в памяти (Heap) после ее завершения. Замыкания используются повсеместно. В качестве типовых примеров использования можно привести функции обратного вызова (callback) и отложенные вызовы (setTimeout).
(() => { 'use strict'; function func() { let foo = 'foo из замыкания'; return () => { console.log(foo); }; }; let callback = func(); ((func) => { func(); })(callback); return 'ЗАМЫКАНИЕ: обратный вызов'; })();
Чуть более сложный пример - мемоизированная функция. Выполнив эту функцию, можно возвратить новую функцию с переменными из замыкания. Эта функция хранит входящие аргументы и возвращаемые значения, чтобы избежать повторного вычисления.
(() => { 'use strict'; function func() { let arr = []; return (foo, bar) => { let result; if (arr[`${foo},${bar}`]) { result = arr[`${foo},${bar}`]; console.log(`сохраненный foo * bar: ${result}`); } else { result = foo * bar; arr[`${foo},${bar}`] = result; console.log(`посчитанный foo * bar: ${result}`); } return result; }; }; let memoized = func(); memoized(3, 11); memoized(1, 11); memoized(3, 11); return 'ЗАМЫКАНИЕ: мемоизированная функция'; })();
Можно создать функцию с методами из уникального лексического окружения.
(() => { 'use strict'; function func1(name) { let foo = `foo из замыкания ${name}`;        function func2() {            return foo = `${foo} и дополнение`; }; func2.bar = 'свойство функции';        func2.method = function() {            return foo = `${foo} и ${this.bar}`;        }; console.log(foo);        return func2;   }; let func3 = func1('func3'); let func4 = func1('func4'); console.log(func3()); console.log(func3()); console.log(func4());    console.log(func4.method()); return 'ЗАМЫКАНИЕ: функция с методами'; })();
Можно создать обособленную область видимости, доступ к которой имеют только методы переданного объекта.
(() => { 'use strict'; let obj = { x: 1, y: 2, }; ((obj) => { let foo = 'foo из замыкания'; obj.bar = 'свойство объекта';        obj.method = function() {            return foo = `${foo} и ${this.bar}`;        }; console.log(foo); })(obj);    console.log(obj.method()); obj.bar = 'другое свойство объекта';    console.log(obj.method()); return 'ЗАМЫКАНИЕ: обособленная область видимости'; })();
5. ТИПЫ ДАННЫХ Примитивные типы данных: boolean, null, undefined, number, string, symbol (ES6). null - специальное значение 'ничто'. undefined - отсутствие значения у объявленной переменной. У number существуют специальные значения NaN и Inifinity.
(() => { 'use strict'; let foo = 0; console.log(typeof foo === 'number'); foo = 'string'; console.log(typeof foo === 'string'); foo = true; console.log(typeof foo === 'boolean'); foo = undefined; console.log(typeof foo === 'undefined'); foo = null; console.log(typeof foo === 'object' && foo === null);    return 'ТИПЫ ДАННЫХ: примитивы'; })();
object - значение в памяти, на которое можно сослаться с помощью идентификатора, и представляет собой набор свойств. Объект можно называть ссылочным типом. Каждое свойство идентифицируется ключом, в качестве которого может выступать строка или символ. Существуют два типа свойств: свойства-значения и свойство-акцессор.
(() => { 'use strict'; let obj = {}; obj.__proto__ = { x: 1, y: 2, z: 3, }; obj.foo = 'простое свойство'; Object.defineProperty(obj, 'bar', { value: 'свойство-значение', enumerable: true, configurable: false, writable: false, }); Object.defineProperty(obj, 'baz', { get() { return `!!! ${this.foo} !!!`; }, set(value) { this.foo = `${this.foo} ${value}`; }, enumerable: false, configurable: false, }); console.log(obj); obj.baz = 'изменено'; console.log(obj.baz); let arr = []; for (let property in obj) { arr.push(property); } console.log(arr); console.log(Object.keys(obj)); console.log(Object.getOwnPropertyNames(obj));    return 'ТИПЫ ДАННЫХ: объекты'; })();
function - это обычный объект, имеющий дополнительную возможность быть вызванным для исполнения. array - это обычный объект со связью между целочисленными ключами его свойств и специальным свойством length.
(() => { 'use strict'; let foo = function() {}; console.log(typeof foo === 'function'); foo = []; console.log(typeof foo === 'object' && Array.isArray(foo)); foo = {}; console.log(typeof foo === 'object' && foo !== null && !Array.isArray(foo));    foo = new Date();    console.log(typeof foo === 'object' && foo instanceof Object && foo.constructor === Date);    return 'ТИПЫ ДАННЫХ: объекты'; })();
symbol (ES6) - уникальный неизменяемый тип данных, который можно использовать как идентификатор для свойств объектов. Таким образом, в любом объекте можно создать приватное свойство, доступное с использованием ссылки на символ.
(() => { 'use strict'; let obj = function() { let foo = Symbol('foo'); let bar = Symbol.for('bar'); console.log(typeof foo === 'symbol'); let obj = { [foo]: 'приватное свойство', [bar]: 'приватное свойство с глобальным символьным идентификатором', baz: 'публичное свойство', }; console.log(obj[foo]); return obj; }(); console.log(obj); console.log(Object.getOwnPropertySymbols(obj)); console.log(obj[Symbol.for('bar')]);    return 'ТИПЫ ДАННЫХ: символы'; })();
reference - внутренний тип, не является типом данных, нужен для разъяснительных целей результата операции присваивания и др. Объект может содержать любое количество свойств, так же как и функция может содержать любое количество кода, а массив - любое количество элементов. Соответственно объект занимает неопределенное количество памяти, поэтому объект нельзя сохранить в переменой как значение. Ссылка состоит из базового значения и имени. Базовым значением может быть: string, number, boolean, object или undefined. Разрешение идентификатора всегда возвращает ссылку с именем идентичным идентификатору.
6. ПРИСВАИВАНИЕ Все данные примитивного типа являются неизменяемыми (иммутабельными). При совершении операции присваивания в переменную сохраняется новое значение. Напротив все данные ссылочного типа являются изменяемыми. Если присваивается значение примитивного типа, то в переменную сохраняется копия этого значения.
(() => { let foo = 'значение'; let bar = foo; console.log(foo); return 'ПРИСВАИВАНИЕ: примитивный тип'; })();
Если присваивается значение ссылочного типа, то в переменную сохраняется ссылка на значение.
(() => { 'use strict'; let foo = { prop: 'исходное значение', }; let bar = foo; bar.prop = 'измененное значение'; console.log(foo); return 'ПРИСВАИВАНИЕ: ссылочный тип'; })();
Деструктуризация объекта (ES6) позволяет объявить переменные из объекта и присвоить им значения. Можно изменить названия переменных и задать значения по умолчанию.
(() => { 'use strict'; let {size: {x: width, y: height, z: depth = 30}} = { size: { x: 10, y: 20 } }; console.log(width, height, depth); return 'ПРИСВАИВАНИЕ: деструктуризация объекта'; })();
Деструктуризация массива (ES6) позволяет объявить переменные из массива и присвоить им значения. Можно задать значения по умолчанию. Можно объявить переменную с массивом оставшихся элементов с помощью оператора spread (ES6).
(() => { 'use strict'; let [first, {x: second}, third = 15, ...rest] = [5, {x: 10}, undefined, 20, 25, 30]; console.log(first, second, third, rest); return 'ПРИСВАИВАНИЕ: деструктуризация массива'; })();
7. СОЗДАНИЕ ФУНКЦИИ Есть два способа создания функции: объявление (Function Declaration) и выражение (Function Expression). Объявленная функция с именем создается перед исполнением кода, при use strict доступна только области видимости блока, в котором объявлена. Анонимная функция используется тогда, когда нет необходимости сохранять функцию в переменной.
(() => {    'use strict'; if (true) { console.log(func1()); function func1() { return 1; }; } console.log(typeof func1);    let func2 = function() {        return 2;    }    console.log(func2());    let func3 = () => {        return 3;    }    console.log(func3());    [4].forEach((element) => {        console.log(element);    }, 0);    return 'СОЗДАНИЕ ФУНКЦИИ'; })()
Методы в блоке можно записывать в сокращенном виде (ES6). Стрелочные функции можно записывать в сокращенном виде (ES6).
(() => { 'use strict'; let obj = { method() { console.log(true); }, }; obj.method(); let func = x => x + 1; console.log(func(1)); return 'СОЗДАНИЕ ФУНКЦИИ: методы и стрелочные функции'; })();
8. АРГУМЕНТЫ ФУНКЦИИ Можно передавать любое количество аргументов. С помощью объекта arguments можно получить все аргументы. В стрелочных функциях (ES6) нет arguments, он берется из замыкания. С помощью spread (ES6) можно передать массив аргументов.
(() => { 'use strict'; function func(foo, bar) { console.log(arguments); ((foo) => { console.log(arguments); })(bar); }; func(1); func(1, 2, 3, ...[4, 5]); return 'АРГУМЕНТЫ ФУНКЦИИ'; })();
9. ПАРАМЕТРЫ ФУНКЦИИ Можно задавать дефолтные значения параметрам (ES6). Параметры можно деструктурировать (ES6). С помощью spread (ES6) можно получить массив параметров.
(() => { 'use strict'; function func({x: width, y: height, z: depth = 3} = {}, [first, second, third = 3] = [] , foo = 'foo', ...rest) { console.log(`${width} ${height} ${depth}`, `${first} ${second} ${third}`, foo, rest); }; func({ x: 1, y: 2, }, [1, 2], undefined, 4, 5); return 'ПАРАМЕТРЫ ФУНКЦИИ'; })();
10. this this является свойством контекста исполнения. Значение this напрямую связано с типом исполняемого кода и определяется при входе в контекст, оставаясь неизменным. В глобальном коде this ссылается на глобальный объект. В коде функции значение this определяется вызывающей стороной в зависимости от того, каким образом синтаксически вызвана функция. Если слева от скобок вызова функции будет значение типа ссылка, то this будет ссылаться на базовый объект этого значения. Если базовый объект отсутствует, this будет ссылаться на глобальный объект, а при use strict будет равен undefined. При вызове функции в качестве конструктора this будет ссылаться на созданный объект. Можно указать this при вызове функции с помощью call или apply. Можно указать this при создании функции с помощью bind.
(() => { 'use strict'; function func1() { console.log(this); }; let obj1 = { prop: 'foo', method: func1, }; let func2 = func1.bind(obj1); func1(); func2(); obj1.method(); obj1.method.call(this); let obj2 = new func1(); return 'this'; })();
11. ООП Один из важнейших принципов ООП - разделение внутреннего и внешнего интерфейсов. Внутренний интерфейс - это свойства и методы, доступ у которым имеют только другие методы, их называют приватными. Во внешнем интерфейсе свойства и методы доступны извне, из называют публичными. Другим типичным принципом ООП являются константы.
(() => { 'use strict'; function Constr() { const CONSTANT = 'приватная константа'; let priv = 'приватное свойство'; let func = function func() { console.log(this.pub); }.bind(this); this.pub = 'публичное свойство'; this.method = () => { func(); console.log(priv); }; }; let obj = new Constr(); obj.method(); return 'ООП'; })();
В ООП должно быть наследование. В функциональном стиле наследование делается через вызов функции-родителя. Приватные методы и свойства записываются с префиксом _, так как в наследованном объекте не будет доступа к переменным.
(() => { 'use strict'; function Constr1() { const CONSTANT = 'приватная константа'; let priv = 'приватное свойство'; let func = function func() { }.bind(this); this._priv = 'приватное свойство'; this.pub = 'публичное свойство'; this.method = () => { func(); }; }; function Constr2() { Constr1.call(this); this.method = () => { console.log(typeof priv); console.log(this._priv); }; }; let obj = new Constr2(); obj.method(); return 'ООП: наследование'; })();
12. ПРОТОТИПЫ Объекты можно организовать в цепочки так, что свойства, не найденные в одном объекте, автоматически искались в следующем. Для этого служит свойство __proto__. Можно создать объект с прототипом с помощью Object.create. Можно создать объект с прототипом с помощью свойства prototype у конструктора.
(() => { 'use strict'; let obj1 = { prop1: 'свойство 1', }; let obj2 = { prop2: 'свойство 2', }; function Constr() { this.prop3 = 'свойство 3'; }; Constr.prototype = obj1; obj2.__proto__ = obj1; let obj3 = Object.create(obj2); let obj4 = new Constr(); console.log(obj2.prop1); console.log(obj3.prop2); console.log(obj4.prop1); return 'ПРОТОТИПЫ'; })();
В прототипном стиле ООП методы записываются в прототип конструктора. Наследование также работает через прототипы.
(() => { 'use strict'; function Constr1() { this.prop1 = 'свойство 1'; }; Constr1.prototype.method = function Constr1Method() { console.log(this.prop1); }; function Constr2() { Constr1.apply(this, arguments); this.prop2 = 'свойство 2'; }; Constr2.prototype = Object.create(Constr1.prototype); Constr2.prototype.constructor = Constr2; Constr2.prototype.method = function Constr2Method() { Constr1.prototype.method.apply(this, arguments); console.log(this.prop2); }; let obj = new Constr2(); obj.method(); return 'ПРОТОТИПЫ: ООП'; })();
В ES6 были добавлены классы, которые фактически работают через прототипы. super() вызывает конструктор родителя, без этого вызова this не будет доуступен. Методы родителя можно вызвать через super.method(). Статические методы самого конструктора можно записывать через ключевое слово static. Классы подобно функции можно создавать в виде Class Declaration и Class Expression.
(() => { 'use strict'; class Constr1 { constructor() { this.prop1 = 'свойство 1'; } method() { console.log(this.prop1); } static method() { console.log('свойство конструктора'); } }; class Constr2 extends Constr1 { constructor() { super(); this.prop2 = 'свойство 2'; } method() { super.method(); console.log(this.prop2); } }; let obj = new Constr2(); obj.method(); Constr2.method(); return 'ПРОТОТИПЫ: классы'; })();
С ES6 появилось несколько возможностей задать приватные свойства и методы вместо _prop. Например, через символы.
(() => { 'use strict'; let prop1 = Symbol('свойство'); let method1 = Symbol('метод'); class Constr1 { constructor() { this[prop1] = 'приватное свойство'; } [method1] () { console.log(this[prop1]); } }; class Constr2 extends Constr1 { constructor() { super(); console.log(Object.getOwnPropertySymbols(new Constr1)); console.log(Object.getOwnPropertySymbols(Constr1.prototype)); } }; let obj = new Constr2(); let [prop2] = Object.getOwnPropertySymbols(obj); let [method2] = Object.getOwnPropertySymbols(obj.__proto__.__proto__); obj[method2](); return 'ПРОТОТИПЫ: классы'; })();
13. ПРОМИСЫ В ES6 появилась очередь работ (Job Queue). Очередь работ выполняется в конце каждого тика (Tick) цикла событий. Если в течение тика были добавлены "работы", то они будут выполнены в конце этого тика в порядке добавления. Promise (ES6) - специальный объект, который содержит свое состояние. В новом промисе код выполняется синхронно. После вызова resolve/reject промис считается выполненным и меняет свое состояние. Промис ожидает обработчика состояния. Во внешнем коде на состояния навешиваются обработчики с помощью then. При навешивании обработчика или при выполнении промиса обработчик попадает в очередь работ. Можно делать цепочки промисов, результат предыдущего переходит в последующий. Если в результате промиса вернуть промис, то в последующий переходит результат выполнения этого промиса. Можно навесить обработчик на несколько промисов, который запустится после завершения выполнения всех промисов.
(() => { 'use strict';    let promise1 = new Promise(resolve => {        setTimeout(() => {            resolve(true);        }, 2000);    });    let promise2 = new Promise((resolve, reject) => { console.log('синхронный код'); resolve(1);   }).then(result => { console.log('асинхронный код'); console.log(result); return ++result; }).then(result => { console.log(result); return new Promise(resolve => { setTimeout(() => { resolve(++result); }, 1000); }); }).then(result => { console.log(result);        return ++result;   });    Promise.all([promise1, promise2]).then(result => {        console.log(result);    });    return 'ПРОМИСЫ'; })();
В ES7 реализован способ создания асинхронных функций на промисах. async определяет, что внутри функции можно использовать await, возвращает промис. await ожидает выполнения асинхронной функции.
(() => { 'use strict'; async function func() { console.log(await (new Promise(resolve => { setTimeout(() => { resolve('в промисе'); }, 2000); }))); }; func().then(() => { console.log('после await'); });    return 'ПРОМИСЫ: async-await'; })();
14. AJAX AJAX - технология обращения к серверу без перезагрузки страницы. Существуют несколько способов доставки данных без перезагрузки страницы: создание тегов script и img, создание дочерних iframe и объект XMLHttpRequest (XHR). Метод open служит для настройки запроса, его аргументы: HTTP-метод, адрес, асинхронность, логин, пароль. Метод send отсылает запрос, его аргументы: тело. Метод abort прерывает запрос. Существуют методы для получения и отправки заголовов: setRequestHeader, getResponseHeader и getAllResponseHeaders. Можно задать таймаут запроса свойством timeout. Метод onreadystatechange вызывается событием readystatechange на каждом этапе отправки запроса и получения ответа. Всего существуют 5 статусов: 0 - исходное состояние; 1 - вызван open; 2 - получены заголовки; 3 - браузер получил пакет данных; 4 - запрос завершен. Текущий статус можно посмотреть в свойсте readyState. В современных браузерах предусмотрены следующие события: loadstart - запрос начат; progress - браузер получил пакет данных; abort - запрос был отменен; error - запрос завершен с ошибкой; load - запрос успешно завершен; timeout - запрос был прекращен по таймауту; loadend - запрос завершен. Ответ содержат следующие свойства: status - код ответа; statusText - текстовое описание статуса; responseText - текст ответа.
let XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; (() => { 'use strict'; let func = () => { return new Promise(resolve => { let xhr = new XMLHttpRequest(); xhr.open('GET', 'https://reqres.in/api/products/1', true); xhr.send(); xhr.onload = () => { resolve(xhr.responseText); } }); }; (async () => { console.log(await func()); })();    return 'AJAX'; })();
В новых реализациях появился метод fetch, который заменяет XMLHttpRequest и работает на промисах.
(() => { })();
15. HTTP HTTP - протокол передачи данных. Состоит из трех частей: 1. Стартовая строка определяет тип сообщения; 2. Заголовки характеризуют тело сообщения, параметры передачи и др. 3. Тело сообщения содержат данные сообщения.
Стартовая строка различается для запроса и ответа. Запрос содержит метод, uri и версию.
//GET /wiki/HTTP HTTP/1.0 //Host: ru.wikipedia.org
Ответ содержить версию, код состояния и пояснение ответа.
//HTTP/1.0 200 OK
Каждый сервер должен поддерживать методы GET и HEAD. Если метод не поддерживается, сервер вернет статус 501. Если метод неприменим, сервер вернет статус 405.
Метод OPTIONS служит для определения возможностей сервера. Метод GET используется для запроса содержимого ресурса. Клиент может передавать параметры запроса в uri. Запрос является идемпотентным, то есть всегда должен возвращать один и тот же ответ, если ресурс не изменился.
//GET /path/resource?param1=value1&param2=value2 HTTP/1.1
Метод HEAD аналогичен методу GET, служит для проверки наличия ресурса или его изменения. Метод POST служит для отправки в теле запроса клиентских данных. Метод PUT аналогичен методу POST, но различаются тем, что POST отправляет данные для обработки ресурсом, а PUT предполагает, что загружаемые данные соответствуют ресурсу. Метод PATCH аналогичен PUT, но для фрагмента ресурса. Метод TRACE позволяет получить запрос с информацией, которую добавляют промежуточные серверы. Метод DELETE удаляет русурс. Метод CONNECT преобразует соединение в TCP/IP-туннель.
Коды состояния делятся на группы: 1xx - информационные; 2xx - успех; 3xx - перенаправление; 4xx - ошибка клиента; 5xx - ошибка сервера.
Заголовки - это строки в HTTP-сообщении, содержащие разделенную двоеточием пару параметр-значение.
Тело соощения отделяется пустой строкой. Его наличие в запросе определяется методом и добавлением заголовка Content-Length или Transfer-Encoding. Его наличие в ответе зависит от метода запроса и кода ответа.
16. COOKIE Применяются для хранения данных на клиенте. Браузер способен ответить на запрос с указанием сохранить куки. Последующие запросы браузер отсылает с уже установленным куки. Для куки могут заполняться атрибуты: срок действия, путь, домен. Куки имеют предельный размер 4096 байт. Наиболее часто куки используются для аутентификации и хранения настроек клиента.
17. RESTful API REST представляет собой набор ограничений при проектировании архитектуры систем, основанных на данных. В общем виде запрос к API выглядит следующим образом:
/* GET /api/articles - список статей GET /api/articles/1 - статья 1 POST /api/articles - создать статью PUT /api/articles/1 - изменить статью 1 PATCH /api/articles/1 - изменить часть статьи 1 DELETE /api/articles/1 - удалить статью 1 GET /api/articles/1/authors - список авторов статьи 1 */
Не существует точного соглашения о том, как должен выглядеть API. Поэтому то, как работает API описывается в документации к конкретной реализации. Существуют реализации, которые основаны на RESTful API, но в которых оговорены более строгие правила. Например, Web API или JSON API.
18. DOM DOM - объектная модель документа. Объект document позволяет работать с содержимым страницы. DOM представляет собой дерево объектов, каждый соответствует html-тегу страницы. Теги образуют узлы-элементы, внутри них могут быть узлы-тексты. DOM нужен для того, чтобы маннипулировать страницей, читать информацию, создавать и изменять элементы.
Получить дочерние элементы можно через свойство childNodes. Родитель доступен через parentNode. Эти свойства учитывают и текстовые узлы. Для работы с элементами существуют свойства children и parentElement.
Для поиска элемента в DOM используют методы getElement* и querySelector*. getElementById возвращает элемент с определенным id. getElementsByTagName, getElementsByClassName можно вызывать из элементов и они находят все совпадающие элементы. querySelectorAll возвращает все элементы, соответствующие CSS-селектору, querySelector возвращает только первый, оба метода можно использовать в элементам. closest возвращает первый родительский элемент, соответствующий CSS-селектору.
Свойством innerHTML можно получить и перезаписать содержимое элемента в виде строки. Свойство data позволяет прочитать и изменить текстовое содержимое элемента.
Элементы могут обладать специальными свойствами, называемые атрибутами. Для работы с ними существуют методы hasAttrivute, getAttribute, setAttribute, removeAttribute.
Атрибуту class соответствуют два свойства className и classList, с помощью них можно изменять классы элемента.
Своство dataset позволяет обратиться к data-атрибутам элемента.
Для создания элемента существует метод createElement, для создания текстового узла - createTextNode. Для добавления элемента в DOM существуют методы appendChild и insertBefore. Можно клонировать узел методом cloneNode. Можно удалить узел методом removeChild и заменить методом replaceChild. Также появились методы append, prepend, before, after, replaceWith для вставки узлов. Метод insertAdjacentHTML позволяет вставить HTML-строку в определенное место элемента.
Для создания множества DOM-узлов используется метод createDocumentFragment.
Стили элементов содержатся в объекте style. Стили можно задать строкой с помощью свойства cssText, считать с помощью метода getComputedStyle.
19. СОБЫТИЯ "Общение" между браузером и Java Script реализовано по событийному шаблону. Шаблон представляет собой имя события, структуру данных и функцию, вызывающую это событие. В современных браузерах структура данных - это объект new Event(). В качестве обработчика события используется метод addEventListener, который ожидает в качестве аргументов имя события и функцию обработчик. Обработчик можно навесить на HTML-элемент в виде атрибута onclick. Можно задать обработчик через свойство элемента onclick. Можно навесить обработчик, используя метод addEventListener, а снять через removeEventListener.
При наступлении события обработчики сначала срабатывают на самом вложенном объекте, а затем на поочередно на внешних. Это называется всплытием. Всегда можно выяснить, на каком элементе произошло событие с помощью event.target, а event.currentTarget соответствует элементу, который обрабатывает событие на данный момент. Можно остановить всплытие с помощью метода event.stopPropagation. Можно остановить обработку и дальнейшее всплытие в текущем элементе с помощью метода event.stopImmediatePropagation. У addEventListener есть третий аргумент, задав который можно отловить событие на стадии погружения.
С помощью метода event.preventDefault можно остановить дефолтные обработчики события. Можно создавать собственные события через new Event(), а затем имитировать событие с помощью метода dispatchEvent. Для создания специфичных событий существуют специальные конструкторы, например: MouseEvent, KeyboardEvent, MouseEvent.
Браузер генерирует множество событий, не связанных с устройствами ввода. Например, стадии загрузки документа: DOMContentLoaded, load, beforeunload/unload.
20. WEB WORKER Воркер - это специальный объект, созданный с помощью конструктора new Worker, который запускает файл по имени. Код из файла будет выполнен в отдельном потоке. В отдельном потоке нет доступа к DOM, но есть доступ к Local Storage и XMLHttpRequest. Основной поток и поток воркера "общаются" с помощью сообщений, используя метод postMessage, и обрабатывают сообщения с помощью обработчика onmessage. Воркер можно остановить методом terminate.
21. ДРУГИЕ ВОЗМОЖНОСТИ ES6
Loading…

no comments

    sign in to comment