这个代码块的语法是什么?

What is the syntax of this block of code?

当我找到这个答案时,我正在寻找一种方法来 return 数组的模式:

var store = ['1','2','2','3','4'];
var frequency = {};  // array of frequency.
var max = 0;  // holds the max frequency.
var result;   // holds the max frequency element.
for(var v in store) {
    frequency[store[v]]=(frequency[store[v]] || 0)+1; // increment frequency.
    if(frequency[store[v]] > max) { // is this frequency > max so far ?
            max = frequency[store[v]];  // update max.
            result = store[v];          // update result.
    }
}

这段代码运行完美,我对它的理解非常好,我能够输出最常见的值和该值出现的次数。但是,这个代码块对我来说毫无意义。具体行:

frequency[store[v]]=(frequency[store[v]] || 0)+1;

我还以为frequency是一个数组,以store[v]作为索引。此代码块中到底发生了什么?

这对你有用吗?

for(var v in store) {
    numberWeAreLookingAt = store[v];

    // we hadn't gone through this number yet, so it's not defined 
    // as a property in the object "frequency"
    if(frequency[numberWeAreLookingAt] === undefined)
      frequency[numberWeAreLookingAt] = 0; // let's initialize that property with the 
                                           // number zero, in it we will hold the
                                           // number of times it appeared

    // Sum 1 to the times it appeared already (or zero if we 
    // initialized it on the "if" above)
    frequency[numberWeAreLookingAt] = frequency[numberWeAreLookingAt] + 1;

    // the times this number appeared is more than "max"?
    if(frequency[numberWeAreLookingAt] > max) {
        // then now "max" is the times this number appeared
        max = frequency[numberWeAreLookingAt];
        // and the result is this number
        result = numberWeAreLookingAt;
    }
}

请注意,您问题中的代码完全可读。如果你真的看不懂它,你就不能"blame it on the programmer":你只是不太理解代码,应该努力。

"Making code readable" 并不意味着冗长......它意味着 "make it obvious on a first read to whoever knows the syntax",我认为您问题中的代码非常适合。我的代码非常冗长,不需要我的评论:它们只是解释下一行代码的作用

"may"唯一需要解释的代码行是:

frequency[store[v]]=(frequency[store[v]] || 0)+1;

你可以在上面看到它的分解...x = (x || 0)+1 表示 get x if it's defined, or 0 if it's not: then add 1 and assign back to x,这是我在代码中以详细形式所做的。

其他似乎混淆 OP(如评论中所述)的事情是使用括号语法访问对象属性。这在动态执行的语言中并不少见(我认为,考虑到对象原型在 javascript 中的完成方式,括号语法比点语法更有意义,但这只是一种观点)。

在 Javascript 中,您可以使用两种不同的语法访问对象属性:object.property 等同于 object[property]。主要区别在于,当使用括号语法时,您可以使用表达式来计算 属性 名称(或使用其他变量,就像我们在这里所做的那样)。例如,在 C# 中,您可以使用 dynamicExpandoObject.

执行相同的操作

请注意,虽然这可能会让您感到困惑,但它对这个问题来说并不是那么重要......您还可以认为 frequency 是一个数组,其中索引器是对象,而不是序列号,并且它的工作方式相同(例如,在 PHP 中,您可以使用键控数组或 C# 中的 Dictionary 来实现此目的,这是函数式语言中非常典型的模式)。

frequency 不是数组。它是一个对象,是键到值的映射。在这种情况下,键是 store 数组中的字符串,值是这些字符串出现的频率。查看正在发生的事情的最简单方法之一是添加几个 console.logs:

var store = ['1','2','2','3','4'];
var frequency = {};  // array of frequency.
var max = 0;  // holds the max frequency.
var result;   // holds the max frequency element.
for(var v in store) {
    frequency[store[v]]=(frequency[store[v]] || 0)+1; // increment frequency.
    console.log( frequency );
    if(frequency[store[v]] > max) { // is this frequency > max so far ?
            max = frequency[store[v]];  // update max.
            console.log( 'Found new max!', max + ' occurrences of \'' + store[v] + '\'' );
            result = store[v];          // update result.
    }
}

运行 然后查看控制台以了解 frequency 对象在每次迭代后包含的内容。这就是我得到的 Chrome:

Object {1: 1}
Found new max! 1 occurrences of '1'
Object {1: 1, 2: 1}
Object {1: 1, 2: 2}
Found new max! 2 occurrences of '2'
Object {1: 1, 2: 2, 3: 1}
Object {1: 1, 2: 2, 3: 1, 4: 1}

frequency[store[v]]=(frequency[store[v]] || 0)+1; 是 shorthand 用于:

 if (frequency[store[v]]) {
     frequency[store[v]]++;
 } else {
     frequency[store[v]] = 1;
 }

这是因为 JavaScript returns 中的 || operator 如果为真,则其左操作数为真,否则为右操作数,因此表达式 frequency[store[v]] || 0 的计算结果为 0frequency[store[v]]undefined 时(因为 undefined 是假的),但是一旦 frequency[store[v]]1 或更大,它的计算结果为 frequency[store[v]].

首先,浏览 this tutorial 以了解 Javascript 数组和 Javascript 对象之间的区别。然后你会像这样阅读代码:

var store = ['1','2','2','3','4'];               // store[0] == '1', store[1] = '2', etc.
var frequency = {};  // array of frequency.      // frequency.'1' = undefined

然后,当分配发生时,它更容易理解。 frequency[store[v]] 只是 frequency.'1' where v == 0,这意味着您正在访问对象 frequency 及其由字符串 1 命名的字段。 javascript 对象可以有任何名称的字段,例如frequency.'apple'frequency.'table' 等。在您赋予它们价值之前,它们只是未定义的。

那么作业就更容易阅读了

if (frequency.'1' is undefined)
    store the value [0 + 1] into frequency.'1'
else increment the value by 1