Привет, я Ральф. Я занят написанием своего первого приложения JavaScript, которое представляет собой инструмент обучения на основе конечных элементов (принцип физики / инженерии) с использованием графики React, Redux и Three JS. Мне довольно сложно писать статьи, но я считаю, что попытки что-то объяснить заставляют меня задуматься.
Как полный новичок в JavaScript, я представлял, прежде чем начать, что это будет легко, я много лет работаю в объектно-ориентированном программировании с C++/C#, и весь синтаксис выглядит очень похожим, однако я не оценил, как много еще предстоит узнать, JavaScript, HTML, CSS, TypeScript, React, Redux…
Вот некоторые из концепций, на изучение которых я потратил свое время:
Функция стрелки () =› {
Хотя я видел это до того, как перешел на C#, я познакомился с ним только в JavaScript. Давайте рассмотрим несколько примеров:
// Create a function with empty parentheses so nothing is passed in const myFunction1 = () => { return “Hello” } // returns: Hello // Pass in a name parameter and concatenate it to Hello, const myFunction2 = (name) => { return “Hello “ + name } // returns: Hello Fred // With only a single line the return and curly braces aren’t needed const myFunction3 = (name) => “Hello “ + name // With only a single parameter the brackets aren’t needed either const myFunction4 = name => “Hello “ + name // Default values can be set on the parameters to override when nothing is passed const myFunction5 = (name = “Grace”) => “Hello “ + name //Call myFunction5() returns: Hello Grace var myFunction6 = { i: 25, arrowF: () => this.i, regularF: function() {return this.i;} } myFunction6.arrowF(); // returns undefined, because the arrow function is self contained and does not have a ‘this’ myFunction6.regularF(); // returns 10,
Стрелочные функции очень полезны, когда вы хотите написать аккуратный лаконичный код для обработки коллекций, массивов или списков объектов.
Вот несколько хороших примеров
const nums = [5, 7, 16, 0, 1, 22, 29]; const sum = nums.reduce((a, b) => a + b); // returns 80 const even = nums.filter(v => v % 2 == 0); // returns 16,0,22 const double = nums.map(v => v * 2); // returns 10,14,32,0,2,44,58
Возврат функции из функции
В простой форме внутренняя приватная функция «квадрат» вызывается возвратом
function hyp(a, b) { function square(num) { return num * num; } return Math.sqrt(square(a) + square(b)); } hyp(5,12) // returns: 13
Но что, если я хочу внешне вызвать функцию внутри функции, как если бы я делал это из класса, возможно, с геттером или общедоступным методом:
function counter() { let x = 0 return { incr: function () {return x++}, //Increment after the return decr: function () {return x — } } } let s = counter() //Invoke the counter and initialise the variable s.incr() //Returns: 0 s.incr() //Returns: 1 s.incr() //Returns: 2 s.decr() //Returns: 1
Теперь я могу использовать функцию как класс, хранить и поддерживать переменные, придавать ей функциональность и доступность.
Я не вижу, чтобы эта техника часто использовалась, но она дает мне ощущение знакомого класса 🙂
Подъем
Странная концепция использования переменной перед ее объявлением называется подъемом, объявление поднимается вверх:
num = 10 alert(num) //10 is alerted var num var num2 num2 = 22 alert(num2) //22 is alerted
Это не относится к let или const, хотя для меня все это произвольно, так как я всегда буду следовать соглашению и в любом случае объявлять сначала, это просто хорошая практика.
Три точки… Отдохни и расправься
Это было введено в ES6 и имеет несколько приложений:
остальные и спред операторы
Отдых, это позволяет нам быть очень гибкими с параметрами, которые мы передаем:
function myFunc(a, b, …args) { return a + b + args.reduce((a, b) => a + b) }; myFunc(22, 98, 43, 3, 26) // Returns 192 myFunc(22, 98, 43, 3, 26, 45, 22, 17) // Returns 276
Мы можем добавить столько аргументов, сколько захотим, и они добавляются в любой массив, чтобы делать то, что нам нравится.
Распространять
var oldOne = { model: ‘Mk1’, wheels: 4 }; var newerOne = { model: ‘Mk2’, satnav: true, cruise: false }; var evenNewerOne = { model: ‘Mk3’, cruise: true } var mergedObj = { …oldOne, …newerOne, …evenNewerOne }; // Object {“model”:”Mk3",”wheels”:4,”satnav”:true,”cruise”:true}
Это аккуратный способ выбрать все поля из любого из объектов, независимо от того, присутствуют ли они во всех из них или нет, и объединить их с последующими объектами, перезаписывая данные из любых предыдущих.
Это особенно полезно с React и Redux, когда мы не хотим мутировать объекты, это позволяет нам взять все существующие части существующего объекта, заменить устаревшие части и создать новый объект для возврата очень лаконичным образом.
Двойные фигурные скобки в jsx {{ }}
В первый раз, когда я увидел это, это смутило меня, но когда я понял немного больше и подумал об этом, тогда это обрело смысл.
Внешний набор при использовании в jsx означает Javascript, встроенный в jsx.
Внутренний набор содержит поля объекта. Просто действительно!
<MusicItem album={{band: “Arcade Fire”, title: “Funeral”, year: 2004}} />
Реквизит в Redux
Много читая о том, как структурировать мой код и как будет выглядеть архитектура, я получил много положительных отзывов о достоинствах Redux для управления состоянием и реализации структурированного однонаправленного потока управления и данных.
Единственный способ узнать об этом на самом деле - это попробовать, так что это то, к чему меня привело.
В Redux компонент используется для отображения определенного раздела страницы, каким бы маленьким он ни был.
Он должен быть автономным, чтобы его можно было бросить в любое место, которое нам нравится, и вести себя и выглядеть одинаково. Если бы это был просто статический контент, тогда все в порядке.
<div> <h1>Title</h1> </div>
Нет необходимости что-либо передавать этому или запускать что-либо из него.
Если мы хотим сделать его немного интереснее, ему понадобится «реквизит».
<div className=”item”> <input type=”checkbox” checked={props.checked} onChange={() => props.handleChange()} /> <p>{props.text}</p> </div>
Этот компонент очень простой, но это универсальный флажок. Мы хотели бы передать ему следующие реквизиты для предоставления отображаемой информации:
- проверил
- текст
и обработчик событий:
- ручка изменения
Чтобы сделать это в Redux, параметры отображения будут поступать из хранилища Redux и, следовательно, будут привязаны к состоянию, когда мы подключаем компонент к хранилищу.
const mapStateToProps = (state) => { return{ checked: state.item.checked, text: state.item.text, id: state.item.id, } }
Эта команда назначает реквизиты checked, text и id, используемые компонентом, соответствующим полям состояния. Когда у вас есть приложение, заполненное состоянием, эти сопоставления можно смешивать и сопоставлять из любого места в глобальном состоянии, что делает его очень гибким.
Обработчик будет переданной функцией, которая может быть назначена и запущена извне, когда пользователь установит флажок.
const mapDispatchToProps = dispatch => { return { handleChange: () => {dispatch(checkboxChangeAction())}, } } export default connect( mapStateToProps, mapDispatchToProps )(CustomCheckbox)
Подключение к хранилищу позволяет нам объединить все определения реквизита и создать компонент.
нулевые и неопределенные проверки с помощью &&
Традиционно && является логическим оператором для комбинирования условной проверки, и из-за того, как он работает, он нашел удобный способ проверки нулей. Возьмите этот пример, написанный традиционно:
let result = “no-one” if(object1 != null) { result = object1.name }
object1 может быть создан или не создан, и если это не так, будет выдана ошибка, поэтому выполняется проверка.
result = object1 && object1.name
Из-за того, как работает &&, если первая проверка ложна (проверка объекта1 null или неопределенная проверка), то вторая не выполняется, тем самым завершая строку и защищая от ошибки.
Проверка ===
Из-за того, что JavaScript довольно свободно обрабатывает переменные по сравнению с более структурированными языками, это дополнительное сравнение особенно полезно.
Самый простой способ демонстрации — показать несколько примеров:
//Check the value only (0 and 0) with double equals (‘0’ == 0) ? “Same”: “Different” // Returns Same //Check the value and type (0 and 0, string and number) with triple equals (‘0’ === 0) ? “Same”: “Different” // Returns Different (null == undefined) ? “Same”: “Different” // Returns Same (null === undefined) ? “Same”: “Different” // Returns Different
Двойное равенство выполняет принуждение, которое преобразует значения переменных в один и тот же тип перед выполнением сравнения.
Закрытие
Замыкание — это фундаментальная концепция того, что находится в масштабе и видимо в конкретных функциях, это то, что я должен признать, что у меня есть приблизительное представление о том, что я не могу претендовать на понимание более тонких деталей. Мой следующий этап обучения — освоиться с этим и немного попрактиковаться.
Всегда есть чему поучиться!
Если вы заметите здесь какие-либо ошибки, дайте мне знать.