Понимание приведение типов в JavaScript - PullRequest
0 голосов
/ 16 февраля 2019

Я знаю, == оператор выполняет приведение типов.Но я не могу понять следующее поведение.

const x = new Boolean(false);

if (x) {
  console.log("if(x) is true");
}

if (x == false) {
  console.log("if(x == false) is true");
}

Удивительно, но вышеприведенный фрагмент выводит обе строки:

if(x) is true if(x == false) is true

Может кто-нибудь объяснить это странное поведение или есть что-то фундаментальное?пропал?

Ответы [ 5 ]

0 голосов
/ 16 февраля 2019

Как уже упоминалось в других ответах, это потому, что x является объектом - логическим объектом, но все же объектом, поскольку вы используете оператор new - и применяется только при сравнении x с false: if (x) проверяет, является ли x значением truey , и, следовательно, не нуждается в принуждении (нет других задействованных операндов): объект всегда "истинен" (weeeell…почти всегда: typeof null возвращает object, но это ложное значение. Но это уже другая история ...).

Вы можете легко проверить, когда вызывается принуждение, нажав символ toPrimitive :

var x = new Boolean(false);

// first of all, if it wasn't an object you couldn't
// do this
x[Symbol.toPrimitive] = function(hint) {
  console.log({hint});
  return this.valueOf();
}

// no console.log yet
if (x) {
  console.log("if(x) is true");
}

// here you got the console.log before the one
// inside the block, since the coercion happens
// in the `if`
if (x == false) {
  console.log("if(x == false) is true");
}
0 голосов
/ 16 февраля 2019

когда вы делаете if (expression) в javascript, выражение оценивается путем приведения к логическому значению.

Несколько сбивает с толку, Boolean(new Boolean(false)) оценивается как истина, потому что, как сказал Ник, это все еще объект.Это то, что вызывает поведение, которое вас смущает.

Полезное чтение для получения дополнительной информации https://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/

0 голосов
/ 16 февраля 2019

new Boolean(false) производит объект.Объекты всегда правдивы , даже если они оборачивают ложное примитивное значение.Например, new String("") также является правдивым, несмотря на то, что "" является ложным.

С другой стороны, когда вы делаете new Boolean(false) == false, он приводит объект к его примитивному значению для сравнения.Кстати, new Boolean(false) === false это , а не true, поскольку их типы не совпадают.

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

0 голосов
/ 16 февраля 2019

Если вы напишите

const x = new Boolean(false);

typeof x вернет object.Тип object равен " truey ", что означает, что он оценивается как true, если нет такого оператора, как ==.Однако его значение равно false, поэтому второе утверждение также оценивается как true.

Таким образом, операторы if ведут себя по-разному, потому что оператор if без проверки проверяет, является ли тип истинным или ложным (в данном случае truey -> true), и вызовы if с помощью сравнения (==).valueOf(), то есть false.

В любом случае вы не должны использовать оболочки new для этого сценария.

const x = false;

достаточно.Для приведения вы можете использовать Boolean() без new оболочки.

Чтобы проверить, верны ли значения, вы можете использовать двойное отрицание:

const x = new Boolean(false);

if (x) console.log(!!x);

if (x == false) console.log(x.valueOf());
0 голосов
/ 16 февраля 2019

Вы должны использовать Boolean(false) вместо new Boolean(false), поскольку Boolean - это функция.

В противном случае вы получите пустой объект {}, который отличается от того, который возвращаетсясамой функцией, которая является boolean.

const x = new Boolean(false);
const y = Boolean(false);

console.log(x, typeof x);
console.log(y, typeof y);

В первом тесте вы проверяете только, является ли значение истинным, а пустой объект - правдивым, поскольку x = {} тест проходит:

const x = new Boolean(false);

console.log(x, !!x, !!{}, Boolean(x))

if (x) {
  console.log("if(x) is true");
}

Однако при использовании == оператор приводит new Boolean(false) к своему примитивному значению, используя x.valueOf, что составляет false, и, таким образом,равенство проходит.

const x = new Boolean(false);

console.log(x.valueOf())
...