了解 in return 函数中的增量运算符
understanding the increment operator within in return function
- 我正在尝试理解一小段代码
- 对于第一个 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
看来你误解了++i
和i++
之间的区别。该问题涉及 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 的值,当它已经递增时。
- In循环的In运算符前后
- 使用!而in运算符在应该为true时返回false,为什么
- JSLint 如何允许“in”运算符
- 如何检测在 Javascript 中使用“in”运算符是否安全
- 为什么下面的“in”运算符找不到这个数组中的字符串
- Symfony2 JSON 对象 - 错误未捕获类型错误:无法使用“in”运算符搜索“636”
- JavaScript中“in”运算符有什么好处/优势
- 在 Javascript 中模拟“IN”运算符以简化冗余逻辑 OR 的最佳解决方案是什么?
- 了解 in return 函数中的增量运算符
- 获取未捕获的类型错误:无法使用“in”运算符搜索“length”in
- 类型错误:无法使用“in”运算符在 [{}] 中搜索“_id”
- 在JavaScript中使用“in”运算符有什么好处
- 角度类型提前异步结果 - 收到错误“类型错误:无法使用'in'运算符搜索 ..在..".
- 无法在 nodeJS:TypeError 中对用户进行身份验证:无法使用“in”运算符在 fs 中搜索“用户名”
- Javascript:在代理中捕获“in”运算符
- 未捕获的类型错误:无法使用“in”运算符在 false 中搜索“长度”
- 无法使用“in”运算符搜索错误
- 将 In 运算符与带有数组的 WebSQL 一起使用
- in运算符总是返回false
- 不能使用“in”运算符搜索“_id”