So basically this would be the solution using continue and labels, which I would say, avoid the range checking on the loop level and the calculation of the range end, by using null terminator on the search string, such that null !== undefined and extra if check to hand the last case, look for alternative here, in c++ need like a double character, but saving a few instructions here and there, if there are a lot of partial matches, then only checking one if statement so one less for each partial match.
I recon branch prediction should be better too, as main be on character matching and no branch prediction would be needed for increase performance at for loop level, since is no condition.
function johnMary(str) {
str +="\0"; // add a sentinal, as john out of bounds is undefined, which is not equal to John.
const strJohn = "John";
let countJohn = 0;
main:for(let i = 0; i < str.length; i++) {
match:for (let j = 0, k = i; true; j++, k++) {
if (str[k] !== strJohn[j]){
if (strJohn[j] === undefined) {
break;
}
continue main;
}
}
countJohn++;
}
return countJohn
}
console.log(johnMary("John\0John\0"));
or less jumps..
function johnMary(str) {
str +="\0"; // add a sentinal, as john out of bounds is undefined, which is not equal to John.
const strJohn = "John";
let countJohn = 0;
main:for(let i = 0; i < str.length; i++) {
match:for (let j = 0, k = i; true; j++, k++) {
if (str[k] !== strJohn[j]){
if (strJohn[j] === undefined) {
countJohn++;
}
continue main;
}
}
}
return countJohn
}
console.log(johnMary("John\0John\0"));