2016-02-16 2 views
0

Эта функция подсчитывает количество всех символов строки в строке. Я не совсем понимаю здесь утверждение if и как оно работает.как это сделать, если заявление работает и означает? (Javascript)

function getFrequency(string) { 
    var freq = {}; 
    for (var i=0; i<string.length;i++) { 
     var character = string[i]; 
     if (freq[character]) { 
      freq[character]++; 
     } else { 
      freq[character] = 1; 
     } 
    } 

    return freq; 
}; 

Я думал freq[character] это свойство объекта, такого как AB, как это работает с if(freq[character]) также как делает приращение freq[character]++ работ?

Я сделал тест, как это, чтобы попытаться понять его.

var v = {}; 
v.h = 3; 
v["h"]++; 
v["h"] = v["h"] + 1; 
v.h++; 
v.h = v.h + 2; 
console.log(v); 
console.log(v["h"]); 

Я думаю, что я могу предположить, если заявление работает, что если свойство существует, но я думал, что JS имеет свойство объекта вызывает .hasOwnProperty не должны это использовать вместо этого? Что касается приращений, для моего теста это работает, но я просто не понимаю причины.

Может кто-нибудь дать мне руку, чтобы разработать это? За все время заблаговременно

+1

Похоже, что он подсчитывает вхождения символов 'string = 'abbcccdd'' ==' freq = [1,2,3,2] ' – brod

+0

Это подсчитывает количество вхождений каждого символа (буквы, цифры и т. Д.) В строка. Оператор if говорит по существу «если значение [character] объекта freq установлено и имеет значение, затем добавьте его к нему (это то, что' ++ 'делает), в противном случае установите его в 1« –

+0

» [Удачи] (http://stackoverflow.com/questions/7615214/in-javascript-why-is-0-equal-to-false-but-when-tested-by-if-it-is-not-fals) –

ответ

4

В javascript объекты являются Ассоциативные массивы. И наоборот. Между этими понятиями нет разницы.

Так определяя эту переменную как пустой объект:

var freq = {}; 

... фактически создает ассоциативный массив (например, словарь или карты) без ключей добавлены еще.

Продолжая, давайте возьмем строку ввода, например eek. Код здесь будет смотреть на первую букву и обрабатывать freq[character] так же, как freq['e'], что совпадает с freq.e.

В этом коде начальное значение любой буквы в объекте freq составляет undefined. Так что первоначальный if() проверка первого «е» в нашей строке на самом деле выглядит следующим образом:

if(undefined)

Javascript имеет понятие «truthy» и «falsy» ценностей; anything in javascript can be evaluated as a boolean, и (в большинстве случаев) достигается разумный результат. Глядя на undefined, JavaScript будет просто относиться к этому с falsy значение, падают на else блок, и, следовательно, выполнить этот код:

freq[character] = 1; 

Как уже установлено, это то же самое, как freq.e = 1;

Теперь, когда цикл продолжается до следующей буквы (также «e»), javascript завершит вычисление выражения if (1). Javascript трактует это и все остальные ненулевые числа как «truthy», поэтому в этот раз будет выполнять следующую строку:

freq[character]++; 

Опять же, это то же самое, как freq.e++, где freq.e имел значение «1» который теперь может быть увеличен до «2».

Еще один раз через цикл для окончательной буквы «k». На этот раз мы получаем freq.k, который по-прежнему не определен. Undefined является ложным, поэтому управление падает до блока else, а freq.k - «1».

Теперь вы можете увидеть, как мы можем начинать увеличивать буквы в массиве, когда вы находите их в строке, даже если кажется, что вы никогда не определяли массив в первую очередь, никогда не устанавливайте никаких значений ничем, кроме " undefined ", и никогда не было реального логического значения для проверки.

+0

Wow спасибо за подробности, но это только что вызвало мое любопытство относительно '.hasOwnProperty', почему мы все еще нуждаемся в этом, если мы можем проверить его так же, как' if (object [property]) 'вместо использования' if (object.hasOwnProperty ['prop']) ' – Dora

+0

' .hasOwnProperty() 'просто возвращает логическое значение. Вы не можете его использовать, но это более подробно. –

+0

Это не в тему, но интересно, можно ли это сделать без использования объектов и просто вернуться, как список? Практически одно и то же, но не объект. – Dora

2

if (freq[character]) проверяет, имеет ли объект freq его значение со значением character в качестве наименования. Результат этого выражения оценивается как true или false.

Это может быть более четко указано, как показано в следующем, не исчерпывающим образом иллюстрирует:

if (freq[character] == null) 

или

if (typeof freq[character] === 'undefined') 

В опасность в не будучи явным при оценке, если объект является undefined или null, если он фактически установлен на другой тип, который равен true или false (0, 1, '0', true, false).

+0

'freq.character' эквивалентен' freq ["character"] '. Имена свойств после '.' являются литералами, а не переменными. – Barmar

+0

@ Бармар - Отмечено, спасибо. – lintmouse

3

if (freq[character]) проверяет, является ли значение «правдивым». То есть, это не false, null, undefined или 0. В первый раз, когда мы сталкиваемся с любым символом, значение будет undefined, так как литерал объекта создается пустым, поэтому проверка «правдивая» завершится неудачей, и управление упадет до блока else.

Итак, когда мы сначала увидим конкретное письмо, установите значение 1 (которое теперь «правдиво»).

Любые последующие встречи этой буквы просто увеличивают значение, которое было бы эквивалентно, например, freq[character] = freq[character] + 1;. Синтаксис приращения - это просто сокращение.

+0

Так что, если свойство является числовым значением, приращение будет работать именно так, потому что это как JS? : D – Dora

+0

Надеюсь, вы не возражаете против изменений. Не стесняйтесь отката, если чувствуете, что зашли слишком далеко. –

Смежные вопросы