Я не могу припомнить, чтобы где-то видел это сравнение, и у меня не было четкого представления о принудительном преобразовании в то время, поэтому у меня есть эта статья. Думал, я бы расширил выражение для заголовка? Тогда вы ошибаетесь, давайте сразу перейдем к тому, как преобразуется [] == ![]:
- Поскольку приоритет оператора ! относительно высок, правая часть выражения сначала выполняет ![] для получения значения false, и выражение становится [] == false
- Принудительно присвойте false значение 0, выражение станет [] == 0
- После [] принудительного преобразования в исходный тип «» выражение становится «» == 0
- Преобразование "" в числовой тип, выражение становится 0 == 0
- Обе стороны имеют тот же тип, напрямую верните результат 0 === 0 TRUE
предисловие
Цель этой статьи — обобщить правила принуждения в js и несколько сценариев, которые запускают принуждение. В стандарте ES6 определены шесть примитивных типов, а именно Undefined, Null, String, Number, Boolean и Symbol.
Принудительное преобразование в этой статье относится к выполнению определенного преобразования значения, которое необходимо обрабатывать в соответствии со стандартом ES во время выполнения кода.
Приведение между примитивными типами
Преобразование, которое происходит между примитивными типами, в моем личном понимании заключается в том, что другие типы преобразуются в типы String, Number или Boolean.
Преобразовать в строковый тип
Преобразование других типов-примитивов в тип String обычно происходит, когда по обе стороны от + находятся строки, а значение по другую сторону от + преобразуется в тип String. Рассмотрим следующий код:
var strAddNum = "test" + 1;
var numAddStr = 1 + "test";
var boolAddStr = true + "test";
var undAddStr = undefined + "";
var nullAddStr = null + "";
console.log(strAddNum);
console.log(numAddStr);
console.log(boolAddStr);
console.log(undAddStr);
console.log(nullAddStr);
кодовый портал, результаты приведенного выше кода — все строки. Преобразование других типов-примитивов в тип String в основном является строковой формой его значения, как показано ниже:
- Неопределенный, «неопределенный»
- Ноль ноль"
- Логическое значение, "истина" или "ложь"
- Число, значение NaN, "NaN"
- Число, значение +0 или -0, "0"
- Число, значение +Бесконечность, "Бесконечность"
- Число, значение -Бесконечность, "-Бесконечность"
Преобразование числа в строку для получения подробной информацииES2018 Раздел 7.1.12.1
Примечание. Тип символа нельзя преобразовать в тип строки.
Преобразовать в числовой тип
В случае преобразования в числовой тип в таких операциях, как +-*/%, все операции, кроме +, будут преобразованы в числовой тип.В операции +, только если тип String не отображается с обеих сторон, значение будет преобразовано в Тип номера. . Ситуация с операцией + более сложная, и связанные с ней правила преобразования будут описаны позже. Рассмотрим следующий код:
var trueAddTrue = true + true;
var trueAddFalse = true + false;
var trueAdda0 = true + 0;
var nullAddTrue = null + true;
var undefinedAdd0 = undefined + 0;
var strAdd0 = "" + 0;
console.log(trueAddTrue);
console.log(trueAddFalse);
console.log(trueAdda0);
console.log(nullAddTrue);
console.log(undefinedAdd0);
console.log(strAdd0);
кодовый портал, прежде чем запускать код, вы можете рассмотреть приведенный выше код и каковы результаты печати? Затем запустите его снова и посмотрите, соответствует ли он вашим ожиданиям. Подробная информация о преобразовании других типов-примитивов в числовые типы приведена ниже.
- Не определено, NaN
- Нуль, +0
- Boolaen, значение true, 1
- Логическое значение, значение ложно, +0
- Строка, не может быть преобразована в число, нан
- Строка, которую можно преобразовать в число, является соответствующим числовым значением (подробности см. в ES2018).7.1.3.1)
Примечание. Тип «Символ» также нельзя преобразовать в тип «Число».
Преобразование в логический тип
Случай преобразования в логический тип относительно прост, за исключением следующих случаев, преобразование в логический тип будет ложным, а в других случаях - истинным.
- Undefined
- Null
- Число, +0, -0, NaN
- Строка, строка длины 0 Эти ложные случаи четко указаны в стандарте ES.7.1.2
Объект приведен к примитивному типу
Алгоритм приведения объектов к примитивным типам в ES можно условно описать тремя ситуациями:
- Если для объекта установлено значение [Symbol.toPrimitive], вызовите эту функцию, если возвращаемое значение не является типом объекта, верните результат, в противном случае выдайте исключение TypeError.
- Если подсказка преобразования не указана, подсказка преобразования используется «по умолчанию».
- Если подсказка преобразования «по умолчанию», установите для нее «число».
- Когда указанное приглашение преобразования является «числом», сначала вызовите функцию valueOf объекта и оцените результат, если это примитивный тип, верните результат, в противном случае вызовите функцию toString объекта и оцените возвращаемый результат, если результат является примитивным типом, возврат, в противном случае исключение TypeError
- Когда указанное преобразование предложено сначала вызовите функцию TOSTRING, когда «строка» и определяет ее результат возврата, если это оригинальный тип, возвращает результат, или значение вызова функционирования объекта и определяет ее результат, если результат Оригинальный тип возвращается, в противном случае бросьте ненормальный типError
Среди трех вышеперечисленных ситуаций первая ситуация имеет наивысший приоритет, а вторая и три ситуации имеют одинаковый приоритет, который необходимо определить в соответствии со сценарием использования. Указанная подсказка преобразования указывается, когда алгоритм вызывается внутри по стандарту ES.
В первом случае только объект Symbol и объект Date имеют встроенный [Symbol.toPrimitive], а свойство для записи имеет значение false, перечисляемое — false, а настраиваемое — true. Неособые случаи приведения, возникающие при преобразовании объектов в примитивные типы, относятся ко второму, а третий встречается реже. Второго случая должно быть достаточно для нормальной работы по кодированию, третий случай встречается редко, подробности см. в стандарте ES.
var test = {
[Symbol.toPrimitive]: function(hint) {
console.log(hint)
},
valueOf: function() {
console.log("valueOf")
},
toString: function() {
console.log("toString")
}
}
test + ""; //"default"
test * 0; //"number"
String(test); //"string"
кодовый порталВ приведенном выше коде указаны функции [Symbol.toPrimitive], valueOf и toString, которые определяют тестовый объект соответственно. Можно заметить, что функции valueoOf и toString не вызываются. Указанная функция [Symbol.toPrimitive] может принимать параметр приглашения, этот параметр Это обязательный запрос на преобразование при принуждении. Таким образом, мы можем возвращать разные значения в функции в соответствии с различными сценариями преобразования.
Приведение примитивного типа к объекту (упаковка)
Перед тем, как приступить к описанию этой проблемы, можно подумать о том, какие сцены будут принудительно вставлять примитивные типы в объект, на самом деле эта сцена почти везде в js-коде, рассмотрим следующий код:
var str = "testString";
str.replace("test", "");
Значение str, определенное в приведенном выше коде, является не объектом, а примитивным типом String, у которого, очевидно, нет метода для вызова.
На самом деле, когда выполняется str.replace, значение str будет преобразовано в объект, и будет получен объект экземпляра типа String, а на прототипе экземпляра определен ряд методов, и экземпляр не может После выполнения этой строки кода экземпляр будет переработан, поэтому str здесь по-прежнему является строкой.
Рассмотрим следующий код:
var a = 3;
a.fn = function(){};
a.fn();
Несколько сценариев принудительной конвертации
Обычно есть три сценария, в которых происходит принуждение в js-коде:
- +операция
- -,*,/,% операция
- == сравнение
- как условие суждения
+операция
Унарная + операция
При выполнении унарной операции + она будет принудительно преобразована в числовой тип, например
var a = {
[Symbol.toPrimitive]: function(hint) {
console.log(hint); // number
if(hint === "number") {
return 2;
} else {
return 9;
}
}
};
console.log(+a); // 2
var b = "3";
console.log(+b); // 3
Двоичный + операция
Двоичный + операция - это ситуация, в которой сложность вторая только до == сравнение в нескольких принудительных преобразованиях. Лично шаги преобразования суммируются следующим образом:
- Во-первых, приведите значения с обеих сторон к исходному типу (подсказка преобразования не указана, то есть подсказка преобразования является подсказкой по умолчанию);
- Если с обеих сторон есть типы String, они преобразуются в типы String, и возвращаются строки, склеенные с обеих сторон;
- Если второй не возвращается, значения с обеих сторон приводятся к числовому типу, и возвращается результат вычисления;
var a = "";
var b = {
[Symbol.toPrimitive]: function(hint) {
console.log(hint); // "default"
if(hint === "default") {
return 2;
} else {
return 9;
}
}
};
var c = a + b; //这里b转换为原始类型返回的是Number类型2,由于a是"",所以b被转换为"2",后与""拼接返回"2"
console.log(c); // "2"
var d = 3;
var e = {
[Symbol.toPrimitive]: function(hint) {
console.log(hint); // "default"
if(hint === "default") {
return 2;
} else {
return 9;
}
}
};
var f = d + e; //这里e转换为原始类型返回的是Number类型2,由于两侧均没有String类型,则至第3步,强制转换为Number后返回两侧相加的结果5
console.log(f); // 5
-,*,/,% операция
Все приведения, задействованные в этих операторах, преобразуются в числовой тип, поэтому здесь вам просто нужно выяснить, что представляет собой процесс преобразования в числовой. Преобразование примитивного типа в числовой было описано выше, вот процесс преобразования Object в числовой:
- Преобразование объекта в исходный тип и указание подсказки преобразования как «число» при преобразовании;
- После преобразования в исходный тип преобразованный преобразуется в числовой тип в соответствии с исходным типом;
var a = 8;
var b = {
[Symbol.toPrimitive]: function(hint) {
console.log(hint); // "number"
if(hint === "number") {
return 2;
} else {
return 9;
}
}
};
console.log(a-b); // 6
console.log(a/b); // 4
console.log(a*b); // 16
console.log(a%b); // 0
console.log(undefined * 0); //NaN
console.log(null * -1); // 0
console.log(false * -1); //0
console.log(true * -1); // -1
console.log("1" * -1); // -1
== Сравнить
==Основы сравнения ===Сравнение
x === y, конкретные шаги сравнения следующие:
- Если типы x и y несовместимы, вернуть false;
- Если x и y имеют тип Number, вернуть false, если один из x и y равен NaN; вернуть true, если значения x и y равны; если x равно +0, y равно -0 или x равно -0, y равно +0 возвращает true, иначе возвращает false;
- Возвращает true, если x и y имеют тип undefined
- Возвращает true, если x и y имеют нулевой тип
- Возвращает true, если x и y имеют тип String и их значения совпадают, в противном случае возвращает false
- Если x и y имеют логический тип, их значения равны true или оба возвращают true, иначе возвращают false
- Возвращает true, если x и y имеют тип Symbol и их значения совпадают со значением Symbol, в противном случае возвращает false
- Возвращает true, если x и y имеют тип Object и их значение — один и тот же объект (ссылочный адрес тот же), в противном случае возвращает false
х == у правило
Хотя для сравнения == существует немного больше правил преобразования, на самом деле их всего несколько.Числовые типы с обеих сторон преобразуются в зависимости от того, какой тип соответствует, но некоторые из них, возможно, потребуется преобразовать дважды, как показано ниже:
- Если типы обеих сторон равны, результат === возвращается напрямую;
- Возвращает true, если x не определено, а y равно null или если x равно null, а y не определено
- Если обе стороны относятся к типу String и типу Number, преобразуйте тип String в тип Number и продолжайте использовать == для сравнения.
- Если на одной стороне есть логический тип, преобразуйте логический тип в числовой тип и продолжайте использовать == для сравнения.
- Если обе стороны имеют тип строки, числа или символа и тип объекта, преобразуйте тип объекта в исходный тип и продолжайте использовать == для сравнения.
- иначе вернуть ложь
Вот несколько сравнений, которые могут показаться несколько нелогичными.
"0" == false; // true
false == 0; // true
false == ""; // true
false == []; // true
"" == 0; // true
"" == []; // true
0 == []; // true
[] == ![]; //true
как условный приговор
Об этой ситуации сказать особо нечего, в основном, кроме undefined, null, +0, -0, NaN, "" эти шесть значений будут преобразованы в false, а все остальные случаи верны;
Случай приведения значения, отличного от логического, происходит следующим образом:
- if(...)
- for(...;...;...) второе условное выражение
- Условные выражения в while(...) и do...while(...)
- ...?...:...первое условное выражение в троичном выражении
- || и &&
В заключение
На самом деле их так много, как описано выше.В повседневной среде разработки его следует использовать в качестве условия суждения, +, == эти три ситуации, наиболее распространенным из этих трех должно быть условие суждения, эта ситуация Скорее, это является самым простым.