Який правильний спосіб перевірити рівність рядків у JavaScript?


842

Який правильний спосіб перевірити рівність між рядками в JavaScript?


2
Чи є причина не використовувати ==?
Кендрік

21
@Kendrick - точно. Це система примусу до типу може бути неймовірно неінтуїтивною і може робити помилки дуже легко не помітити ( виглядає правильно, але може бути дуже помилково)
STW

20
@Kendrick - тому що, наприклад, {} == "[object Object]"оцінює істину.
Chetan Sastry

12
дещо дратує, що String().equals()це не метод у JS ...
Олександр Міллс

2
@AlexanderMills Чому?
Ри-

Відповіді:


624

завжди, поки ви повністю не зрозумієте відмінності та наслідки використанняоператорів==та===операторів, використовуйте===оператор, оскільки це позбавить вас від незрозумілих (не очевидних) помилок та WTF. "Регулярний"==оператор може мати дуже несподівані результати через внутрішньо-примусового типу, тому використання===рекомендується завжди.

Для ознайомлення з цим та іншими частинами Javascript, що знаходяться проти поганого, читайте про містера Дугласа Крокфорда та його роботи. Там є чудовий Google Tech Talk, де він підводить багато корисної інформації: http://www.youtube.com/watch?v=hQVTIJBZook


Оновлення:

Серія " You Don't Know JS " Кайла Сімпсона є чудовою (і читати в Інтернеті безкоштовно). Серія переходить у загальнозрозумілі області мови та пояснює "погані частини", які Крокфорд пропонує вам уникати. Розуміючи їх, ви можете правильно їх використовувати і уникати підводних каменів.

Книга " Вгору та перехід " включає розділ про рівність із цим конкретним підсумком, коли використовувати оператори " вільні" ( ==) проти "строгих" ===:

Щоб зібрати цілу кількість деталей у декількох простих заходах і допомогти вам зрозуміти, використовувати ==чи ===в різних ситуаціях, ось мої прості правила:

  • Якщо будь-яке значення (aka side) у порівнянні могло б бути значенням trueабо falsevalue, уникайте ==та використовуйте ===.
  • Якщо якесь або значення в порівнянні може бути з цих конкретних значень ( 0, ""або []- порожній масив), уникати ==і використання ===.
  • У всіх інших випадках ви безпечні у використанні ==. Він не тільки безпечний, але у багатьох випадках спрощує ваш код таким чином, що покращує читабельність.

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


7
Це не обов'язково, якщо ви впевнені, що обидва операнди є рядковими, наприклад, при використанніif (typeof foo == "string")
Марсель Корпель,

25
@Marcel - ти прав, але набагато краще завжди використовувати ===оператор і ніколи не турбуватися про те, "чи я справді, повністю, на 100% впевнений, що ==буде вести себе, як я думаю, що це буде?"
STW

7
@STW - один із прикладів того, чому Крокфорд не альфа та омега JavaScript, є його порадою не використовувати унарний приріст / декремент ( ++/ --).
Марсель Корпель

10
І ніколи не використовувати ++або --чи однорядкові if/elseзаяви або continueабо newоператор або будь-яке інше число абсолютно законних методи коди, Крокфорд вважав «шкідливим». І, звичайно , ніколи ніколи навіть розглядати думати про використання evalабо withнавіть якщо їх підводні камені , добре зрозумілі. А ви бачили наступну версію JS? Суворіший синтаксис і кілька помічницьких функцій, деякі з яких пливли довгі роки, - це майже все, що ми отримуємо після цього часу. Синтаксис взагалі не розвинувся. Якщо Крокфорд стоїть за цим, то це було погано.
MooGoo

4
@CoffeeAddict - швидкий тест у JSFiddle, схоже, не погоджується. Вони обидва з урахуванням регістру: jsfiddle.net/st2EU
STW

204

Якщо ви знаєте, що це рядки, то не потрібно перевіряти їх тип.

"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, чи не так?
Periata Breatta

58

Лише одне доповнення до відповідей: Якщо всі ці методи повертають помилкові, навіть якщо рядки здаються рівними, можливо, зліва та або з правої сторони від одного рядка є пробіл. Отже, просто покладіть .trim()на кінець рядків перед порівнянням:

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

Я втратив години, намагаючись зрозуміти, що не так. Сподіваюся, це комусь допоможе!


1
Дуже дякую. Мені це дивно, бо я переконався, що немає лівого чи правого простору, і все-таки це був єдиний спосіб вирішити мою проблему. Може, це пов’язано з внутрішнім поданням рядка?
Ніко

2
Дякую @akelec !! @Niko, це, швидше за все, було пов'язано з символом Zero-Width-Space, який невидимий неозброєним оком. Див. En.wikipedia.org/wiki/Zero-width_space . Хоча цей персонаж має свої цілі, багато розробників обурюються його існуванням!
stwr667

Дякую, що засмучувало те, що перевірка рівності в моєму випадку, якщо не вдалося, я не побачив пробілу під час перевірки під час налагодження.
drzounds

Поширена проблема під час завантаження змінної з текстового файлу (тобто: використання fetch). Дуже дякую.
Sopalajo de Arrierez

@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

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

Завжди краще використовувати оператора ідентичності.


3
Хоча це посилання може відповісти на питання, краще включити сюди суттєві частини відповіді та надати посилання для довідки. Відповіді лише на посилання можуть стати недійсними, якщо пов’язана сторінка зміниться.
Паркаш Кумар

{}==" "дав мені, Unexpected token ==що це правильно зробити?
Basheer AL-MOMANI

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;
}

-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 і будь-який рядок, який відповідає йому з масиву, який у нашому випадку ми вибрали "хлопці"


-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

прекрасно працює в хромованих браузерах


Питання задає питання, як перевірити, чи "привіт світ" = "привіт світ", а не як перевірити, чи "привіт світ" є рядком.
Нік

4
Це просто нерозумно. Ви створили версію Rube Goldberg ==.
JJJ

Привіт ОП, ваша редакція у своїй духовній частині зовсім інша, і ваша відповідь вже отримала занадто багато зворотних відгуків. Я закликаю вас видалити цю відповідь та опублікувати нову з відредагованою версією
Yılmaz Durmaz
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.