!
инвертирует правдивость выражения. Поскольку chars
начинается как пустой объект, при первом итерации символа он не будет существовать в свойстве объекта; это будет undefined
. Например, для H
:
chars[character]
// equivalent to
chars.H
// resolves to
undefined
// putting ! in front of it makes it truthy instead:
!undefined -> true
Итак, if(!chars[character]){
говорит: если этот символ еще не существует в объекте, то выполните следующий блок:
chars[character] = 1;
} else {
// The character has already been iterated over;
// it exists on the object, and the value is a number
// Increment that number:
chars[character]++;
}