Привет, я Ральф. Я занят написанием своего первого приложения 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

Двойное равенство выполняет принуждение, которое преобразует значения переменных в один и тот же тип перед выполнением сравнения.

Закрытие

Замыкание — это фундаментальная концепция того, что находится в масштабе и видимо в конкретных функциях, это то, что я должен признать, что у меня есть приблизительное представление о том, что я не могу претендовать на понимание более тонких деталей. Мой следующий этап обучения — освоиться с этим и немного попрактиковаться.

Всегда есть чему поучиться!

Если вы заметите здесь какие-либо ошибки, дайте мне знать.