Как правильно проверить на равенство строк в JavaScript?

844

Как правильно проверить равенство строк в JavaScript?

JSS
источник
2
Есть ли причина не использовать ==?
Кендрик
21
@ Кендрик - конечно. Это система приведения типов может быть невероятно неинтуитивной и может очень легко упускать из виду ошибки (это выглядит правильно, но может быть очень неправильно)
STW
20
@Kendrick - потому что {} == "[object Object]"оценивается как true, например.
Четан Шастри
12
несколько раздражает, что String().equals()это не метод в JS ...
Александр Миллс
2
@AlexanderMills Почему?
Ry-

Ответы:

624

всегда Пока вы полностью не понять различия и последствия использования==и===операторов, используйте===оператортак как это избавит вас от непонятных (неочевидных) ошибок и WTFs. «Обычный»==оператор может иметь очень неожиданные результаты из-за приведения типов внутри, поэтому использование===всегда является рекомендуемым подходом.

Для понимания этого и других «хороших и плохих» частей Javascript прочитайте о Дугласе Крокфорде и его работе. В Google Tech Talk есть отличная информация: http://www.youtube.com/watch?v=hQVTIJBZook


Обновить:

Серия « Вы не знаете » от Кайла Симпсона превосходна (и бесплатна для чтения онлайн). Эта серия статей посвящена часто неправильно понимаемым областям языка и объясняет «плохие стороны», которые Крокфорд предлагает вам избегать. Поняв их, вы сможете правильно их использовать и избежать подводных камней.

Книга " Up & Going " содержит раздел, посвященный равенству , в котором содержится конкретное описание того, когда следует использовать операторы верстки ( ==) и строгого ( ===):

Чтобы свести все детали к нескольким простым выносам и помочь вам узнать, использовать ли они ==или ===в различных ситуациях, вот мои простые правила:

  • Если какое-либо значение (иначе сторона) в сравнении может быть значением trueили false, избегайте ==и используйте ===.
  • Если какое- либо значение в сравнении может быть из этих конкретных значений ( 0, ""или []- пустой массив), избегать ==и использования ===.
  • Во всех остальных случаях вы безопасны в использовании ==. Это не только безопасно, но и во многих случаях упрощает ваш код таким образом, чтобы улучшить читаемость.

Я по-прежнему рекомендую выступление Крокфорда для разработчиков, которые не хотят тратить время на то, чтобы по-настоящему понять Javascript - это хороший совет для разработчика, который лишь изредка работает в Javascript.

STW
источник
7
Нет необходимости, если вы уверены, что оба операнда являются строковыми, например, при использованииif (typeof foo == "string")
Марсель Корпель
25
@ Марсель - вы правы, но гораздо лучше всегда использовать ===оператора и никогда не беспокоиться о том, "действительно ли я на 100% уверен, что ==будет вести себя так, как я думаю?"
STW
7
@STW - один из примеров того, почему Крокфорд не является альфа и омегой JavaScript, это его совет не использовать унарное увеличение / уменьшение ( ++/ --).
Марсель Корпель
10
И никогда не использовать ++или --или однострочные if/elseзаявления или continueили newоператор или любое другое число совершенно законных методы коды, Крокфорд счел «вредным». И, конечно , никогда никогда даже рассматривать думать об использовании evalили withдаже если их подводные камни , хорошо понятны. А вы видели следующую версию JS? Более строгий синтаксис и несколько вспомогательных функций, некоторые из которых используются годами, - это почти все, что мы получаем после всего этого времени. Синтаксис не развивался вообще. Если за этим стоит Крокфорд, то это было плохо.
MooGoo
4
@CoffeeAddict - быстрый тест в JSFiddle, похоже, не согласен. Они оба чувствительны к регистру: jsfiddle.net/st2EU
STW
205

Если вы знаете, что это строки, то нет необходимости проверять тип.

"a" == "b"

Однако обратите внимание, что строковые объекты не будут равны.

new String("a") == new String("a")

вернет ложь.

Вызовите метод valueOf (), чтобы преобразовать его в примитив для объектов String,

new String("a").valueOf() == new String("a").valueOf()

вернет истину

Анураг
источник
4
спасибо за этот JSS, два строковых объекта никогда не будут равны, если они не являются одним и тем же объектом, независимо от значения.
Анураг
4
@JSS: Кроме того, new String("a") == "a"это правда (но не будет ===), потому что левая часть будет преобразована в примитивное строковое значение.
Мэтью Крамли
5
@JSS: new String("a") == new String("a"), new String("a") === new String("b"), new String("a") === new String("a")будет все возвращается false, так как вы имеете дело со ссылками на объекты Stringкласса, а не примитивы типа string.
Palswim
4
Просто чтобы уточнить это для всех, кто читает. new String(foo)создает строковый объект и String(foo) преобразует foo в строковый примитив.
Разбойник
9
@FakeRainBrigand - ясно, как грязь, но это то, что javascripts о, не так ли?
Периата Breatta
59

