理解返回函数中的增量运算符

时间:2016-03-03 19:53:48

标签: javascript

  • 我想了解一小段代码
  • 对于第一个我打印1,因为++ i的值是增量后的i的值。
  • 但不确定为什么第二个和第三个打印2和3因为它冲突(值i ++是增量前的i的值)
  • 到底为什么打印4
  • 你们能告诉我为什么会这样做吗

       //What is i?
    
        var i=0;
        var add = function(){
         ++i;
         console.log(i); //output--->1
            return function(){
                i++; 
                console.log(i); //output--->2
                ///not sure why it happens like this
                return function(){
                    i++;
                    console.log(i); //output--->3
                    ///not sure why it happens like this
                    add();
                }
            }
        };
        add()()();
        //what does this method do here
    

4 个答案:

答案 0 :(得分:0)

您似乎误解了++ii++之间的区别。该问题涉及SAME语句的运算符优先级。

如果你总是在下一行做console.log(),你就不会发现差异。

尝试这样的事情:

var x = 0;
console.log(x); // => 0
console.log(++x); // => 1 (increment happened before the console.log)
console.log(x); // => still 1 (nothing changed)

var x = 0; // let's start again
console.log(x); // => 0
console.log(x++); // => still 0 (increment happened after the console.log)
console.log(x); // => 1

现在让我们考虑执行返回的函数(参见注释):

var i=0;
var add = function(){
 ++i;
 console.log(i); //output--->1 - from add() and also output--->4 from the final call to add() at the end of the function
    return function(){
        i++; 
        console.log(i); //output--->2 - from add()()
        ///not sure why it happens like this
        return function(){
            i++;
            console.log(i); //output--->3 - from add()()()
            ///not sure why it happens like this
            add(); // calls add() one more time (which only executes the first ++i and the first console log)
        }
    }
};
add()()();

答案 1 :(得分:0)

加()

通过将i递增1来返回函数

()

执行该函数,因此在递增后返回另一个函数。

()

执行该函数,因此在递增后你有另一个函数,并且该函数调用add(),它再次递增并返回另一个函数。

i增加4次,函数返回函数4次但最后一个函数没有执行,它只是返回到正文。

 add()   ----> function (){ i is 1 now., return ... }

 add()() ----> function (){ i is 2 now., return ...}

 add()()() ----> function (){ i is 3 now, function(){i is 4 now, return...} }

i ++或++ i是无关紧要的,除非它在语句的指令链中,并且如果你在同一语句中多次使用它,它可能会变成未定义的行为。

如果你在最里面的函数中调用它作为add()()()而不是add(),那么它将是无限递归的。

函数中的指令是按顺序发出的(甚至是执行和完成的,除非它们是基于事件的)。

答案 2 :(得分:0)

i肯定似乎正在做人们通常所期望的事情。我相信你可能会对preincrement和postincrement运算符的差异感到困惑。 ++i返回i的递增值,而i++在递增之前返回原始值i。话虽如此,他们最终都会增加i。以下代码显示了这一点:

var i = 0;
console.log(++i);// prints '1'
console.log(i);  // also prints '1'

var j = 0;
console.log(j++);// prints '0' because that was the original value
console.log(j);  // prints '1' because j still got incremented in the end

答案 3 :(得分:0)

让我们通过一些增强的日志记录来分解它。

首先让我们谈谈大局。您提供的示例代码是一个currying示例。它是一种函数式编程技术,它意味着你分解了一个将多个参数带入一系列函数的函数。您可以read more about currying on stackoverflowWikipedia或只是谷歌搜索。

这意味着您的功能是一系列功能。我将您的示例更改为等效代码,逐个调用每个函数。

// The definition of the add function
var add = function(){
     console.log('first function in the sequence');
     ++i;
     console.log('i = ', i); //output--->1

    return function(){
        console.log('second function in the sequence');
        i++; 
        console.log('i =', i); //output--->2

        return function(){
            console.log('third function in the sequence');

            i++;
            console.log('i =', i); //output--->3
            console.log(typeof(add()));
        }
    }
};


// This is how you invoke the 'add' sequence one by one
var i=0;
console.log('\n***** calling the sequence one by one \n')

const f2 = add()
console.log(typeof(f2))

const f3 = f2()
console.log(typeof(f3))

f3()

首先我们定义add函数,它和你的一样。它实际上是三个函数的序列。

通过调用add()本身来调用第一个函数。

  • 第一个函数将i增加1。 (i具有初始值 由0行定义的var i=0;。 )
  • 然后该函数会记录i的值,此时此值为1
  • 然后它返回一个函数(第二个函数)。

这意味着如果你只是调用add()这样的add,你将得到一个函数,i的值将是1

为了证明这一点,我在上面的代码中添加了以下内容:

const f2 = add()
console.log(typeof(f2))

此时的控制台输出是

***** calling the sequence one by one 

first function in the sequence
i =  1
function

i = 1,代码中的f2类型是函数。 add()的返回值是一个函数。

让我们调用f2并在这些行上将其返回值分配给f3

const f3 = f2()
console.log(typeof(f3))

这会产生以下输出:

second function in the sequence
i = 2
function

调用了第二个函数并更改了i的值。它返回了另一个函数f3。是时候调用第三个函数了。

f3()

f3没有返回值,你可以在代码中看到它没有返回任何内容。控制台输出是:

third function in the sequence
i = 3
first function in the sequence
i =  4
function

您看到我们打印出我们在第三个函数中,递增i并记录其值,即3。

然后,如果你看一下代码发生了什么,我们再次在第三个函数内调用add()。所以第一个函数将再次运行。它递增i并记录其值。 我在f3中注销了add()的类型,你发现它是一个函数。这是序列的结尾add()将函数返回到f3,我们在那里没有做任何更多的事情。

现在让我们回到您的代码。

主要区别在于您不是逐个调用函数,而是在一行上调用它们。这个。

add()()()

您可以立即调用返回的函数。这会产生相同的输出:

***** calling the full sequence 

first function in the sequence
i =  1
second function in the sequence
i = 2
third function in the sequence
i = 3
first function in the sequence
i =  4
function

P.S。 i ++和++中的++的顺序对你来说并不重要,因为你稍后会记录i的值,当它已经递增时。