То, которое равняется оператору (== по сравнению с == =) должно использоваться в сравнениях JavaScript?

Как вы можете видеть, люди предлагают вам максимально использовать подготовленные заявления. Это не так, но когда ваш запрос выполняется всего один раз за процесс, будет небольшое снижение производительности.

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

Мой подход:

  • Если вы ожидаете, что ввод будет целым, убедитесь, что он действительно целое число. В языке с переменным типом, таком как PHP, этот очень важен. Вы можете использовать, к примеру, это очень простое, но мощное решение: sprintf("SELECT 1,2,3 FROM table WHERE 4 = %u", $input);
  • Если вы ожидаете чего-то еще от целого шестнадцатеричного значения. Если вы отбросите его, вы полностью избежите ввода. В C / C ++ есть функция, называемая mysql_hex_string() , в PHP вы можете использовать bin2hex() . Не беспокойтесь о том, что экранированная строка будет иметь размер в 2 раза по сравнению с исходной длиной, потому что даже если вы используете mysql_real_escape_string, PHP должен выделять одну и ту же емкость ((2*input_length)+1), что то же самое.
  • hex метод часто используется при передаче двоичных данных, но я не вижу причин, почему бы не использовать его во всех данных для предотвращения атак SQL-инъекций. Обратите внимание, что вам необходимо предварительно добавить данные с помощью 0x или использовать функцию MySQL UNHEX.

Так, например, запрос:

SELECT password FROM users WHERE name = 'root'

Будет:

SELECT password FROM users WHERE name = 0x726f6f74

или

SELECT password FROM users WHERE name = UNHEX('726f6f74')

Hex - идеальный выход.

Разница между функцией UNHEX и префиксом 0x

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

Префикс ** 0x ** может использоваться только для столбцов данных, таких как char, varchar, text, block, binary, и т. д. Кроме того, его использование немного сложно, если вы собираетесь вставить пустую строку. Вам придется полностью заменить его на '', или вы получите сообщение об ошибке.

UNHEX () работает в любом столбце; вам не нужно беспокоиться о пустой строке.


Hex-методы часто используются в качестве атак

Обратите внимание, что этот шестиугольный метод часто используется как атака SQL-инъекции, где целые числа точно так же, как и строки mysql_real_escape_string. Тогда вы можете избежать использования кавычек.

Например, если вы просто делаете что-то вроде этого:

"SELECT title FROM article WHERE id = " . mysql_real_escape_string($_GET["id"])

атака может очень легко ввести вас . Рассмотрим следующий введенный код, возвращенный из вашего скрипта:

SELECT ... WHERE id = -1 union all select table_name from information_schema.tables

и теперь просто извлеките структуру таблицы:

SELECT ... WHERE id = -1 union all select column_name from information_schema.column где table_name = 0x61727469636c65

И тогда просто выберите нужные данные. Разве это не круто?

Но если кодер инъекционного сайта будет шестнадцатеричным, инъекция не будет возможна, потому что запрос будет выглядеть следующим образом: SELECT ... WHERE id = UNHEX('2d312075...3635')

5666
задан Taryn 22 March 2017 в 06:13
поделиться

16 ответов

Идентификационные данные (===) оператор ведет себя тождественно к равенству (==) оператор ни кроме какого преобразования типов сделан, и типы должны быть тем же, которое будут считать равными.

Ссылка: учебное руководство Javascript: операторы сравнения

== оператор выдержит сравнение для равенства после выполнения любых необходимых преобразований типов. === оператор не сделает преобразования, поэтому если два значения не будут тем же типом === просто возвратится false. Оба одинаково быстры.

Заключить превосходный JavaScript Douglas Crockford в кавычки: Хорошие Части,

JavaScript имеет два набора операторов равенства: === и !==, и их злые близнецы == и !=. Хорошие работают способ, которым Вы ожидали бы. Если эти два операнда имеют тот же тип и имеют то же значение, то === производит true и !== производит false. Злые близнецы делают правильную вещь, когда операнды имеют тот же тип, но если они имеют различные типы, они пытаются принудить значения. правила, по которым они делают, которые являются сложными и ненезабываемыми. Это некоторые интересные случаи:

'' == '0'           // false
0 == ''             // true
0 == '0'            // true

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true

Отсутствие транзитивности вызывает тревогу. Мой совет никогда не состоит в том, чтобы использовать злых близнецов. Вместо этого всегда используйте === и !==. Все сравнения, просто показанные продукт false с === оператор.


Обновление:

Положительная сторона была поднята @Casebash в комментариях и в @Phillipe Laybaert ответ относительно ссылочных типов. Для ссылочных типов == и === действуйте последовательно друг с другом (кроме особого случая).

var a = [1,2,3];
var b = [1,2,3];

var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };

var e = "text";
var f = "te" + "xt";

a == b            // false
a === b           // false

c == d            // false
c === d           // false

e == f            // true
e === f           // true

