1. Значение истинности и ложности JavaScript

В JavaScript истинные выражения — это выражения, которые оцениваются как логическое значение true, а ложные — как логическое значение false. В отличие от других языков, значения true и false не ограничиваются boolean типами данных и сравнениями. Он может иметь множество других форм.

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

Следующие значения всегда ложны:

  • false
  • 0 (ноль)
  • '' или "" (пустая строка)
  • null
  • undefined
  • NaN

Все остальное правда. Это включает:

  • '0' (строка, содержащая один ноль)
  • 'false' (строка, содержащая текст «false»)
  • [] (пустой массив)
  • {} (пустой объект)
  • function(){} («пустая» функция)

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

if (value) {
  // value is truthy
}
else {
  // value is falsy
  // it could be false, 0, '', null, undefined or NaN
}

2. НУЛЕВОЕ И НЕОПРЕДЕЛЕННОЕ

На первый взгляд null и undefined могут показаться одинаковыми, но это далеко не так. В этой статье будут рассмотрены различия и сходства между null и undefined в JavaScript.

Есть две особенности, null которые вы должны понимать:

  • null — пустое или несуществующее значение.
  • null должен быть назначен.

Вот пример. Мы присваиваем значение null a:

let a = null;
console.log(a);
// null

Не определено чаще всего означает, что переменная была объявлена, но не определена. Например:

let b;console.log(b);
// undefined

Вы также можете явно установить переменную равной undefined:

let c = undefined;console.log(c);
// undefined

Наконец, при поиске несуществующих свойств в объекте вы получите undefined:

var d = {};console.log(d.fake);
// undefined

3. Двойное и тройное равенство
В JavaScript есть два визуально похожих, но очень разных способа проверки равенства. Вы можете проверить равенство с помощью == или ===. Вот отличия:

При использовании двойного равенства в JavaScript мы проверяем свободное равенство. Двойное равно также выполняетприведение типов.

Приведение типа означает, что два значения сравниваются только после попытки преобразовать их в общий тип.

Пример проиллюстрирует это. Вспомните ранее, когда мы тестировали следующее со строгим равенством:

77 === '77'
// false (Number v. String)

77 строго не равно '77', потому что они имеют разные типы. Однако, если бы мы проверили эти значения с нечетким равенством…

77 == '77'
// true

Вы можете видеть, что мы получаем true. Это из-за приведения типов. JavaScript на самом деле попытается преобразовать наши значения в аналогичный тип. В данном случае это удается. Строковое значение '77' можно легко преобразовать в числовое значение 77. Поскольку 77 равно, мы получаем ответ на true.

При использовании тройного равенства === в JavaScript мы проверяем строгое равенство. Это означает, что и тип, и значение, которые мы сравниваем, должны быть одинаковыми.

Давайте рассмотрим пару примеров строгого равенства.

В этом первом примере мы сравниваем число5 с числом5. Как и ожидалось, возвращается true. Оба являются числами, и оба имеют одинаковое значение, равное 5.

5 === 5
// true

Имея это в виду, мы можем рассмотреть еще два примера, которые вернут true:

'hello world' === 'hello world'
// true (Both Strings, equal values)true === true
// true (Both Booleans, equal values)

Потрясающий. Теперь давайте посмотрим на некоторые примеры, которые вернут false:

В этом примере мы сравним число 77 со строковым значением 77. Это означает, что наши операнды будут иметь то же самое значение, но другой тип. Это вернет false

77 === '77'
// false (Number v. String)

Вот два дополнительных примера:

'cat' === 'dog'
// false (Both are Strings, but have different values)false === 0
// false (Different type and different value)

4. Карта JavaScript и фильтр

От классического forloop до forEach() метода, различных приемов и методов используются для перебора наборов данных в JavaScript. Одним из самых популярных методов является метод . .map() создает массив путем вызова определенной функции для каждого элемента в родительском массиве. .map() — это неизменяющий метод, который создает новый массив, в отличие от изменяющих методов, которые вносят изменения только в вызывающий массив.

Этот метод может иметь множество применений при работе с массивами. В этом руководстве вы рассмотрите четыре заслуживающих внимания применения в JavaScript: вызов функции элементов массива, преобразование строк в массивы, рендеринг списков в библиотеках JavaScript и переформатирование объектов массива.

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

Вот пример:

const sweetArray = [2, 3, 4, 5, 35]
const sweeterArray = sweetArray.map(sweetItem => {
    return sweetItem * 2
})
console.log(sweeterArray)

Этот вывод записывается в консоль:

Output
[ 4, 6, 8, 10, 70 ]

