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

Сегодня я хотел бы обсудить такие ситуации, когда я столкнулся с такими проблемами, и сбить их, посмотрев на детали.

Итак, приступим…

1. Прохождение объектов

Лично я следую правилу: Мы сохраняем только ссылку на объект в переменной. Да, мы не сохраняем никаких объектов внутри переменной (объявленной или параметризованной). Под ссылкой я имел в виду следующее: когда мы вызываем переменную, она указывает на исходный объект для выполнения операции. И когда мы пытаемся передать объект другой переменной или другой функции (в качестве параметра), мы фактически передаем ссылку на исходный объект. А это может привести к мутации.

Пример-объявление переменной-

var obj = { "name": "Prince Garg", "age": 23 };
var objCopy= obj;
objCopy.age= 24;
console.log(obj); // { "name": "Prince Garg", "age": 24 } -OOPS

И, переменная как параметр-

function someFunction( paramObj ) {
   paramObj.age= 24
}
var obj = { "name": "Prince Garg", "age": 23 };
someFunction(obj);
console.log(obj); // { "name": "Prince Garg", "age": 24 } -OOPS

Мутация может привести к катастрофе. Поэтому избегать таких ситуаций — хорошая идея. Если вы хотите передать объект из одной переменной в другую переменную или в функцию, используйте Object.assign({}, obj). Это поможет вам избежать мутаций, и вам никогда не придется беспокоиться о неожиданных изменениях объекта.

Рассмотрим модифицированные примеры-

Заявленная переменная-

var obj = { "name": "Prince Garg", "age": 23 };
var objCopy= Object.assign({}, obj);
objCopy.age= 24;
console.log(obj); // { "name": "Prince Garg", "age": 23 } -Yeyee

И, переменная как параметр-

function someFunction( paramObj ) {
   paramObj.age= 24
}
var obj = { "name": "Prince Garg", "age": 23 };
someFunction( Object.assign({}, obj) );
console.log(obj); // { "name": "Prince Garg", "age": 23 } -Awesome

Но что, если мы получим объект из .find() или array[index]?

Предположим, у нас есть массив объектов, и мы хотим сохранить один из его объектов внутри переменной. Мы можем использовать .find()илиarray[index]непосредственно, чтобы получить объект и сохранить его внутри переменной. Но знаете что, это снова ссылка на объект, который будет храниться в этой переменной. И если вы измените что-либо с помощью этой переменной, которая содержит объект, он изменит исходный объект. Снова используйте Object.assign() и просто избавьтесь от неожиданной мутации.

2. Использование логических операторов

Хорошо, я знаю, вы будете кричать на меня и говорить, как, черт возьми, мир логических операторов javascript может доставить вам неприятности?

Учитывать,

var string1= "somevalue1";
var string2= "somevalue2";
var booleanTrue= true;
var booleanFalse= false;
var checkString= string1 && string2; // "somevalue2"
var checkBoolean= booleanTrue || booleanFalse; // true
if(checkString === checkBoolean) console.log("Yeyee...");
else console.log("OOPS!");
// OOPS , (WHY?)

Здесь происходит кое-что интересное. Мне нужно ваше внимание здесь, в javascript оператор «&&» возвращает последнее значение («somevalue2»), если все значения истинны, иначе ложны. И «||» оператор возвращает первое истинное значение (true). С другой стороны, «||» оператор вернет последнее ложное значение, если ни одно из значений не является истинным.

Ложными значениями являются числовой ноль (0), NaN, ложь, неопределенная и пустая строка («»). Истинные ценности — это все ценности, которые не являются ложными.

Таким образом, checkString не будет содержать логическое значение, вместо этого оно содержит истинное значение («somevalue2») в переменной checkString. А для checkBoolean? Да, как вы уже догадались, оно будет иметь значение «true». Почему? Потому что правило «||» здесь применяется оператор. Поэтому, когда мы проверяем их равенство с помощью оператора «===», мы проверяем строку («somevalue2») и логическое значение (true). Они не того типа и значения, что мы получили «Упс!» здесь.

Чтобы получить ожидаемый результат (например, «Yeyee…»), мы можем использовать Boolean( ‹expression›). Преобразует истинное значение в логическое значение true, а ложное значение — в логическое false. Или мы также можем использовать оператор not( ! ) дважды, чтобы получить логическое значение. Я предпочитаю использовать функцию Boolean(), она делает наш код более читабельным.

Учитывать,

var string1= "somevalue1";
var string2= "somevalue2";
var booleanTrue= true;
var booleanFalse= false;
var checkString= Boolean( string1 && string2 ); // true
var checkBoolean= booleanTrue || booleanFalse; // true
if(checkString === checkBoolean) console.log("Yeyee...");
else console.log("OOPS!");
// Yeyee... (We got it!)

3. Операторы «==» и «===»

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

Нам нужно только понять некоторые правила, чтобы воспользоваться принудительной природой «==», и вот отличная статья, чтобы понять это.



P.S. спасибо Алексей.

Вышеприведенная таблица проста. При сравнении одинаковых типов используется тот же алгоритм, который используется для «===». При сравнении чисел со строкой строка будет преобразована в число, а затем сравнена.

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

Если вы спросите меня, когда использовать «===» и «==». Мой ответ будет-

  1. Сначала спросите себя, если вы уверены, что типы сравниваемых значений будут одинаковыми, то всегда используйте «===», иначе вы можете использовать «==».
  2. При сравнении объекта с объектом сначала преобразуйте их в строку с помощью JSON.stringify() или конкатенации с пустой строкой («»), которая будет работать нормально, а затем сравните. Ниже приведена причина этого-

Примитивы, такие как строки, логические значения и числа, сравниваются по их значению, а такие объекты, как массивы, даты и простые объекты, сравниваются по их ссылке. Это сравнение по ссылке в основном проверяет, ссылаются ли данные объекты на одно и то же место в памяти.

Вывод:

Просто помните несколько вещей при работе с Javascript, если вы хотите избежать мутаций, используйте Object.assign(). Используйте Boolean(), чтобы получить результат && и || в логическом true или false. Поймите принуждение при использовании «==», иначе вы всегда будете великолепны с «===».

Всегда помни,
ты классный