Привет, читатели, я фронтенд-разработчик, работаю с JS уже 3 года и планирую почти столько же времени читать YDKJS Кайла Симпсона, но так и не добился успеха, это еще одна попытка, я буду подытоживать книги. в этих сообщениях, когда я их читаю.
Это первый пост, и в нем я делюсь своими знаниями из первой книги серии «Вверх и вперед».
Эта книга больше похожа на введение в JavaScript, и в ней подчеркивается, как глубокое понимание JavaScript может принести пользу людям, которые его используют, но не знакомы с концепциями, функциями и предостережениями языка или предпочитают игнорировать то, что они не понимают и продолжать работать с неполным знанием языка, которое у них есть.
Некоторые утверждения из книги, которые звонят мне в колокольчик,
Один из самых важных уроков, которые вы можете извлечь из написания кода, заключается в том, что он предназначен не только для компьютера. Код так же важен для разработчика, если не больше, как и для компилятора.
Ваш компьютер заботится только о машинном коде, наборе двоичных нулей и единиц, который получается при компиляции. Вы можете написать почти бесконечное количество программ, которые выдают одну и ту же серию нулей и единиц. Выбор, который вы делаете в отношении написания своей программы, важен не только для вас, но и для других членов вашей команды и даже для вас самих в будущем.
В предисловии к книге подчеркивается важность понимания сложных моментовJavaScript. Я верю в это и, таким образом, пытаюсь понять эти так называемые трудные моменты с помощью этих книг.
Первая глава представляет собой введение в программирование и JS, здесь есть базовое введение в эти понятия,
переменные, условные операторы, выражения, операторы, циклы, функции, области видимости.
Одним из ключевых моментов этой главы является то, что JavaScript динамически типизируется.
В некоторых языках программирования есть переменные, которые могут содержать только определенный тип значения, например число, строку и т. д., называемые языками со статической типизацией.
В то время как некоторые делают упор на тип значений, а не на переменные, это означает, что переменная может содержать значение любого типа в любое время.
JavaScript следует за вторым, поэтому он динамически типизирован.
Что такое типы в JavaScript?
«В JavaScript есть типизированные значения, а не типизированные переменные».
В JavaScript есть 7 типовnumber
, string
, boolean
, object
, null
, undefined
, symbol
.
Любая переменная может содержать значение любого из этих типов в любое время.
Одна давняя ошибка в JavaScript, которая, вероятно, никогда не будет исправлена, заключается в том, что typeof nullвозвращает объект и нет ноль.
object
является одним из наиболее полезных типов значений.
Есть пара других очень полезных и часто используемых типов, array
и function
, это не типы как таковые, а специализированные или подтипы типа object
.
Встроенные методы типов
Встроенные типы и подтипы имеют поведение, представленное в виде свойств и методов, например, тип string
имеет открытый метод toUpperCase()
, который возвращает новую строку, которая является прописной версией строки, в которой toUpperCase()
был вызван.
let x = "hello world"; // x has a string type value stored in it let y = x.toUpperCase() //y now has string "HELLO WORLD" stored in it
В этом примере много чего происходит внутри, для примитивных типов string
,number
,boolean
есть объекты-оболочки String
,Number
,Boolean
соответственно, у которых это поведение представлено как методы и свойства.
Когда вы пытаетесь использовать это поведение для примитивных значений, JavaScript автоматически упаковывает значение в соответствующий объект-оболочку.
Преобразование типов в JavaScript (Приведение)
Типы в JavaScript можно преобразовывать из одного типа в другой, этот процесс преобразования типов называется приведением.
Приведение может быть неявным или явное, когда из кода понятно, что будет преобразование - это явное приведение, например
let numberString = "55"; //typeof numberString == "string" let number = Number(numberString); //typeof number == "number" // the string is converted to number explicitly
когда из кода не ясно, что происходит преобразование значения, это называется неявным приведением, например
let numberString = "55"; //typeof numberString == "string" let twiceNumber = numberString * 2; //typeof twiceNumber == "number" //the string is converted to a number implicitly
Истинные и ложные значения в JavaScript
При преобразовании других типов значений в логический тип только 6 значений преобразуются в false
,эти значения, включая false, называются ложнымизначениями.
"" 0 -0 undefined null NaN false
только эти значения (кроме false) преобразуются в false
во время приведения, все остальные значения преобразуются в true
.
Сравнение значений в JavaScript
Существует два типа сравнений: равенство и неравенство.
Результат любого сравнения строго логическое значение, т. е. true
или false
, независимо от сравниваемых типов.
Операторы сравнения, доступные в JavaScript:
------------- equality operators -------------- == // loose equality != // loose non-equality === // strict equality !== // strict non-equality ------------- inequality operators ------------ > // greater than < // lesser than >= // greater than or equals to <= // lesser than or equals to
==
, ===
, !=
и !==
— это операторы сравнения на равенство, не путайте !=
и !==
с операторами неравенства, они операторы не-равенства и являются просто отрицательными аналогами соответствующих операторов равенства.
Нечеткое равенство и строгое равенство в JavaScript (== vs ===)
Считается, что разница в ==
и ===
заключается в том, что ==
проверяет равенство значений, а ===
проверяет равенство значений и типов, автор заявляет, что это неточно, а точная разница
==
проверяет равенство с допустимым принуждением и === проверяет на равенство с недопустимым принуждением
Это означает, что когда типы операндов различны, значения не равны в случае ===
(строгое равенство), но в случае ==
(нечеткое равенство) значения приводятся к общему типу, а затем значения сравниваются. за равенство.
Алгоритмы для обоих этих операторов можно найти здесь, настоятельно рекомендую прочитать.
Оператор ==
не является транзитивным, т.е.
// a == b and b == c does not mean a ==c. for example new String("a") == "a" // true "a" == new String("a") //true new String("a") == new String("a") // false
Это связано с тем, что при сравнении нового строкового объекта с примитивной строкой “a”
объект приводится к своему примитивному значению в соответствии с алгоритмом свободного равенства, поэтому результат верен, но при сравнении двух новых строковых объектов сравниваются ссылки на объекты. а не значения, и ссылки обоих этих объектов не совпадают, поэтому сравнение дает false.
Алгоритмы ===
(строгие равенства) и sameValue
, которые используются в Object.is()
, различаются между собой.
- их обработка нулями со знаком, 0 и -0 и +0 равны согласно
===
, но неObject.is()
и, NaN
значений,NaN === NaN
ложно, аObject.is(NaN, NaN)
верно
Области действия в JavaScript
Вы можете объявить переменную, которая будет принадлежать текущей области действия функции или глобальной области видимости, если она объявлена вне какой-либо функции.
function foo() { var a = 100; //the variable a belongs to the scope of function foo /* function body */ } var b = 1000; //the variable b is outside any function so it belongs to the global scope var c = a * 100; //Error:: a cannot be accessed outside foo
это область действия в JS, одним из важных понятий является подъем.
Подъем в JavaScript
В приведенном выше примере кода переменная a
объявлена в области видимости функции foo, а также объявлена вверху, поэтому она доступна внутри полной области действия функции.
Но, если его объявить не вверху, то и он будет доступен во всей области действия функции foo, т.к.
объявление var перемещается в начало области действия.
Это называется Поднятие.
Код не переупорядочивается или что-то в этом роде, просто кажется, что объявление перемещено в верхнюю часть области, но подробности этого находятся в процесс компиляции, который мы обсудим позже.
Просто объявление перемещается наверх, а не присваивание. Поэтому, если вы попытаетесь использовать переменную
a
до ее объявления, вы получите значение какundefined
, только после ее присвоения вы сможете получить фактическое значение переменной.
Строгий режим в JavaScript
«Строгий режим» — это, по сути, только строгий режим, когда строгий режим включен, правила ужесточаются для определенного поведения, и эти ограничения рассматриваются для обеспечения большей безопасности кода, а также ограничения строгого режима делают ваш код более оптимизируемым движком.
строгий режим может быть применен к любому уровню, будь то весь файл или область действия функции, это определяется тем, где вы поместили прагму строгого режима
"use strict"; // this enforces strict mode function foo() { "use strict"; } // this way strict mode is enabled for function scopes
Автор рекомендует использовать строгий режим.
Функции в JavaScript
Мы знаем, что такое функции, как они объявляются, вызываются и прочее.
Но одна интересная особенность функций в JavaScript заключается в том, что функции — это просто значения, которые присваиваются переменным, точно так же, как и другие значения (числа, строки и т. д.). Функции можно присваивать переменным, передавать функциям в качестве параметров, возвращать из функций.
Немедленно вызываемые функциональные выражения (IIFE) в JavaScript
Один из способов вызвать функцию — добавить () к имени функции, есть и другой способ
(function foo() { /* function body */ })();
это пример IIFE, существует множество вариантов использования IIFE, они обсуждаются в последующих книгах серии.
Замыкания в JavaScript
Замыкание — очень важная часть языка, оно повсюду, и вы можете использовать его, даже не подозревая об этом.
Закрытие — это, по сути, когда мы можем получить доступ к переменным области видимости функции даже после того, как она завершила выполнение, и память всех ее переменных должна быть очищена.
Замыкания происходят в основном, когда функция возвращает другую функцию, которая использует переменные из области видимости внешней функции, например
function outer() { var x = 10; return function inner(value) { return x + value; } } var y = outer(); // the execution of outer has finished here // the memory assigned to variable x should be freed // and we must not be able to access the value of x from here on y(100); // because of closures we can access x when we are calling y() // this call returns 110 because x is accessible to the inner function
Существует так много применений замыканий, что мы обязательно обсудим их в посте второй книги Scopes & Closures. Одним из примеров, обсуждаемых в этой книге, является
function makeAdder(valueToAdd) { function add(x) { return x + valueToAdd; } return add; } var addOne = makeAdder(1); var addFive = makeAdder(5); addOne(2) // returns 3 addFive(2) // returns 7
Попытайтесь понять приведенный выше код, это то, что делает замыкания такими мощными.
Модули в JavaScript
Одним из основных применений замыканий являются модули. Модули помогают создавать функциональные возможности, в которых можно скрыть частные детали реализации, такие как функции и переменные, и предоставить только общедоступный API, доступный извне. например
function App() { function somePrivateMethod() { // function body } function somePublicMethod() { // function body } var somePublicVariable = 100; var somePrivateVariable = "key"; var publicApi = { somePublicVariable, somePublicMethod, } return publicApi; } var appAPI = App(); // only public api is exposed to the user // rest of the implementation details are hidden appAPI.somePublicMethod() // is accessible appAPI.somePrivateMethod() // ERROR: is not accessbile so is undefined
this
идентификатор в JavaScript
this
— еще одна широко неправильно понимаемая концепция JS. Люди со знанием других языков, таких как Java, могут полагать, что this
связано с объектно-ориентированным поведением, но это не так в JavaScript.
this
ссылка в функции обычно относится к объекту, который зависит от того, как была вызвана функция. Оно не относится к самой функции.
Существуют различные способы вызова функции, мы кратко обсудим, как значение идентификатора this
отличается в этих случаях, это фрагмент кода из книги
function foo() { console.log(this.bar); } bar = "hello"; var obj1 = { bar: "hi", foo: foo, }; var obj2 = { bar: "obj2 hi", }; foo(); /* logs hello without strict mode ** without strict mode the this identifier defaults to the global object ** in strict mode the this identifier defaults to undefined */ obj1.foo(); // logs hi -> this way of calling sets this identifier to obj1 foo.call(obj2) // logs obj2 hi -> this way of calling sets this identifier to obj2 new foo(); // logs undefined -> this way of calling sets this identifier to an empty object
это основные правила, связанные с this
, им посвящены главы в следующих книгах, мы подробно обсудим их в следующих постах.
Прототипы в JavaScript
Механизм прототипа в JavaScript связан с объектами, когда вы пытаетесь получить доступ к свойству объекта, если это свойство отсутствует в объекте, JS пытается найти другой объект из внутренней ссылки на прототип объекта для поиска этого свойства, это это как запасной вариант.
Это внутреннее связывание прототипов происходит, когда объект создается, пример, указанный в книге,
var obj1 = { bar: "bar", } var obj2 = Object.create(obj1); obj2.foo = "foo"; obj2.foo; // "foo" obj2.bar; // "bar" // bar does not exist directly in obj2 but is present in obj1 // and obj1 is added as the prototype of obj2 using object.create() // so JS looks for bar in obj1 and finds "bar"
Это только введение, прототипы подробно обсуждаются в третьей книге this & Object Prototypes.
Полифиллинг и транспиляция в JavaScript
Время от времени выпускаются новые версии языка с новыми функциями, но поддержка этих функций не обязательно доступна сразу, а иногда даже позже.
Чтобы решить эту проблему, у нас есть полифилл, он работает путем добавления фрагмента кода, который эквивалентен поведению новой функции, например, в книге показано, что Number.isNaN()
является новой функцией и может не работать в старых браузерах, поэтому для ее полифилла мы добавляем этот кусок кода
if (!Number.isNaN) { Number.isNaN = function isNaN(x) { return x !== x; }; }
Он проверяет, доступна ли функция, если нет, то добавляет ее.
Полифиллинг работает с новыми функциями, но в случае изменений синтаксиса, которые приходят с новыми обновлениями языка, полифилл нельзя использовать, в этом случае используется транспиляция кода.
Преобразование нового синтаксического кода в старый синтаксический код является транспилированием, транспиляторы используются для транспиляции кода, babel — широко известный и используемый транспилятор.
Некоторые интересные вещи об использовании JavaScript
Как мы знаем, JS в основном написан для взаимодействия с такими средами, как браузер. Большая часть кода, который мы пишем, не контролируется JavaScript, потому что, когда мы используем такие вещи, как document.getElementById()
, кажется, что document
— это объект JS, но это не так, это глобальная переменная, которая является специальным объектом, который называется host objects
.
Функция getElementById
, которую мы вызываем, также выглядит как функция JS, но это всего лишь интерфейс, предоставляемый нам DOM из браузера. В некоторых браузерах это может быть реализовано в самом JS, но чаще всего это реализовано в таких языках, как C/C++ и т. д.
console.log()
и alert
тоже не JS.
Что эта серия сулит нам, разработчикам?
Эта первая книга была введением в язык, все эти концепции подробно объясняются в следующих книгах, список книг в YDKJS:
- Области действия и замыкания. Эта книга призвана прояснить основы областей действия и замыканий в JS, которые имеют решающее значение для понимания JS. Книга начинается с разоблачения неправильного представления о том, что JS интерпретируется, а не интерпретируется, и поэтому мы углубляемся в то, как компилятор читает наш код и работает с объявлениями функций и переменных, затем книга переходит к пониманию лексической области видимости, а затем, наконец, к замыканиям и некоторым варианты использования, такие как шаблон модуля, который мы обсуждали немного ранее.
- this & Object Prototypes — рассказывает о ключевом слове this, которое мы обсуждали ранее, и о четырех правилах, определяющих его значение в вызове функции, затем он переходит к обсуждению прототипного наследования в JS и что это не то же самое, что классы и наследование, а скорее делегирование поведения, автор утверждает, что делегирование поведения является лучшим шаблоном проектирования, чем классы и наследование.
- Типы и грамматика — в этой книге рассказывается о принуждении, обсуждается, как легко и важно его понять, а не игнорируется и избегается принуждение, и клеймит его как изъян языка.
- Асинхронность и производительность. В этой книге обсуждается асинхронное программирование в JS, разбираются параллельные, асинхронные и параллельные функции, обсуждаются обратные вызовы как метод асинхронного программирования, затем обсуждаются связанные с ним проблемы, а затем обсуждаются решения этих проблем. промисами и генераторами, а также охватывает веб-работников и SIMD. Эта книга предназначена для того, чтобы дать вам инструменты и навыки для написания разумного и производительного кода JS.
- ES6 & Beyond. В этой книге говорится, что JS постоянно развивается, и поэтому основное внимание уделяется новым функциям, добавленным в язык в ES6.
Это первая книга из серии. Это было хорошее чтение и обучение для меня, я надеюсь, что это было полезно. Надеюсь не отставать, прочитать всю серию и познакомиться с JS.