12

迷惑なバグにつながる奇妙な JS の動作に気付きました..

基本的に、if ステートメントで RegExp オブジェクト (.test() メソッド) を使用して str をテストします。テストされた同じ文字列について、コードに if しかない場合、regexp.test() は true を返し、if に問題なく進みます。

問題は、else がある場合 (そしてそれが必要な場合)、何らかの理由で、テストされた同じ str に対して、regexp.test() が false を返し、else に移動することです...

この動作は何ですか?

私は多くのテストを実行しました...

TL/DR : 同じ RegExp でテストされた同じ文字列の場合、IF ステートメントしかない場合、regexp.test() は true を返しますが、else がある場合は false を返します。

some code

言い忘れましたが、すべての単語でバグが発生するわけではありません..

http://jsfiddle.net/zrwkU/13/

テキスト フィールドに「armoire」と入力し、Enter キーを押します。このjsfiddleには「else return false」があり、何も起こりません。

searchDeeper 関数 ( if (regexp.test(tested)){ ) の「else return false」を削除して、もう一度テストを実行します。これで、if および msgbox ポップアップに入ります。

4

2 に答える 2

36

/regex/g.lastIndex = 0

グローバル'g'フラグが設定されたパターンでは、RegExpメソッド。test()最後に一致した場所をexec()追跡し、この整数をRegExpオブジェクトの:lastIndexプロパティに格納します。このインデックスは、各一致が任意の文字列に適用されるときに自動的に進められます。との両方がこのようtest()exec()動作することに注意してください。一致が失敗すると、この最後のインデックスプロパティは自動的にゼロにリセットされます。手動でゼロにリセットすることもできますが、ここで行う必要があるのは確かです。RegExp.lastIndex次のようにリセットする行を追加します。

if (regexp != null){
    regexp.lastIndex = 0;
    if (regexp.test(tested)){
        alert('ok');
        regexp.lastIndex = 0;
        var res = regexp.exec(tested);
        tested = tested.replace(res, '<span class="underlined">' + res + '</span>');
    }else{
        return false;
    }
}

これは、この最後のインデックスの問題を完全に回避する別の解決策です。String.match()代わりに次のメソッドを使用します。

別のString.match()方法:

if (regexp != null){
    if (tested.match(regexp)){
        alert('ok');
        regexp.lastIndex = 0;
        var res = tested.match(regexp);
        tested = tested.replace(res, '<span class="underlined">' + res + '</span>');
    }else{
        return false;
    }
}
于 2012-11-27T15:43:46.487 に答える
2

唯一の問題は、あなたがどこにいるのかということだと思います

}else{
    return false;
}

あなたが実際に望んでいるのは

}else{
   continue;
}

外側のループを継続するためfor (var k in cats){

この更新によると: http://jsfiddle.net/zrwkU/14/

説明として-あなたのコードでは、への呼び出しがtest失敗するとすぐに、それはそれです-使用してジャンプするメソッドから抜け出しますreturn false。に変更することcontinueで、他のカテゴリでも「より深く検索」し続けます。

于 2012-11-27T15:49:40.563 に答える