Метод filter() Array создает новый массив с элементами, которые подпадают под заданные критерии из существующего массива:

var numbers = [1, 3, 6, 8, 11];
var lucky = numbers.filter(function(number) {
  return number > 7;
});
// [ 8, 11 ]

В приведенном выше примере берется массив numbers и возвращается новый отфильтрованный массив, содержащий только те значения, которые больше семи.

Синтаксис фильтра

var newArray = array.filter(function(item) {
  return condition;
});

Аргумент item является ссылкой на текущий элемент в массиве, так как filter() проверяет его на соответствие условию. Это полезно для доступа к свойствам в случае объектов.

Если текущий элемент проходит условие, он отправляется в новый массив.

Фильтрация массива объектов

Обычный вариант использования .filter() — массив объектов через их свойства:

var heroes = [
    {name: “Batman”, franchise: “DC”},
    {name: “Ironman”, franchise: “Marvel”},
    {name: “Thor”, franchise: “Marvel”},
    {name: “Superman”, franchise: “DC”}
];
var marvelHeroes =  heroes.filter(function(hero) {
    return hero.franchise == “Marvel”;
});
// [ {name: “Ironman”, franchise: “Marvel”}, {name: “Thor”, franchise: “Marvel”} ]

5. Найдите массив объектов

Поиск в массиве объектов можно выполнить в Javascript с помощью цикла, методов Array.find() или Array.findIndex().

Вы можете перебирать массив, используя цикл for.

var __POSTS = [ 
	{ id: 1, title: 'Apple', description: 'Description of post 1' }, 
	{ id: 2, title: 'Orange', description: 'Description of post 2' }, 
	{ id: 3, title: 'Guava', description: 'Description of post 3' }, 
	{ id: 4, title: 'Banana', description: 'Description of post 4' }
];
// Search for post with title == "Guava"
var __FOUND = -1;
for(var i=0; i<__POSTS.length; i++) {
	if(__POSTS[i].title == 'Guava') {
		// __FOUND is set to the index of the element
		__FOUND = i;
		break;
	}
}
// On success __FOUND will contain the index of the element
// On failure it will contain -1  
console.log(__FOUND); // 2

Использование Array.find()

Метод Array.find() принимает функцию обратного вызова в качестве параметра и выполняет эту функцию один раз для каждого элемента, присутствующего в массиве, пока не найдет тот, в котором функция возвращает истинное значение.

Если элемент найден, он возвращает значение элемента, в противном случае возвращается значение undefined.

var __POSTS = [ 
	{ id: 1, title: 'Apple', description: 'Description of post 1' }, 
	{ id: 2, title: 'Orange', description: 'Description of post 2' }, 
	{ id: 3, title: 'Guava', description: 'Description of post 3' }, 
	{ id: 4, title: 'Banana', description: 'Description of post 4' }
];
var __FOUND = __POSTS.find(function(post, index) {
	if(post.title == 'Guava')
		return true;
});
// On success __FOUND will contain the complete element (an object)
// On failure it will contain undefined  
console.log(__FOUND); // { id: 3, title: 'Guava', description: 'Description of post 3'

6. Область действия, область действия блока

Область действия определяет видимость или доступность переменной или другого ресурса в области вашего кода.

Глобальный масштаб

В документе JavaScript есть только одна глобальная область видимости. Область за пределами всех функций считается глобальной областью, и переменные, определенные внутри глобальной области, могут быть доступны и изменены в любых других областях.

//global scope
var fruit = 'apple'
console.log(fruit);        //apple
function getFruit(){
    console.log(fruit);    //fruit is accessible here
}
getFruit();                //apple

Локальная область

Переменные, объявленные внутри функций, становятся локальными для функции и рассматриваются в соответствующей локальной области видимости. Каждая функция имеет свою область действия. Одна и та же переменная может использоваться в разных функциях, потому что они привязаны к соответствующим функциям и не видны друг другу.

//global scope
function foo1(){
    //local scope 1
    function foo2(){
        //local scope 2
    }
}
//global scope
function foo3(){
    //local scope 3
}
//global scope

Локальную область можно разделить на область действия и область действия блока. Концепция области действия блока представлена ​​в ECMA Script 6 (ES6) вместе с новыми способами объявления переменных — const и let.

Объем функций

Всякий раз, когда вы объявляете переменную в функции, переменная видна только внутри функции. Вы не можете получить к нему доступ вне функции. var – это ключевое слово для определения переменных для доступа к области действия функции.

function foo(){
    var fruit ='apple';
    console.log('inside function: ',fruit);
}
foo();                    //inside function: apple
console.log(fruit);       //error: fruit is not defined

Область блока