Особый случай - при сравнении литерала с объектом, который оценивает к тому же литералу, из-за toString или valueOf метод. Например, считайте сравнение строкового литерала со строковым объектом созданным String конструктор.

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

Здесь == оператор проверяет значения двух объектов и возврата true, но === видит, что они не тот же тип и возврат false. Какой корректен? Это действительно зависит от того, что Вы пытаетесь сравнить. Мой совет состоит в том, чтобы обойти вопрос полностью и просто не использует String конструктор для создания строковых объектов.

Ссылка
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

6327
ответ дан Community 22 November 2019 в 19:37
поделиться

Я протестировал это в Firefox с Firebug с помощью кода как это:

console.time("testEquality");
var n = 0;
while(true) {
    n++;
    if(n==100000) 
        break;
}
console.timeEnd("testEquality");

и

console.time("testTypeEquality");
var n = 0;
while(true) {
    n++;
    if(n===100000) 
        break;
}
console.timeEnd("testTypeEquality");

Мои результаты (протестировал пять раз каждого и составил в среднем):

==: 115.2
===: 114.4

, Таким образом, я сказал бы, что миниатюрное различие (это - более чем 100 000 повторений, помните), незначительно. Производительность не причина сделать ===. Безопасность с точки зрения типов (хорошо, столь безопасный, как Вы собираетесь войти в JavaScript), и качество кода.

96
ответ дан Peter Mortensen 22 November 2019 в 19:37
поделиться

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

var x = 0;
var isTrue = x == null;
var isFalse = x === null;

, Который довольно скоро становится проблемой. Лучший образец того, почему неявное преобразование является "злым", может быть взят от этого кода в MFC / C++, который на самом деле скомпилирует из-за неявного преобразования из CString для ОБРАБОТКИ, который является типом определения типа указателя...

CString x;
delete x;

, Который, очевидно, во время времени выполнения делает очень неопределенные вещи...

Google для неявных преобразований в C++ и STL для получения некоторых аргументов против него...

22
ответ дан Peter Mortensen 22 November 2019 в 19:37
поделиться

В типичном сценарии не будет никакого различия в производительности. Более важный может быть то, что тысяча "===" 1  КБ, более тяжелый, чем тысяча "==":) профилировщики JavaScript могут сказать Вам, если существует различие в производительности в Вашем случае.

, Но лично я сделал бы то, что предлагает JSLint. Эта рекомендация там не из-за проблем производительности, но потому что приведение типа означает ('\t\r\n' == 0), верно.

48
ответ дан Community 22 November 2019 в 19:37
поделиться

Используя == оператор (Равенство)

true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2;  //true, because "2" is converted to 2 and then compared

Используя === оператор (Идентификационные данные)

true === 1; //false
"2" === 2;  //false

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

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

1110
ответ дан 13 revs, 8 users 32% 22 November 2019 в 19:37
поделиться

=== оператор называют строгим оператором сравнения, он действительно отличается от == оператор.

Позволяет берут 2 Вара a и b.

Для "== b" для оценки к истинному a и b должен быть тем же значением.

В случае "=== b" a и b должны быть тем же значением и также тем же типом для него для оценки к истинному.

Возьмите следующий пример

var a = 1;
var b = "1";

if (a == b) //evaluates to true as a and b are both 1
{
    alert("a == b");
}

if (a === b) //evaluates to false as a is not the same type as b
{
    alert("a === b");
}

Таким образом; с помощью == оператор мог бы оценить к истинному в ситуациях, где Вы не хотите его к настолько использующему === оператор, было бы более безопасным.

В 90%-м сценарии использования это не будет иметь значения, какой Вы используете, но удобно знать различие, когда Вы получаете некоторое неожиданное поведение однажды.

84
ответ дан Reinstate Monica 22 November 2019 в 19:37
поделиться

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

38
ответ дан Sean 22 November 2019 в 19:37
поделиться

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

Итак, возьмем следующий код:

var a = [1,2,3];
var b = [1,2,3];
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

то же самое здесь:

var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Или даже:

var a = { };
var b = { };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

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

Правило таково:

Для типов значений (чисел):
a === b возвращает истину, если a и b имеют одинаковое значение и относятся к одному типу

Для ссылочных типов:
a === b возвращает истину, если a и b ссылаются на один и тот же объект

Для строк:
a === b возвращает истину, если a и b являются строками и содержат одинаковые символы.


Строки: особый случай ...

Строки являются не типы значений, но в Javascript они ведут себя как типы значений, поэтому они будут «равными», когда символы в строке одинаковы и когда они имеют одинаковую длину (как объяснено в третьем правиле)

Теперь это становится интересно:

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

Но как насчет этого?:

var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

Я думал, что строки ведут себя как типы значений? Ну, это смотря кого спросить ... В этом случае a и b не одного типа. a имеет тип Object , а b имеет тип string . Просто помните, что создание строкового объекта с помощью конструктора String создает нечто типа Object , которое большую часть времени ведет себя как строка .

604
ответ дан 22 November 2019 в 19:37
поделиться

