了解 in return 函数中的增量运算符

understanding the increment operator within in return function

本文关键字:运算符 in return 函数 了解      更新时间:2023-09-26
  • 我正在尝试理解一小段代码
  • 对于第一个 i,它打印 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
    

i肯定在做人们通常期望的事情。我相信您可能对前增量和后增量运算符的区别有些困惑。 ++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

看来你误解了++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()()();

add()

只需通过将 i 递增 1 返回一个函数

()

执行该函数,以便在增量后返回另一个函数。

()

执行该函数,以便在增量之后有另一个函数,并且该函数调用 add(),该函数再次递增并返回另一个函数。

i 递增 4 倍,函数

返回函数 4 倍,但最后一个函数没有执行,它只是返回到 body。

 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(),那么它将是无限递归的。

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

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

首先,让我们谈谈大局。您提供的示例代码是柯里的一个示例。这是一种函数式编程技术,这意味着您将一个包含多个参数的函数分解为一系列函数。你可以在stackoverflow,维基百科上阅读更多关于currying的信息,或者只是谷歌它。

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

// 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

附言 ++ 在 i++ 和 ++i 中的顺序对您来说无关紧要,因为您稍后会记录 i 的值,当它已经递增时。