/[^\w]/g != new RegExp('[^\\w]', 'g')

What

正規表現の作り方について、理解に手間取ったので、まとめておきます。

文字列 Hi Bob!!をHiBobとして表示したい (空白や特殊文字を排除したい) 場合、以下の2通りの方法があります。

const word = 'Hi Bob!!';
reg1 = /[^\w]/g;
regResult1 = word.replace(reg1, '');
console.log(regResult1)
// => HiBob
const word = 'Hi Bob!!';
reg2 = new RegExp('[^\\w]', 'g');
regResult2 = word.replace(reg2, '');
console.log(regResult2)
// => HiBob

与える結果が同じなので、reg1とreg2は同じものだと考えましたが、以下の結果から分かるように両者は異なるものみたいです。

console.log(reg1 == reg2)
// => false

Solution

答えは、公式ドキュメントにありました。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions

前者の//で囲む方は正規表現リテラルといい、スクリプトをロードした時に、コンパイルされる正規表現。そのため、正規表現が変化しない場合にパフォーマンスが良い。後者はRegExpのコンストラクタ関数を用いた方法で、該当するコードが実行されるたびにコンパイルされる正規表現。そのため、正規表現が変化する場合にパフォーマンスが良い (正規表現リテラルと異なり、全てのコードをリロードしなくて良いため)。

結論として、

両者とも、与える結果は同じだけど、正規表現のコンパイルのやり方が異なるので、等しくない。

以下正規表現を作成するときに役立つ部分だったので、控えておきます。
正規表現の引数について gとか
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp
正規表現のマッチャについて
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions

Supplement

正規表現^a[^a]の違い

前者は先頭の文字がaだったらマッチするのに対し、後者はaがなかったらマッチする (補集合)。どちらもgを使っていないため、1個マッチした時点でそれ以降は判定しません。

const againLower = 'again'
const againUpper = 'Again'
regAgainLower = againLower.replace(/^a/, 'x')
regAgainUpper = againUpper.replace(/^a/, 'x')
console.log(regAgainLower)
// => xgain
console.log(regAgainUpper)
// => Agxin
const againLower = 'again'
const againUpper = 'Again'
regAgainLower = againLower.replace(/[^a]/, 'x')
regAgainUpper = againUpper.replace(/[^a]/, 'x')
console.log(regAgainLower)
// => axain
console.log(regAgainUpper)
// => xgain