12 концепций, которые прокачают ваш JavaScript

Frontend

Несмотря на уровень знаний вы должны понимать основополагающие концепции языка. Эти 12 концепций, конечно, не охватывают всего, что должен знать разработчик, но важны для любого JS-программиста.

Присвоения примитивных и ссылочных типов

Понимание того, как JavaScript присваивает значение переменной, является залогом работающего кода. Без этого вы можете легко написать код, который непреднамеренно будет изменять значения переменных.

JavaScript всегда использует присвоение по значению. И это очень важно: когда присваиваемое значение является одним из 5 JavaScript’овых примитивов (BooleannullundefinedString и Number) — присваивается фактическое значение. Однако, когда присваиваемое значение является типом ArrayFunction или Object, присваивается ссылка на объект в памяти.

Например, в коде ниже переменной var2 присваивается значение var1. Т. к. var1 является примитивом (String), то переменной var2присваивается строковое значение var1, и она может рассматриваться как отдельная (независимая) переменная. Соответственно, изменения var2 никак не отразятся на var1.

let var1 = 'My string';
let var2 = var1;

var2 = 'My new string';

console.log(var1);
// 'My string'
console.log(var2);
// 'My new string'

А теперь попробуем то же самое с типом Object.

let var1 = { name: 'Jim' }
let var2 = var1;

var2.name = 'John';

console.log(var1);
// { name: 'John' }
console.log(var2);
// { name: 'John' }

Если бы вы ждали от кода выше такого же поведения, как и с примитивами, — это, вероятнее всего, вызвало бы ошибки. Подобное может быть особенно неудобным, если вы решите создать функцию, которая будет изменять какой-нибудь Object.

Замыкания

Замыкания — важный паттерн для приватизации переменной. В примере ниже createGreeter возвращает анонимную функцию, которой доступна переданная переменная greeting со значением «Hello». После эта переменная будет доступна для sayHello.

function createGreeter(greeting) {
 return function(name) {
   console.log(greeting + ', ' + name);
 }
}

const sayHello = createGreeter('Hello');

sayHello('Joe');
// Hello, Joe

Или же более «правдоподобный» пример. У вас может быть некая функция apiConnect(apiKey), которая возвращает некоторые методы с использованием API ключа. В таком случае этот ключ нужно передать только один раз.

function apiConnect(apiKey) {
 function get(route) {
   return fetch(`${route}?key=${apiKey}`);
 }

 function post(route, params) {
   return fetch(route, {
     method: 'POST',
     body: JSON.stringify(params),
       headers: {
         'Authorization': `Bearer ${apiKey}`
       }
     })
 }
 return { get, post }
}

const api = apiConnect('my-secret-key');

// Больше передавать ключ не нужно
api.get('http://www.example.com/get-endpoint');
api.post('http://www.example.com/post-endpoint', { name: 'Joe' });

Деструктуризация

Деструктуризация — это просто способ извлечения свойств из объектов.

const obj = {
 name: 'Joe',
 food: 'cake'
}
const { name, food } = obj;
console.log(name, food);
// 'Joe' 'cake'

Если вам нужно извлечь свойство, дав ему другое имя, — делайте так:

const obj = {
 name: 'Joe',
 food: 'cake'
}

const { name: myName, food: myFood } = obj;
console.log(myName, myFood);

// 'Joe' 'cake'

В следующем примере деструктуризация применяется для «чистой» передачи объекта person в функцию introduce. Иначе говоря, деструктуризация может использоваться для непосредственного извлечения передаваемых параметров. Для тех, кто разрабатывает на React, это может показаться знакомым.

const person = {
 name: 'Eddie',
 age: 24
}

function introduce({ name, age }) {
 console.log(`I'm ${name} and I'm ${age} years old!`);
}

console.log(introduce(person));
// "I'm Eddie and I'm 24 years old!"

Spread

Нельзя не сказать об этой концепции. Spread — это специальный оператор JavaScript, который позволяет расширять выражения в тех местах, где предусмотрено использование нескольких аргументов.

В следующем примере Math.max() не может принять массив arr, т. к. функции с таким аргументом не существует. Math.max() принимает числа отдельными аргументами. Оператор spread(три точки — ...) используется для извлечения отдельных элементов из массива.

const arr = [4, 6, -1, 3, 10, 4];
const max = Math.max(...arr);

console.log(max);
// 10

Rest-параметры

Rest-параметры позволяют передавать произвольное количество аргументов, принимая их в виде массива.

function myFunc(...args) {
 console.log(args[0] + args[1]);
}

myFunc(1, 2, 3, 4);
// 3

Методы массивов

С помощью методов массива в JavaScript можно добиться крутых (а порой и элегантных) способов трансформации данных. На StackOverflow часто можно наткнуться на вопросы о том, как работать с массивом объектов.

Ниже будут перечислены некоторые методы массива, сгруппированные по назначению. Однако это далеко не весь список.

1551 0