Только одно дополнение к ответам: если все эти методы возвращают false, даже если строки кажутся равными, возможно, что есть пробел слева или справа от одной строки. Итак, просто поместите .trim()в конец строки перед сравнением:

if(s1.trim() === s2.trim())
{
    // your code
}

Я потерял часы, пытаясь понять, что не так. Надеюсь, это кому-нибудь поможет!

akelec
источник
1
Большое спасибо. Это странно для меня, потому что я позаботился о том, чтобы не было пробелов ни слева, ни справа, и все же это был единственный способ решить мою проблему. Может быть, это связано с внутренним представлением строки?
Нико
2
Спасибо @akelec !! @Niko, скорее всего, из-за символа Zero-Width-Space, который невидим невооруженным глазом. См. En.wikipedia.org/wiki/Zero-width_space . Хотя этот персонаж имеет свои цели, многие разработчики возмущаются его существованием!
stwr667
Спасибо, что расстраивает, так как проверка на равенство в моем if провалилась, но я не увидел пробелов при проверке во время отладки.
drzounds
Распространенная проблема при загрузке переменной из текстового файла (то есть: использование fetch). Большое спасибо.
Сопалахо де Арриерес
@SopalajodeArrierez, точнее, в конце строки есть пробел или возврат каретки. Добро пожаловать.
akelec
22

что привело меня к этому вопросу paddingиwhite-spaces

проверь мой случай

 if (title === "LastName")
      doSomething();

и название было " LastName"

введите описание изображения здесь

так что, возможно, вам придется использовать trimтакую ​​функцию

var title = $(this).text().trim();
Башир Аль-Момани
источник
2
Спасибо то же самое здесь, я использовал .toString().trim()в
Typescript
17

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

Если вы используете ==, вы позволяете языку выполнять какое-то приведение типов, например:

"1" == 1 // true
"0" == false // true
[] == false // true

Как сказал Дуглас Крокфорд в своей книге:

Всегда лучше использовать оператор идентификации.

ludico8
источник
3
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится.
Паркаш Кумар
{}==" "дал мне, Unexpected token ==как правильно это сделать?
Башир Аль-Момани
12

На самом деле есть два способа сделать строки в javascript.

  1. var str = 'Javascript'; Это создает примитивное строковое значение.

  2. var obj = new String('Javascript');Это создает объект-оболочку типа String.

    typeof str // string
    typeof obj // object

Поэтому лучший способ проверить равенство - использовать ===оператор, поскольку он проверяет значение, а также тип обоих операндов.

Если вы хотите проверить равенство между двумя объектами, используйте String.prototype.valueOfправильный путь.

new String('javascript').valueOf() == new String('javascript').valueOf()
Абхишек
источник
6

Строка Objectsможет быть проверена с помощью JSON.stringyfy()трюка.

var me = new String("me");
var you = new String("me");
var isEquel = JSON.stringify(me) === JSON.stringify(you);
console.log(isEquel);

Мухаммед Усман
источник
1

Учитывая, что обе строки могут быть очень большими, есть 2 основных подхода bitwise searchиlocaleCompare

Я рекомендовал эту функцию

function compareLargeStrings(a,b){
    if (a.length !== b.length) {
         return false;
    }
    return a.localeCompare(b) === 0;
}
Nagibaba
источник
-2

Самый простой способ сделать это - использовать троичный оператор, например, так:

 "was" == "was" ? true : false

но если строка, которую вы хотите сравнить, находится в массиве, вы будете использовать фильтр es6

let stringArray  = ["men", "boys", "girls", "sit", "can", "gotten"]
stringArray.filter(I=> I === boys ? 
stringArray.pop(indexOf(I)) : null)

выше будет проверять ваш stringArray и любую строку, которая соответствует ему из массива, который в нашем случае мы выбрали "boys"

Pedro JR
источник
-8

Я придумал альтернативное решение во время тестирования. Вы можете использовать функцию на прототипе строки.

String.prototype.betwenStr = function(one){

return JSON.stringify(new String(this)) === JSON.stringify(new String(one));

}


 //call it
 "hello world".betweenStr("hello world"); //returns boolean 
 //value

отлично работает в браузерах Chrome

Хоррам бен Салим Хондкар
источник
Вопрос состоит в том, как проверить, является ли «hello world» = «hello world», а не как проверить, является ли «hello world» строкой.
Ник
4
Это просто глупо. Вы создали версию Рубе Голдберга ==.
JJJ
Привет, ОП, твоя редакция совершенно другая по своей духовной части, и твой ответ уже получил слишком много отрицательных отзывов. Я призываю вас удалить этот ответ и опубликовать новый с вашей отредактированной версией
Йылмаз Дурмаз