As a relative JavaScript novice, the accepted answer https://stackoverflow.com/a/494046/1904943 is noted / appreciated, but it is not very intuitive.
Here is a simpler interpretation, by example (using a simple JavaScript IDE).
myString = 'apple pie, banana loaf';
console.log(myString.replaceAll(/pie/gi, 'PIE'))
// apple PIE, banana loaf
console.log(myString.replaceAll(/\bpie\b/gi, 'PIE'))
// apple PIE, banana loaf
console.log(myString.replaceAll(/pi/gi, 'PIE'))
// apple PIEe, banana loaf
console.log(myString.replaceAll(/\bpi\b/gi, 'PIE'))
// [NO EFFECT] apple pie, banana loaf
const match_word = 'pie';
console.log(myString.replaceAll(/match_word/gi, '**PIE**'))
// [NO EFFECT] apple pie, banana loaf
console.log(myString.replaceAll(/\b`${bmatch_word}`\b/gi, '**PIE**'))
// [NO EFFECT] apple pie, banana loaf
// ----------------------------------------
// ... new RegExp(): be sure to \-escape your backslashes: \b >> \\b ...
const match_term = 'pie';
const match_re = new RegExp(`(\\b${match_term}\\b)`, 'gi')
console.log(myString.replaceAll(match_re, 'PiE'))
// apple PiE, banana loaf
console.log(myString.replace(match_re, '**PIE**'))
// apple **PIE**, banana loaf
console.log(myString.replaceAll(match_re, '**PIE**'))
// apple **PIE**, banana loaf
Application
E.g.: replacing (color highlighting) words in string / sentence, [optionally] if the search term matches a more than a user-defined proportion of the matched word.
Note: original character case of matched term is retained. hl: highlight; re: regex | regular expression
mySentence = "Apple, boOk? BOoks; booKEd. BookMark, 'BookmarkeD', bOOkmarks! bookmakinG, Banana; bE, BeEn, beFore."
function replacer(mySentence, hl_term, hl_re) {
    console.log('mySentence [raw]:', mySentence)
    console.log('hl_term:', hl_term, '| hl_term.length:', hl_term.length)
    cutoff = hl_term.length;
    console.log('cutoff:', cutoff)
    // `.match()` conveniently collects multiple matched items
    // (including partial matches) into an [array]
    const hl_terms  = mySentence.toLowerCase().match(hl_re, hl_term);
    if (hl_terms == null) {
        console.log('No matches to hl_term "' + hl_term + '"; echoing input string then exiting ...')
        return mySentence;
    }
    console.log('hl_terms:', hl_terms)
    for (let i = 0;  i < hl_terms.length; i++) {
        console.log('----------------------------------------')
        console.log('[' + i + ']:', hl_terms[i], '| length:', hl_terms[i].length, '| parseInt(0.7(length)):', parseInt(0.7*hl_terms[i].length))
        // TEST: if (hl_terms[i].length >= cutoff*10) {
        if (cutoff >= parseInt(0.7 * hl_terms[i].length)) {
            var match_term = hl_terms[i].toString();
            console.log('matched term:', match_term, '[cutoff length:', cutoff, '| 0.7(matched term length):', parseInt(0.7 * hl_terms[i].length))
            const match_re = new RegExp(`(\\b${match_term}\\b)`, 'gi')
            mySentence = mySentence.replaceAll(match_re, '<font style="background:#ffe74e">$1</font>');
        }
        else {
            var match_term = hl_terms[i].toString();
            console.log('NO match:', match_term, '[cutoff length:', cutoff, '| 0.7(matched term length):', parseInt(0.7 * hl_terms[i].length))
        }
    }
    return mySentence;
}
// TESTS:
// const hl_term = 'be';
// const hl_term = 'bee';
// const hl_term = 'before';
// const hl_term = 'book';
const hl_term = 'bookma';
// const hl_term = 'Leibniz';
// This regex matches from start of word:
const hl_re = new RegExp(`(\\b${hl_term}[A-z]*)\\b`, 'gi')
mySentence = replacer(mySentence, hl_term, hl_re);
console.log('mySentence [processed]:', mySentence)
Output
mySentence [raw]: Apple, boOk? BOoks; booKEd. BookMark, 'BookmarkeD',
bOOkmarks! bookmakinG, Banana; bE, BeEn, beFore.
hl_term: bookma | hl_term.length: 6
cutoff: 6
hl_terms: Array(4) [ "bookmark", "bookmarked", "bookmarks", "bookmaking" ]
----------------------------------------
[0]: bookmark | length: 8 | parseInt(0.7(length)): 5
matched term: bookmark [cutoff length: 6 | 0.7(matched term length): 5
----------------------------------------
[1]: bookmarked | length: 10 | parseInt(0.7(length)): 7
NO match: bookmarked [cutoff length: 6 | 0.7(matched term length): 7
----------------------------------------
[2]: bookmarks | length: 9 | parseInt(0.7(length)): 6
matched term: bookmarks [cutoff length: 6 | 0.7(matched term length): 6
----------------------------------------
[3]: bookmaking | length: 10 | parseInt(0.7(length)): 7
NO match: bookmaking [cutoff length: 6 | 0.7(matched term length): 7
mySentence [processed]: Apple, boOk? BOoks; booKEd.
<font style="background:#ffe74e">BookMark</font>, 'BookmarkeD',
<font style="background:#ffe74e">bOOkmarks</font>! bookmakinG,
Banana; bE, BeEn, beFore.