Let me add this counsel:

If in doubt, read the specification!

ECMA-262 is the specification for a scripting language of which JavaScript is a dialect. Of course in practice it matters more how the most important browsers behave than an esoteric definition of how something is supposed to be handled. But it is helpful to understand why new String("a") !== "a".

Please let me explain how to read the specification to clarify this question. I see that in this very old topic nobody had an answer for the very strange effect. So, if you can read a specification, this will help you in your profession tremendously. It is an acquired skill. So, let's continue.

Searching the PDF file for === brings me to page 56 of the specification: 11.9.4. The Strict Equals Operator ( === ), and after wading through the specificationalese I find:

11.9.6 The Strict Equality Comparison Algorithm
The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:
1. Если Тип (x) отличается от Типа (y), вернуть false .
2. Если Type (x) - Undefined, вернуть true .
3. Если Type (x) равен Null, вернуть true .
4. Если Тип (x) не является числом, перейдите к шагу 11.
5. Если x равно NaN , вернуть false .
6. Если y равно NaN , вернуть false .
7. Если x имеет то же числовое значение, что и y, вернуть истину .
8. Если x равен +0, а y равен −0, вернуть true .
9. Если x равен −0, а y равен +0, вернуть true .
10. Верните false .
11. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions); otherwise, return false.
12. If Type(x) is Boolean, return true if x and y are both true or both false; otherwise, return false.
13. Верните true , если x и y относятся к одному и тому же объекту или если они относятся к объектам, соединенным друг с другом (см. 13.1.2). В противном случае верните false .

Интересен шаг 11. Да, строки обрабатываются как типы значений. Но это не объясняет, почему new String ("a")! == "a" . У нас есть браузер, не соответствующий ECMA-262?

Не так быстро!

Давайте проверим типы операндов. Попробуйте сами, заключив их в typeof () . Я обнаружил, что new String («a») является объектом, и используется шаг 1: return false , если типы разные.

Если вам интересно, почему new String ("a") не возвращает строку, как насчет упражнения по чтению спецификации? Радоваться, веселиться!


Айдиакапи написал это в комментарии ниже:

Из спецификации

11.2.2 Новый Оператор :

Если Тип (конструктор) не является Объектом, выбросить исключение TypeError.

Другими словами, если String не относится к типу Object, его нельзя использовать с оператором new.

new всегда возвращает объект, даже для конструкторов String . Увы! Семантика значений для строк (см. Шаг 11) теряется.

И это, наконец, означает: new String ("a")! == "a" .

new всегда возвращает объект, даже для конструкторов String . Увы! Семантика значений для строк (см. Шаг 11) теряется.

И это, наконец, означает: new String ("a")! == "a" .

new всегда возвращает объект, даже для конструкторов String . Увы! Семантика значений для строк (см. Шаг 11) теряется.

И это, наконец, означает: new String ("a")! == "a" .

265
ответ дан 22 November 2019 в 19:37
поделиться

В JavaScript это означает одно и то же значение и тип.

Например,

4 == "4" // will return true

, но

4 === "4" // will return false 
94
ответ дан 22 November 2019 в 19:37
поделиться

Проверяет, равны ли одинаковые стороны в типе , а также в значении .

Пример:

'1' === 1 // will return "false" because `string` is not a `number`

Типичный пример:

0 == ''  // will be "true", but it's very common to want this check to be "false"

Другой типичный пример:

null == undefined // returns "true", but in most cases a distinction is necessary
78
ответ дан 22 November 2019 в 19:37
поделиться

Это строгий контрольный тест.

Это хорошо, особенно если вы проверяете от 0 до false и null.

Например, если у вас есть:

$a = 0;

Then:

$a==0; 
$a==NULL;
$a==false;

All возвращает true, и вы можете этого не захотеть. Предположим, у вас есть функция, которая может возвращать 0-й индекс массива или false в случае ошибки. Если вы проверите с "==" false, вы можете получить запутанный результат.

То же самое, что и выше, но со строгим тестом:

$a = 0;

$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false
32
ответ дан 22 November 2019 в 19:37
поделиться

=== Оператор проверяет значения, а также типы переменных на равенство. Оператор

== просто проверяет значение переменных на равенство.

34
ответ дан 22 November 2019 в 19:37
поделиться

В PHP и JavaScript это оператор строгого равенства. Это означает, что он будет сравнивать как тип, так и значения.

100
ответ дан 22 November 2019 в 19:37
поделиться

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

0==false   // true,although they are different types

0===false  // false,as they are different types

2=='2'    //true,different types,one is string and another is integer but 
            javaScript convert 2 to string by using == operator 

2==='2'  //false because by using === operator ,javaScript do not convert 
           integer to string 

2===2   //true because both have same value and same types 
53
ответ дан 22 November 2019 в 19:37
поделиться

Из основной ссылки javascript

=== Возвращает true, если операнды строго равны (см. выше) без преобразования типов.

22
ответ дан 22 November 2019 в 19:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: