Який правильний спосіб перевірити рівність рядків у 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.