Область блока — это область внутри условий if, switch или циклов for и while. Вообще говоря, всякий раз, когда вы видите {фигурные скобки, это блок. В ES6 ключевые слова const и let позволяют разработчикам объявлять переменные в области блока, что означает, что эти переменные существуют только в соответствующем блоке.

function foo(){
    if(true){
        var fruit1 = 'apple';        //exist in function scope
        const fruit2 = 'banana';     //exist in block scope
        let fruit3 = 'strawberry';   //exist in block scope
    }
    console.log(fruit1);
    console.log(fruit2);
    console.log(fruit3);
}
foo();
//result:
//apple
//error: fruit2 is not defined
//error: fruit3 is not defined

7. Свяжите, позвоните и подайте заявку

Вы можете использовать call()/apply() для немедленного вызова функции. bind() возвращает связанную функцию, которая при последующем выполнении будет иметь правильный контекст («это») для вызова исходной функции. Таким образом, bind() можно использовать, когда функцию нужно вызывать позже в определенных событиях, когда это полезно.

Чтобы понять, что такое это в JavaScript, прочитайте Понимание «это в JavaScript».

call() or Function.prototype.call()

Проверьте пример кода ниже для call()

//Demo with javascript .call()
var obj = {name:"Niladri"};
var greeting = function(a,b,c){
    return "welcome "+this.name+" to "+a+" "+b+" in "+c;
};
console.log(greeting.call(obj,"Newtown","KOLKATA","WB"));
// returns output as welcome Niladri to Newtown KOLKATA in WB

Первый параметр в call() методе устанавливает значение this, которое является объектом, для которого вызывается функция. В данном случае это объект «obj» выше.

Остальные параметры являются аргументами фактической функции.

apply() or Function.prototype.apply()

Проверьте приведенный ниже пример кода для apply()

//Demo with javascript .apply()
var obj = {name:"Niladri"};
var greeting = function(a,b,c){
    return "welcome "+this.name+" to "+a+" "+b+" in "+c;
};
// array of arguments to the actual function
var args = ["Newtown","KOLKATA","WB"];  
console.log("Output using .apply() below ")
console.log(greeting.apply(obj,args));
/* The output will be 
  Output using .apply() below
 welcome Niladri to Newtown KOLKATA in WB */

Подобно методу call(), первый параметр в apply() метода устанавливает значение this, которое является объектом, для которого вызывается функция. В данном случае это объект «obj» выше. Единственная разница между методом заключается в том, что второй параметр метода apply() принимает аргументы фактической функции в виде массива.

bind() or Function.prototype.bind()

Проверьте приведенный ниже пример кода для bind()

//Use .bind() javascript
var obj = {name:"Niladri"};
var greeting = function(a,b,c){
    return "welcome "+this.name+" to "+a+" "+b+" in "+c;
};
//creates a bound function that has same body and parameters 
var bound = greeting.bind(obj); 

console.dir(bound); ///returns a function
console.log("Output using .bind() below ");
console.log(bound("Newtown","KOLKATA","WB")); //call the bound function

8. Резюме React Hooks

React Hooks — это способ, с помощью которого ваши функциональные компоненты «зацепляются» за жизненный цикл и состояние React. Они были представлены в React Раньше только компоненты на основе классов могли использовать жизненный цикл и состояние React. Помимо того, что функциональные компоненты позволяют делать это, хуки позволяют невероятно легко повторно использовать логику с отслеживанием состояния между компонентами.

Если вы впервые переходите на Hooks, это изменение может показаться немного неприятным. Эта глава предназначена для того, чтобы помочь вам понять, как они работают и как о них думать. Мы хотим помочь вам перейти от ментальной модели компонентов класса к функциональным компонентам с помощью React Hooks. Вот что мы рассмотрим:

  1. Краткий обзор жизненного цикла компонентов класса.
  2. Обзор жизненного цикла функциональных компонентов с хуками
  3. Хорошая ментальная модель для понимания React Hooks в функциональных компонентах.
  4. Тонкая разница между компонентами класса и функции

Реагировать на хук состояния

А, государство. Краеугольный камень экосистемы React. Давайте познакомимся с хуками, представив самый распространенный хук, с которым вы будете работать — useState().

Давайте взглянем на компонент класса, который имеет состояние.

import React, { Component } from 'react';
import './styles.css';
class Counter extends Component {
	state = {
		count: this.props.initialValue,
	};
	setCount = () => {
		this.setState({ count: this.state.count + 1 });
	};
	render() {
		return (
			<div>
				<h2>This is a counter using a class</h2>
				<h1>{this.state.count}</h1>
				<button onClick={this.setCount}>Click to Increment</button>
			</div>
		);
	}
}
export default Counter;

С помощью React Hooks мы можем переписать этот компонент и удалить многое, что сделает его более понятным:

import React, { useState } from 'react';
function CounterWithHooks(props) {
	const [count, setCount] = useState(props.initialValue);
	return (
		<div>
			<h2>This is a counter using hooks</h2>
			<h1>{count}</h1>
			<button onClick={() => setCount(count + 1)}>Click to Increment</button>
		</div>
	);
}
export default CounterWithHooks;

На первый взгляд кода меньше, но что происходит?

Синтаксис состояния реакции

Итак, мы увидели наш первый крючок! Ура!

const [count, setCount] = useState();

Использование в функциональных компонентах

Давайте применим наш новоиспеченный клон useState в знакомой обстановке. Мы сделаем компонент Counter!

// Example 1
function Counter() {
  const [count, setCount] = useState(0) // same useState as above
  return {
    click: () => setCount(count() + 1),
    render: () => console.log('render:', { count: count() })
  }
}
const C = Counter()
C.render() // render: { count: 0 }
C.click()
C.render() // render: { count: 1 }

Здесь, вместо рендеринга в DOM, мы решили просто console.log вывести наше состояние. Мы также предоставляем программный API для нашего счетчика, чтобы мы могли запускать его в скрипте, а не прикреплять обработчик событий. Благодаря этому дизайну мы можем имитировать отрисовку нашего компонента и реагировать на действия пользователя.

Хотя это работает, вызов геттера для доступа к состоянию — это не совсем API для настоящего хука React.useState. Давайте это исправим.

Устаревшее закрытие

Если мы хотим соответствовать реальному API React, наше состояние должно быть переменной, а не функцией. Если бы мы просто выставили _val вместо того, чтобы оборачивать его в функцию, мы бы столкнулись с ошибкой:

// Example 0, revisited - this is BUGGY!
function useState(initialValue) {
  var _val = initialValue
  // no state() function
  function setState(newVal) {
    _val = newVal
  }
  return [_val, setState] // directly exposing _val
}
var [foo, setFoo] = useState(0)
console.log(foo) // logs 0 without needing function call
setFoo(1) // sets _val inside useState's scope
console.log(foo) // logs 0 - oops!!

Это одна из форм проблемы устаревшего закрытия. Когда мы деструктурировали foo из вывода, он ссылается на _val на момент первоначального вызова useState… и больше никогда не меняется! Это не то, чего мы хотим; обычно нам нужно, чтобы состояние нашего компонента отражало текущее состояние, при этом будучи просто переменной, а не вызовом функции! Эти две цели кажутся противоположными.

9. Доступность

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

  • Один общий заголовок страницы, который нельзя изменить
  • Управление фокусом делает невозможным управление приложениями с помощью клавиатуры
  • Дополнительные добавленные ‹div› и обертки могут нарушить семантику
  • Использование семантического HTML труднодостижимо

Используйте семантический HTML

Это может быть довольно очевидным, однако все еще существует контент React, который не использует семантический HTML для создания основных элементов на странице. Вместо того, чтобы создавать кнопку с помощью ‹div› и ‹span›, используйте теги ‹button›, которые имеют неотъемлемое значение для вспомогательных технологий. Чем больше семантики вы сможете использовать в своем приложении, тем проще будет вам (разработчику) и пользователю вспомогательных технологий.

Создание доступных приложений React

React полностью поддерживает создание доступных веб-сайтов, часто с использованием стандартных методов HTML. Мы рассмотрим несколько способов сделать ваши реагирующие приложения более доступными.

Совет. Используйте Bit для создания приложений React быстрее с помощью компонентов. Это помогает вашей команде совместно использовать компоненты и повторно использовать их для быстрого создания новых приложений. Это отлично подходит для хранения набора доступных компонентов, которые вы можете использовать. Попробуйте.

10. Замещающий текст на изображениях

Атрибут alt (или «альтернативный») — еще один быстрый способ сделать ваше приложение React более доступным. Когда средство чтения с экрана достигает изображения, оно вслух читает текст alt, описывающий содержимое изображения.

const AlligatorImg = () => (
  <img
    src='./img/alligator.png'
    alt='Alligator coming out of water with mouth open'
  />
)

Цель текста alt состоит в том, чтобы человек, слушающий его, понял содержание изображения. Оно должно быть достаточно конкретным, чтобы человек мог представить изображение, не видя его.

Вывод

Теперь мы изучили основную концепцию фильтрации JavaScript, что мы можем сделать. Если вы чувствуете вдохновение, чтобы строить на этих примерах. Ваше здоровье!