Автор оригинала: FreeCodeCamp Community Member.
Густаво Азеведо
JavaScript – самый популярный язык программирования и был с 2014 года, согласно Обзор переполнения стека Отказ Неудивительно, что более 1/3 всех заданий разработчика требуется некоторое знание JavaScript. Итак, если вы планируете работать разработчиком в ближайшее время, вы должны быть знакомы с этим чрезвычайно популярным языком.
Цель поста состоит в том, чтобы объединить все концепции JavaScript, которые часто воспитываются в интервью разработчика. Он был написан, чтобы вы могли просмотреть все, что вам нужно знать о JavaScript в одном месте.
Типы и принуждение
Есть 7 встроенных типов: null
, undefined
, логический
, Номер
, строка
, объект
и Символ
(ES6).
Все это типы называются примитивами, кроме объект
Отказ
typeof 0 // number typeof true // boolean typeof 'Hello' // string typeof Math // object typeof null // object !! typeof Symbol('Hi') // symbol (New ES6)
- Null vs. undefined
Undefined это отсутствие определения. Используется в качестве значения по умолчанию для неинициализированных переменных, функциональные аргументы, которые не были предоставлены и отсутствуют свойства объектов. Функции возвращаются undefined
Когда ничего не было явно возвращено.
Null это отсутствие значения. Это значение назначения, которое можно назначить переменной в виде представления «без значения».
- Неявное принуждение
Посмотрите на следующий пример:
var name = 'Joey'; if (name) { console.log(name + " doesn't share food!") // Joey doesn't share food! }
В этом случае строковая переменная Имя
принужден к правду и у вас есть «Джои не делится едой!» напечатано в нашей консоли. Но откуда вы знаете, что будет принуждено к правде и что будет принуждено к ложным?
Значения Falsy являются значениями, которые будут принуждены к ложь
когда принудило логическое принуждение к нему.
Значения Falsy: ""
, 0
, null
, undefined
, Нан
, ложь
Отказ
Что-то, что явно не явно на фальсивом списке – это правда – Boolean принужден к настоящему Отказ
Boolean(null) // false Boolean('hello') // true Boolean('0') // true Boolean(' ') // true Boolean([]) // true Boolean(function(){}) // true
Да. Вы прочитали это правильно. Пустые массивы, объекты и функции являются логическими принужденными к True!
- Строка и номер принуждения
Первое, что вы должны знать, это +
оператор. Это сложный оператор, потому что он работает как для количества добавления, так и для конкатенации строки.
Но, *,/, и -
Операторы эксклюзивны для числовых операций. Когда эти операторы используются со строкой, она заставляет строку быть принужденной к числу.
1 + "2" = "12" "" + 1 + 0 = "10" "" - 1 + 0 = -1 "-9\n" + 5 = "-9\n5" "-9\n" - 5 = -14 "2" * "3" = 6 4 + 5 + "px" = "9px" "$" + 4 + 5 = "$45" "4" - 2 = 2 "4px" - 2 = NaN null + 1 = 1 undefined + 1 = NaN
- == vs. ===.
Широко распространено, что ==
Проверяет равенство и ===
проверяет равенство и тип. Ну, это заблуждение.
На самом деле, для равенство с принуждением И для равенства без принуждения – Строгое равенство Отказ
2 == '2' // True 2 === '2' // False undefined == null // True undefined === null // False
Принуждение может быть сложно. Посмотрите на следующий код:
Что бы вы ожидали, что следующее сравнение? console.log (а);
(1)
Это сравнение на самом деле возвращает true. Почему? Что действительно происходит под капотом, это то, что если вы сравниваете логический
с чем-то другим, чем логический
JavaScript Coardes, что логический
к Номер
и сравнивает. (2)
Это сравнение сейчас между Номер
и а строка
Отказ JavaScript теперь принудительно, что строка
к Номер
и сравнивает оба количества. (3)
В этом случае окончательное сравнение 0
правда.
'0' == false (1) '0' == 0 (2) 0 == 0 (3)
Для полностью понимания того, как выполняются такие сравнения, вы можете проверить документацию ES5 здесь Отказ
Для чит-листа вы можете нажать здесь Отказ
Некоторые сложные сравнения, чтобы посмотреть на:
false == "" // true false == [] // true false == {} // false "" == 0 // true "" == [] // true "" == {} // false 0 == [] // true 0 == {} // false 0 == null // false
Значение против справки
Простые значения (также известные как примитивы) всегда назначаются Value-Copy: null
, undefined
, логический
, Номер
, строка
и ES6 Символ
Отказ
Составные значения всегда создают копию ссылки на задание: объекты, которые включают массивы и функции.
var a = 2; // 'a' hold a copy of the value 2. var b = a; // 'b' is always a copy of the value in 'a' b++; console.log(a); // 2 console.log(b); // 3 var c = [1,2,3]; var d = c; // 'd' is a reference to the shared value d.push( 4 ); // Mutates the referenced value (object) console.log(c); // [1,2,3,4] console.log(d); // [1,2,3,4] /* Compound values are equal by reference */ var e = [1,2,3,4]; console.log(c === d); // true console.log(c === e); // false
Чтобы скопировать составное значение по значению, вам нужно сделать копия этого. Ссылка не указывает на исходное значение.
Сфера
Область применения относится к контексту выполнения. Он определяет доступность переменных и функций в коде.
Глобальный объем является самой внешней областью. Переменные, объявленные вне функции, находятся в глобальном объеме и могут быть доступны в любой другой области. В браузере окно объект является глобальным объемом.
Местный охват это прицел, вложенный внутри другой объем функций. Переменные, объявленные в местном объеме, доступны в пределах этой области, а также в любых внутренних областях.
function outer() { let a = 1; function inner() { let b = 2; function innermost() { let c = 3; console.log(a, b, c); // 1 2 3 } innermost(); console.log(a, b); // 1 2 — 'c' is not defined } inner(); console.log(a); // 1 — 'b' and 'c' are not defined } outer();
Вы можете подумать о приличиях как серия дверей, уменьшающихся по размеру (от наибольшего до самого маленького). Короткий человек, который подходит через самую маленькую дверь – внутренняя область охвата – также подходит через любые большие двери – внешние области Отказ
Высокий человек, который застрял на третьей двери, например, будет иметь доступ ко всем предыдущим дверям – внешние области – Но не какие-то дополнительные двери – Внутренние области Отказ
Подъемник
Поведение «движущихся» var
и Функция
Декларации к вершине их соответствующих областей на этапе компиляции называются Подъем Отказ
Декларации функций полностью поднимаются. Это означает, что заявленная функция может быть вызвана, прежде чем она определяется.
console.log(toSquare(3)); // 9 function toSquare(n){ return n*n; }
Переменные частично поднимаются. var
Декларации поднимаются, но не его задания.
Пусть
и Const
не поднимаются.
{ /* Original code */ console.log(i); // undefined var i = 10 console.log(i); // 10 } { /* Compilation phase */ var i; console.log(i); // undefined i = 10 console.log(i); // 10 } // ES6 let & const { console.log(i); // ReferenceError: i is not defined const i = 10 console.log(i); // 10 } { console.log(i); // ReferenceError: i is not defined let i = 10 console.log(i); // 10 }
Функция Expression vs. Функциональная декларация
- Функция выражение Выражение функции создается, когда выполнение достигает его и используется с этого, не поднимается.
var sum = function(a, b) { return a + b; }
- Декларация функции Декларация функции может быть названа как до, так и после того, как она была определена – он поднимается.
function sum(a, b) { return a + b; }
Переменные: var, пусть и const
До ES6, можно было только объявить переменную, используя var
Отказ Переменные и функции, объявленные внутри другой функции, не могут быть доступны любым из ограждений – они находятся на определенном режиме.
Переменные, объявленные внутри сферы блока, такие как Если
заявления и для
Петли, могут быть доступны от внешней части отверстия и закрытия фигурных скобок блока.
Примечание : Необъявленная переменная – назначение без var
, Пусть
или Const
– Создает var
переменная в глобальном масштабе.
function greeting() { console.log(s) // undefined if(true) { var s = 'Hi'; undeclaredVar = 'I am automatically created in global scope'; } console.log(s) // 'Hi' } console.log(s); // Error — ReferenceError: s is not defined greeting(); console.log(undeclaredVar) // 'I am automatically created in global scope'
ES6 Пусть
и Const
новые. Они не поднимаются и наведут блокировку альтернативы для переменной декларации. Это означает, что пару фигурных скобок определяют объем, в котором переменные, объявленные либо пусть или Const, ограничены.
let g1 = 'global 1' let g2 = 'global 2' { /* Creating a new block scope */ g1 = 'new global 1' let g2 = 'local global 2' console.log(g1) // 'new global 1' console.log(g2) // 'local global 2' console.log(g3) // ReferenceError: g3 is not defined let g3 = 'I am not hoisted'; } console.log(g1) // 'new global 1' console.log(g2) // 'global 2'
Обычное заблуждение в том, что Const
неизменно. Это не может быть переназначено, но его свойства могут быть изменился !
const tryMe = 'initial assignment'; tryMe = 'this has been reassigned'; // TypeError: Assignment to constant variable. // You cannot reassign but you can change it… const array = ['Ted', 'is', 'awesome!']; array[0] = 'Barney'; array[3] = 'Suit up!'; console.log(array); // ["Barney", "is", "awesome!", "Suit up!"] const airplane = {}; airplane.wings = 2; airplane.passengers = 200; console.log(airplane); // {passengers: 200, wings: 2}
Закрытие
А закрытие Это сочетание функции и лексической среды, из которой она была объявлена. Закрытие позволяет функцию доступа к переменным от ограждения – окружающая среда – Даже после того, как он покидает объем, в котором он был объявлен.
function sayHi(name){ var message = `Hi ${name}!`; function greeting() { console.log(message) } return greeting } var sayHiToJon = sayHi('Jon'); console.log(sayHiToJon) // ƒ() { console.log(message) } console.log(sayHiToJon()) // 'Hi Jon!'
Приведенный выше пример охватывает две вещи, которые вам нужно знать о закрытиях:
- Относится к переменным во внешнем объеме. Возвращенная функция доступа к
сообщение
Переменная от ограждения. - Он может ссылаться на переменные внешних областей, даже после возврата внешней функции.
Сайхитожон
ссылка наприветствие
Функция, созданная, когдаСайхи
был запущен.приветствие
Функция поддерживает ссылку на ее внешний объем – окружающая среда – в которомсообщение
существуют.
Одним из основных преимуществ закрытий является то, что это позволяет Инкапсуляция данных Отказ Это относится к идее, что некоторые данные не должны быть напрямую открытыми. Следующий пример иллюстрирует это.
К тому времени Элементарный
Создан внешняя функция уже вернулась. Это означает, что Персонал
Переменная существует только внутри закрытия, и она не может быть доступен в противном случае.
function SpringfieldSchool() { let staff = ['Seymour Skinner', 'Edna Krabappel']; return { getStaff: function() { console.log(staff) }, addStaff: function(name) { staff.push(name) } } } let elementary = SpringfieldSchool() console.log(elementary) // { getStaff: ƒ, addStaff: ƒ } console.log(staff) // ReferenceError: staff is not defined /* Closure allows access to the staff variable */ elementary.getStaff() // ["Seymour Skinner", "Edna Krabappel"] elementary.addStaff('Otto Mann') elementary.getStaff() // ["Seymour Skinner", "Edna Krabappel", "Otto Mann"]
Давайте углубимся в закрытие, решив одно из самых распространенных проблем собеседования на эту тему: что не так с следующим кодом и как бы вы это исправить?
const arr = [10, 12, 15, 21]; for (var i = 0; i < arr.length; i++) { setTimeout(function() { console.log(`The value ${arr[i]} is at index: ${i}`); }, (i+1) * 1000); }
Учитывая вышеуказанный код, консоль отобразит четыре одинаковых сообщения «Значение undefined - это индекс: 4"
Отказ Это происходит, потому что каждая функция, выполняемая в цикле, будет выполнена после завершения всей циклы, ссылается на последнее значение, сохраненное в Я
, который был 4.
Эта проблема может быть решена с помощью IIFE, которая создает уникальный объем для каждой итерации и хранения каждого значения в его объеме.
const arr = [10, 12, 15, 21]; for (var i = 0; i < arr.length; i++) { (function(j) { setTimeout(function() { console.log(`The value ${arr[j]} is at index: ${j}`); }, j * 1000); })(i) }
Другое решение будет объявлять Я
Переменная с Пусть
что создает тот же результат.
const arr = [10, 12, 15, 21]; for (let i = 0; i < arr.length; i++) { setTimeout(function() { console.log(`The value ${arr[i]} is at index: ${i}`); }, (i) * 1000); }
Немедленное вызываемое выражение функции (IIFE)
IIFE – это выражение функции, которое называется сразу после его определения. Обычно используется, когда вы хотите создать новую переменную область.
(окружающие скобки) Предотвращает лечение его в качестве декларации функции.
Последняя скобка () выполняют функцию выражения.
На IIFE вы называете функцию именно, когда вы определяете ее.
var result = []; for (var i=0; i < 5; i++) { result.push( function() { return i } ); } console.log( result[1]() ); // 5 console.log( result[3]() ); // 5 result = []; for (var i=0; i < 5; i++) { (function () { var j = i; // copy current value of i result.push( function() { return j } ); })(); } console.log( result[1]() ); // 1 console.log( result[3]() ); // 3
Использование IIFE:
- Позволяет прикрепить личные данные к функции.
- Создает свежие среды.
- Избегает загрязнения глобального пространства имен.
Контекст
Контекст часто путают как то же самое, что и сферу. Чтобы прояснить вещи, давайте будем иметь в виду следующее: Контекст чаще всего определяется тем, как вызывается функция. Это всегда относится к стоимости это
в определенной части вашего кода. Область Относится к видимости переменных.
Функциональные вызовы: вызов, применить и связываться
Все эти три метода используются для прикрепления это
в функцию и разница находится в вызове функций.
.call ()
Призывает функцию немедленно и требует от вас в аргументах в виде списка (один за другим).
.apply ()
Призывает функцию немедленно и позволяет передавать аргументы в качестве массива.
.call ()
и .apply ()
в основном эквивалентны и используются для одобрения метода от объекта. Выбирая, какой из них используется, зависит от того, что из них легче пройти аргументы в. Просто решите, проще пройти в массиве или запятее в списке аргументов.
Быстрый совет: Подать заявку на А Рэй – C . Все за C ОММА.
const Snow = {surename: 'Snow'} const char = { surename: 'Stark', knows: function(arg, name) { console.log(`You know ${arg}, ${name} ${this.surename}`); } } char.knows('something', 'Bran'); // You know something, Bran Stark char.knows.call(Snow, 'nothing', 'Jon'); // You know nothing, Jon Snow char.knows.apply(Snow, ['nothing', 'Jon']); // You know nothing, Jon Snow
Примечание Если вы проходите в массиве в качестве одного из аргументов в функции вызова, это будет относиться к тому, что весь массив в виде одного элемента. ES6 позволяет нам распространять массив в качестве аргументов с функцией вызова.
char.knows.call(Snow, ...["nothing", "Jon"]); // You know nothing, Jon Snow
.bind ()
Возвращает новую функцию с определенным контекстом и параметрами. Обычно используется, когда вы хотите, чтобы функция была вызвана позже с определенным контекстом.
Это возможно благодаря его способности поддерживать данный контекст для вызова оригинальной функции. Это полезно для асинхронных обратных вызовов и событий.
.bind ()
Работает как функция вызова. Это требует, чтобы вы проходили в аргументах один за другим, разделенным запятой.
const Snow = {surename: 'Snow'} const char = { surename: 'Stark', knows: function(arg, name) { console.log(`You know ${arg}, ${name} ${this.surename}`);} } const whoKnowsNothing = char.knows.bind(Snow, 'nothing'); whoKnowsNothing('Jon'); // You know nothing, Jon Snow
«Это» ключевое слово
Понимание ключевого слова это
В JavaScript и то, что он ссылается, может быть довольно сложным время от времени.
Значение это
обычно определяется контекстом выполнения функций. Контекст выполнения просто означает, как называется функция.
Ключевое слово . это
Выступает в качестве заполнителя и будет относиться к тому, что объект называется этим методом, когда метод на самом деле используется.
Следующий список являются упорядоченными правилами для определения этого. Остановитесь на первом, который применяется:
- Новый Привязка – При использовании
Новый
Ключевое слово для вызова функции,это
это вновь построенный объект.
function Person(name, age) { this.name = name; this.age =age; console.log(this); } const Rachel = new Person('Rachel', 30); // { age: 30, name: 'Rachel' }
- Явная привязка – При звонке или применении используются для вызова функции,
это
это объект, который передается в качестве аргумента. Примечание :.bind ()
Работает немного по-другому. Он создает новую функцию, которая позвонит оригиналу с объектом, который был связан с ним.
function fn() { console.log(this); } var agent = {id: '007'}; fn.call(agent); // { id: '007' } fn.apply(agent); // { id: '007' } var boundFn = fn.bind(agent); boundFn(); // { id: '007' }
- Неявное привязку – Когда функция вызывается с контекстом (содержащий объект),
это
это объект, который функция является свойством. Это означает, что функция называется как метод.
var building = { floors: 5, printThis: function() { console.log(this); } } building.printThis(); // { floors: 5, printThis: function() {…} }
- Привязка по умолчанию – Если ни одно из вышеуказанных правил не применяется,
это
Это глобальный объект (в браузере, это окно объекта). Это происходит, когда функция называется автономной функцией. Функция, которая не объявлена методом, автоматически становится свойством глобального объекта.
function printWindow() { console.log(this) } printWindow(); // window object
Примечание : Это также происходит при вызове автономной функции из внешней функции.
function Dinosaur(name) { this.name = name; var self = this; inner(); function inner() { alert(this); // window object — the function has overwritten the 'this' context console.log(self); // {name: 'Dino'} — referencing the stored value from the outer context } } var myDinosaur = new Dinosaur('Dino');
- Лексический этот – Когда функция называется функцией стрелки
=>
,это
получаетэто
Значение его окружающей массы в то время его создано.это
Сохраняет значение из своего исходного контекста.
function Cat(name) { this.name = name; console.log(this); // { name: 'Garfield' } ( () => console.log(this) )(); // { name: 'Garfield' } } var myCat = new Cat('Garfield');
Строгий режим
JavaScript выполняется в строгом режиме с помощью «Используйте Strict»
Директива. Строгий режим Затягивает правила для разбора и обработки ошибок в вашем коде.
Некоторые из его преимуществ:
- Делает отладки проще – ошибки кода, которые в противном случае были бы проигнорированы, теперь будут генерировать ошибки, такие как присвоение неиспорченного глобального или имущества.
- Предотвращает случайные глобальные переменные – Назначение стоимости неразработанной переменной теперь будет выбросить ошибку.
- Предотвращает недействительное использование удаления – Попытки удаления переменных, функций и неотъемлемых свойств теперь будут бросать ошибку.
- Предотвращает дублирующие имена свойств или значений параметров – Дублированное названное свойство в объекте или аргументе в функции теперь будет бросать ошибку. (Это больше не так в ES6)
- Делает Eval () безопаснее – Переменные и функции, объявленные внутри
Eval ()
Заявление не создается в окрестностях. - «Защиты» JavaScript устраняет это принуждение – ссылается на
это
Значение NULL или undefined не принуждается к глобальному объекту. Это означает, что в браузерах больше не возможно, чтобы ссылаться на объект окна, используяэто
внутри функции.
`Новый`
Новый
ключевое слово вызывает функцию специально. Функции, вызываемые с использованием Новый
Ключевое слово называется Конструктор Функции Отказ
Так что же делает Новый
Ключевое слово на самом деле делает?
- Создает новый объект.
- Устанавливает Объект Прототип быть прототипом из Функция конструктора Отказ
- Выполняет функцию конструктора с
это
как вновь созданный объект. - Возвращает созданный объект. Если конструктор возвращает объект, этот объект возвращается.
// In order to better understand what happens under the hood, lets build the new keyword function myNew(constructor, ...arguments) { var obj = {} Object.setPrototypeOf(obj, constructor.prototype); return constructor.apply(obj, arguments) || obj }
В чем разница между вызовом функции с Новый
Ключевое слово и без него?
function Bird() { this.wings = 2; } /* invoking as a normal function */ let fakeBird = Bird(); console.log(fakeBird); // undefined /* invoking as a constructor function */ let realBird= new Bird(); console.log(realBird) // { wings: 2 }
Прототип и наследование
Прототип является одним из самых запутанных концепций в JavaScript и одной из причин этого, потому что есть два разных контекста, в которых слово Прототип используется.
- Прототип отношения Каждый объект имеет Прототип Объект, из которого он наследует все свойства его прототипа.
.__ Proto__
это нестандартный механизм (доступен в ES6) для извлечения прототипа объекта (*) Отказ Это указывает на «родительский родитель» – Прототип объекта Отказ Все нормальные объекты также наследуют.constructor
Свойство, которое указывает на конструктор объекта. Всякий раз, когда объект создан из функции конструктора,.__ Proto__
Ссылки на свойство этого объекта к.Прототип
Свойство конструкторной функции, используемой для его создания. (*)Object.getPrototyep ()
Стандартная функция ES5 для извлечения прототипа объекта. - Прототип недвижимости Каждая функция имеет
.Прототип
имущество. Он ссылается на объект, используемый для прикрепления свойств, которые будут унаследоваться объектами дальше вниз по цепочке прототипа. Этот объект содержит, по умолчанию, A.constructor
Свойство, которое указывает на оригинальную функцию конструктора. Каждый объект, созданный с функцией конструктора, наследует свойство конструктора, которое указывает на эту функцию.
function Dog(breed, name){ this.breed = breed, this.name = name } Dog.prototype.describe = function() { console.log(`${this.name} is a ${this.breed}`) } const rusty = new Dog('Beagle', 'Rusty'); /* .prototype property points to an object which has constructor and attached properties to be inherited by objects created by this constructor. */ console.log(Dog.prototype) // { describe: ƒ , constructor: ƒ } /* Object created from Dog constructor function */ console.log(rusty) // { breed: "Beagle", name: "Rusty" } /* Object inherited properties from constructor function's prototype */ console.log(rusty.describe()) // "Rusty is a Beagle" /* .__proto__ property points to the .prototype property of the constructor function */ console.log(rusty.__proto__) // { describe: ƒ , constructor: ƒ } /* .constructor property points to the constructor of the object */ console.log(rusty.constructor) // ƒ Dog(breed, name) { ... }
Цепь прототипа
Цепь прототипов представляет собой серию связей между объектами, которые ссылаются друг на друга.
В поисках свойства в объекте JavaScript Engine Engine старается получить доступ к тому, что свойство на самом объекте.
Если не найден, JavaScript Engine будет искать, что свойство на объекте он унаследовал свои свойства от – Прототип объекта Отказ
Двигатель пройдет в цепь, которая ищет это свойство и вернуть первый, который он находит.
Последний объект в цепочке является встроенный Объект. Прототип
, который имеет null
как его Прототип Отказ Как только двигатель достигнет этого объекта, он возвращает undefined
Отказ
Собственные против унаследованных свойств
Объекты имеют собственные свойства и унаследованные свойства.
Собственные свойства являются свойствами, которые были определены на объекте.
Унаследованные свойства были унаследованы через цепочку прототипа.
function Car() { } Car.prototype.wheels = 4; Car.prototype.airbags = 1; var myCar = new Car(); myCar.color = 'black'; /* Check for Property including Prototype Chain: */ console.log('airbags' in myCar) // true console.log(myCar.wheels) // 4 console.log(myCar.year) // undefined /* Check for Own Property: */ console.log(myCar.hasOwnProperty('airbags')) // false — Inherited console.log(myCar.hasOwnProperty('color')) // true
Object.Create ( Obj ) – Создает новый объект с указанным Прототип объект и свойства.
var dog = { legs: 4 }; var myDog = Object.create(dog); console.log(myDog.hasOwnProperty('legs')) // false console.log(myDog.legs) // 4 console.log(myDog.__proto__ === dog) // true
Наследование по ссылке
Унаследованное свойство – это копия посредством ссылки Прототип объекта имущество, из которого он унаследовал эту собственность.
Если свойство объекта мутируется на прототипе, объекты, которые наследуют, что свойство будет делиться той же мутацией. Но если собственность заменяется, изменение не будет передано.
var objProt = { text: 'original' }; var objAttachedToProt = Object.create(objProt); console.log(objAttachedToProt.text) // original objProt.text = 'prototype property changed'; console.log(objAttachedToProt.text) // prototype property changed objProt = { text: 'replacing property' }; console.log(objAttachedToProt.text) // prototype property changed
Классическое наследование по сравнению с прототипом наследования
В классическом наследстве объекты наследуют от классов – как проект или описание объекта, которое будет создано – и создавать отношения подкладка. Эти объекты создаются через функции конструктора с использованием нового ключевого слова.
Недостатком классического наследства заключается в том, что это вызывает:
- негибкая иерархия
- плотные проблемы сцепления
- Хрупкие проблемы базового класса
- проблемы дублирования
- И такая известная горилла/банановая проблема – «То, что вы хотели, был бананом, то, что у вас была горилла, держа банана, и все джунгли».
В прототиповом наследстве объекты наследуют непосредственно от других объектов. Объекты обычно создаются через Object.Create ()
, объектные литералы или фабричные функции.
Есть три различных вида прототипов наследования:
- Прототип делегация – Прототип делегата является объектом, который используется в качестве модели для другого объекта. Когда вы наследуете от прототипа делегата, новый объект получает ссылку на прототип и его свойства. Этот процесс обычно осуществляется с помощью
Object.Create ()
Отказ - Согласно наследство – процесс наследования свойств от одного объекта к другому, копируя свойства прототипа объекта, не сохраняя ссылку между ними. Этот процесс обычно осуществляется с помощью
Объект.assign ()
Отказ - Функциональное наследование – Этот процесс использует Функция завода (*) Чтобы создать объект, а затем добавляет новые свойства непосредственно на созданный объект. Этот процесс имеет преимущество в том, что обеспечивает инкапсуляцию данных через закрытие. (*) Функция завода это функция, которая не является классом или конструктором, который возвращает объект без использования
Новый
ключевое слово.
const person = function(name) { const message = `Hello! My name is ${name}`; return { greeting: () => console.log(message) } } const will = person("Will"); will.greeting(); // Hello! My name is Will
Вы можете найти полную статью по этой теме Эрик Эллиотт здесь Отказ
Производитель состав над наследством класса
Многие разработчики согласны с тем, что наследство класса следует избегать в большинстве случаев. В этом шаблоне вы разработаете свои типы относительно того, что они являются , что делает его очень строгим узором.
Состав, с другой стороны, вы разработаете свои типы относительно того, что они сделать , что делает его более гибким и многоразовым.
Вот хорошее видео на этой теме Mattias Petter johansson
Асинхронный JavaScript
JavaScript – это однопоточный язык программирования. Это означает, что JavaScript Engine может обрабатывать только кусок кода одновременно. Одним из его основных последствий является то, что когда JavaScript сталкивается с куском кода, который требует много времени для обработки, он заблокирует весь код после этого от работы.
JavaScript использует структуру данных, которая хранит информацию о активных функциях имени Стек вызовов Отказ Стек вызовов похож на кучу книг. Каждая книга, которая входит в эту кучу, сидит на вершине предыдущей книги. Последняя книга, которую нужно войти в кучу, будет первым, удаленным из нее, и первая книга, добавленная к кучу, будет удалена последней.
Решение для выполнения тяжелых кусочков кода без блокировки ничего не является Функции асинхронного обратного вызова Отказ Эти функции выполняются позже – асинхронно Отказ
Асинхронный процесс начинается с асинхронных функций обратного вызова, помещенного в Куча или Регион памяти. Вы можете думать о куче как Менеджер событий Отказ Стек вызовов спрашивает менеджер событий выполнить определенную функцию только тогда, когда произойдет определенное событие. Как только это событие произойдет, менеджер событий перемещает функцию к очереди обратного вызова. Примечание : Когда менеджер событий обрабатывает функцию, код после этого не заблокирован, и JavaScript продолжает его выполнение.
Контур событий обрабатывает выполнение нескольких кусков вашего кода со временем. Контур событий контролирует стек вызовов и очереди обратного вызова.
Стек вызовов постоянно проверяется, пусто он или нет. Когда он пуст, очередь обратного вызова проверяется, если есть функция, ожидающая, когда вызывается. Когда есть ожидание функции, первая функция в очереди нажимается в стек вызова, который будет запускать его. Этот процесс проверки называется «тик» в контуре события.
Давайте сломаем выполнение следующего кода, чтобы понять, как работает этот процесс:
const first = function () { console.log('First message') } const second = function () { console.log('Second message') } const third = function() { console.log('Third message') } first(); setTimeout(second, 0); third(); // Output: // First message // Third message // Second message
- Первоначально консоль Browser Console понятен, а стек вызовов и менеджер событий пусты.
Сначала ()
добавляется в стек вызова.Console.log («Первое сообщение»)
добавляется в стек вызова.Console.log («Первое сообщение»)
выполняется и консоль браузера отображается «Первое сообщение» ОтказConsole.log («Первое сообщение»)
удаляется из стека вызовов.Сначала ()
удаляется из стека вызовов.Settimeout (второй, 0)
добавляется в стек вызова.Settimeout (второй, 0)
выполняется и обрабатывается менеджером событий. И после 0 мс менеджер событий перемещаетсявторой ()
к очереди обратного вызова.Settimeout (второй, 0)
сейчас завершается и удален из стека вызовов.В-третьих ()
добавляется в стек вызова.console.log («Третье сообщение»)
добавляется в стек вызова.console.log («Третье сообщение»)
выполняется и консоль браузера отображается «Третье сообщение» Отказconsole.log («Третье сообщение»)
удаляется из стека вызовов.В-третьих ()
удаляется из стека вызовов.- Стек вызовов теперь пуст и
второй ()
Функция ждет, чтобы быть вызвана в очереди обратного вызова. - Структура событий движется
второй ()
от очереди обратного вызова в стек вызова. Console.log («Второе сообщение»)
добавляется в стек вызова.Console.log («Второе сообщение»)
выполняется и консоль браузера отображается «Второе сообщение» ОтказConsole.log («Второе сообщение»)
удаляется из стека вызовов.второй ()
удаляется из стека вызовов.
Примечание : второй ()
Функция не выполняется после 0 мс. время Вы проходите в Сетримс
Функция не относится к задержке его выполнения. Менеджер событий ждет данного времени перед перемещением этой функции в очередь обратного вызова. Его исполнение пройдет только на будущем «галочка» в петле события.
Спасибо и поздравляю для чтения до этого момента! Если у вас есть какие-либо мысли об этом, не стесняйтесь оставить комментарий.