Добро пожаловать в часть 6 серии. Мы продолжим задавать вопросы по ES6 здесь. Ознакомиться с пятой частью сериала можно здесь.
Вопрос 34- Объясните классы в ES6?
Ответ-Функция конструктора и классы ES6 одинаковы. Классы ES6 — это не что иное, как синтетический сахар для функции конструктора, и внутри они ведут себя точно так же.
Рассмотрим приведенный ниже пример функции конструктора.
То же самое можно написать с классами ES6 с конструктором, но это точно так же.
Вопрос 35- Объясните подклассы и наследование в ES6?
Ответ-Концепция подклассов и наследования такова на других языках, таких как Java и C++.
Рассмотрим приведенный ниже пример. У нас есть родительский класс «Млекопитающее» и подкласс «Летучая мышь», который наследуется от него. Обратите внимание, что мы использовали ключевое слово «extends».
Теперь, чтобы использовать переменные «ноги» и «имя» в «Летучей мыши», мы используем метод «супер()». Также обратите внимание, что мы можем использовать update «walk()» и добавлять дополнительные функции.
class Mammal { constructor(_legs, _name="Nabendu") { this.legs = _legs; this.name = _name; } walk() { return `${this.name} is walking`; } } class Bat extends Mammal { constructor(_legs, _name, _isVegetarian) { super(_legs, _name); this.isVegetarian = _isVegetarian; } fly() { return `${this.name} is flying`; } walk() { let eatable = this.isVegetarian ? 'carrot' : 'bug'; return `${super.walk()} with a ${eatable}`; } } let fruitBat = new Bat(4,'Bond', true); console.log(fruitBat.walk()); //Bond is walking with a carrot let meatBat = new Bat(2, undefined, false); console.log(meatBat.walk()); // Nabendu is walking with a bug
Вопрос 36- Объясните итераторы в JavaScript?
Ответ-Недавно появился JavaScript [Symbol.iterator] свойство в типах данных. Это указывает, является ли структура данных итерируемой или нет. Это включает в себя массив, строки, карту, наборы и список узлов. Объекты не имеют свойства [Symbol.iterator].
Если мы проверим __proto__ массива, мы сможем найти свойство [Symbol.iterator].
Но это не относится к объектам, поскольку они не являются итерируемыми.
Теперь iterator создаются с помощью «Symbol.iterator» и могут использоваться для перебора всех структур данных, имеющих свойство [Symbol.iterator].
Рассмотрим приведенный ниже пример. Здесь мы создаем итератор по синтаксису в строке 3. Теперь мы можем перебирать массив с помощью «iterator.next()». Каждый запуск дает и Object, у которых есть «значение» и «выполнено», которые указывают, есть ли элемент. Обратите внимание, что после пятого запуска мы получаем «значение» как undefined и «готово» как true.
Вопрос 37- Объясните генераторы в JavaScript?
Ответ-Генератор — это специальный тип функций, который генерирует что-то, когда мы перебираем его с помощью итератора. Они отличаются от массива тем, что не имеют значений заранее, а генерируют их по запросу.
Давайте посмотрим на приведенный ниже пример. Функция генератора имеет специальный синтаксис с «*». Кроме того, внутри генератора есть операторы yield. Каждый «next()» переходит к следующему оператору yield.
В приведенном выше примере не показаны какие-либо преимущества генератора, и это то же самое, что итерация по массиву. Но давайте посмотрим на следующий пример, где у нас есть бесконечный цикл while внутри генератора.
Сначала посмотрите на эту обычную функцию. Если мы запустим его, это вызовет бесконечный цикл и приведет к сбою вашего браузера.
//Normal Function function normalInfinite() { let i = 0; while(true) { console.log(i); i++; } } normalInfinite();
Но функция того же типа с генератором не создает бесконечный цикл. Он приостанавливается каждый раз, когда вызывается yield, и будет генерировать следующее значение «i» каждый раз, когда вызывается «next()».
Вопрос 38. Объясните асинхронное ожидание в JavaScript?
Ответ.Асинхронное ожидание — это, по сути, промисы под капотом. Но они упростили реализацию кода обещаний. Если обещания упростили код для обратных вызовов, то асинхронное ожидание упростило код для обещаний.
Давайте сначала проверим пример вложенного промиса. Здесь у нас есть три функции, которые возвращают промисы: cleanRoom, removeGarbage и winIcecream. Теперь, когда запускается функция cleanRoom
и из промиса возвращается разрешение, будет запущен немедленный блок .then. В .then мы возвращаем следующее removeGarbage
, а в этом .then мы возвращаем winIcecream
. Мы передаем сообщение из одной функции в другую, поэтому оно будет добавлено.
let cleanRoom = function() { return new Promise(function(resolve, reject) { resolve('Cleaned the room,'); }); }; let removeGarbage = function(message) { return new Promise(function(resolve, reject) { resolve(message + ' removed Garbage,'); }); }; let winIcecream = function(message) { return new Promise(function(resolve, reject) { resolve( message + ' won Icecream'); }); }; cleanRoom().then(function(result){ return removeGarbage(result); }).then(function(result){ return winIcecream(result); }).then(function(result){ console.log(result + ' All Finished'); }) //Cleaned the room, removed Garbage, won Icecream All Finished
Мы рефакторим код с асинхронным ожиданием. Здесь вместо трех функций у нас есть одна функция cleaningTheRoom, перед которой стоит ключевое слово «async». Это означает, что функция будет иметь оператор ожидания. В «ожидании» мы можем получить значение, возвращаемое промисом, сохраненным в переменной. Этот тип кода намного чище, чем обещание.
const cleaningTheRoom = async() => { const cleanRoom = new Promise((resolve, reject) => { resolve('Cleaned the room,');}); const removeGarbage = new Promise((resolve, reject) => { resolve('removed Garbage,');}); const winIcecream = new Promise((resolve, reject) => { resolve(' won Icecream');}); let roomCleaned = await cleanRoom; console.log(roomCleaned); let garbageRemoved = await removeGarbage; console.log(garbageRemoved); let icecreamWon = await winIcecream; console.log(icecreamWon); } cleaningTheRoom().then(() => console.log('All Finished ')); //Cleaned the room, removed Garbage, won Icecream All Finished
То же самое можно еще уменьшить с помощью Promise.all, который переходит на следующую строку только в том случае, если все промисы разрешены. Здесь мы также используем деструктуризацию массива.
const cleaningTheRoom = async() => { const cleanRoom = new Promise((resolve, reject) => { resolve('Cleaned the room,');}); const removeGarbage = new Promise((resolve, reject) => { resolve('removed Garbage,');}); const winIcecream = new Promise((resolve, reject) => { resolve(' won Icecream');}); let [roomCleaned, garbageRemoved, icecreamWon] = await Promise.all([cleanRoom, removeGarbage, winIcecream]); console.log(`${roomCleaned} ${garbageRemoved} ${icecreamWon}`) } cleaningTheRoom().then(() => console.log(' All Finished ')); //Cleaned the room, removed Garbage, won Icecream All Finished
Теперь мы выполняем обработку ошибок в асинхронном ожидании по-другому, чем в промисах. Обратите внимание, что в промисах у нас может быть блок «.catch» для перехвата ошибок из-за отклонения промиса.
В асинхронном ожидании мы заключаем ожидание в блок try-catch.
const cleaningTheRoom = async() => { const cleanRoom = new Promise((resolve, reject) => { reject('Room not cleaned,');}); const removeGarbage = new Promise((resolve, reject) => { resolve('removed Garbage,');}); const winIcecream = new Promise((resolve, reject) => { resolve(' won Icecream');}); try { let roomCleaned = await cleanRoom; console.log(roomCleaned); let garbageRemoved = await removeGarbage; console.log(garbageRemoved); let icecreamWon = await winIcecream; console.log(icecreamWon); } catch(e) { console.log('Error in a promise '); } } cleaningTheRoom().then(() => console.log('All Finished ')); //Error in a promise All Finished
На этом завершается часть 6 серии и вопросы ES6. Часть 7 вы можете найти здесь.