首页 > 试题广场 >

请问以下JS代码最终输出的结果和num值分别是多少? var

[单选题]
请问以下JS代码最终输出的结果和num值分别是多少?
var test = (function() {
  var num = 0
  return () => {
      return num++
  }
}())
for (var i = 0; i < 20; i++) {
  test()
}
console.log(test());


  • 20、20
  • 20、21
  • 21、21
  • 21、20
var test = (function() {  //test是一个自执行函数,自执行函数里返回了一个箭头函数
  var num = 0             //故test()的时候是调用执行了箭头函数
  return () => {
      return num++
  }
}())


for (var i = 0; i < 20; i++) {
  test()                   //调用一次test()就执行一次箭头函数,for循环里调用了20次
}                          //for循环第一次test()返回了0,第20次返回了19
console.log(test());       //这里又调用了一次test(),此时test()返回了20,
                           //而num的值比test()的返回值num++ 大1,故num为21

发表于 2022-01-05 11:01:44 回复(4)
var test = () 

// 可以将上面的代码拆分开分析一下,下面是()里的代码,外面的()只是为了符合语法。
// 下面是一个自执行函数,一开始它自己调用自己一次,将箭头函数返回给 var test。
function() {
  var num = 0
  return function() {
    return num++
  }
}()

// 那 var test 现在就是一个函数了。
// 在返回箭头函数的时候,函数里引用了第6行的num,所以该函数不进行销毁。
// 如果销毁了,那么test()的时候,num就不翼而飞,找不到了。

// 现在 test就相当于
var test = function() {
  return num++;
}

for (var i = 0; i < 20; i++) {
  test()
  // 这里就相当于调用了20次的test,test存储的num也就变成了20
}

console.log(test());
// 最后又输出了一次,num+1,变成了21。

发表于 2022-02-21 21:35:22 回复(1)

解析:

立即调用函数表达式:IIFE( 立即调用函数表达式)是一个在定义时就会立即执行的 JavaScript 函数。

箭头函数:箭头函数表达式的语法比函数表达式更简洁,并且没有自己的 this、arguments、super 或 new.target 。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且不能用作构造函数。

闭包:一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。闭包让你可以在一个内层函数中访问到其外层函数的作用域。在JavaScript中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

代码运行逻辑:

循环中执行 test() 函数,即相当于如下代码所示:

for (var i = 0; i < 20; i++) {
    () => {
        return num++; // 循环未执行时,num === 0;循环结束时,num === 20。
    };
};

因为函数 test() 构成闭包,所以匿名箭头函数仍然可以访问到其定义的变量 num。又因为匿名箭头函数体返回后自加num,所以当函数 console.log() 调用函数 test() 时,打印 20,再自加 1,即 最终输出的结果为 20,num值为21。

发表于 2021-12-22 16:26:43 回复(1)
考点是闭包 + 后自加。 test 一直持有自执行函数的环境( num 的值),当使用 test() 时执行内部函数( num++ )。 因此,在 for 循环中执行20次循环得到的值为19( num的操作为后++,即此时只是获取变量 num 的值,再进行 +1 操作)。同理在 console.log 执行时输出值为20,操作结束后值为 num 执行 +1 操作,此时 num 值为 21。 以上为个人见解。如有异同,欢迎交流
发表于 2021-12-20 21:38:36 回复(0)
居然又没大佬解释,凭自增运算符选对正确答案🤣
发表于 2021-12-12 01:50:58 回复(4)
立即执行函数执行后:var test = () => { return num++ } 此时,test 并没有被调用。for 循环中,test 被调用了 20 次。故,num 的值已经达到了 20。而 console.log() 中又执行了一次,num 的值来到了 21,而 test 函数中 return 的是 num++ ,即 num 自增加一前的值,也就是 20。所以答案应该是 B
发表于 2022-02-21 14:07:45 回复(0)
上来立即执行函数先执行,返回一个箭头函数,但是没被调用,所以不执行num++。然后循环,这里是test()也就是执行返回的剪头函数,所以从这里开始 num++
发表于 2022-06-15 12:59:06 回复(0)
num = 0,test()进入循环;循环内 i = 0时,return num = 0,但return后 num 自增1,所以此时num = 1;
则如上,i = 19,return num = 19,此时num自增1,num = 20;
第10行代码,test()执行一次再被打印,则return num = 20, 此时num自增1,所以num = 21,选B。
发表于 2022-01-25 11:34:28 回复(0)
i++是因为先用后加,导致最后一次还没来得及加1,就已经return结束程序了
发表于 2021-12-28 16:57:23 回复(0)
难道不是因为立即执行函数吗
发表于 2022-07-26 10:59:19 回复(0)
var test = ()  // 可以将上面的代码拆分开分析一下,下面是()里的代码,外面的()只是为了符合语法。 // 下面是一个自执行函数,一开始它自己调用自己一次,将箭头函数返回给 var test。 function() {   var num = 0   return function() {     return num++   } }() // 那 var test 现在就是一个函数了。 // 在返回箭头函数的时候,函数里引用了第6行的num,所以该函数不进行销毁。 // 如果销毁了,那么test()的时候,num就不翼而飞,找不到了。 // 现在 test就相当于 var test = function() {   return num++; } for (var i = 0; i < 20; i++) {   test()   // 这里就相当于调用了20次的test,test存储的num也就变成了20 } console.log(test()); // 最后又输出了一次,num+1,变成了21。
编辑于 2024-04-09 14:51:09 回复(0)
***了,起初虽然有立即执行函数,但是立即执行的函数返回的函数没有调用🙈
发表于 2023-11-20 16:52:23 回复(0)
先说下i++和++i的区别:
i++ 会先复制一个副本,然后在真值上 (真值就是原来的数据) +1,
相当于产生了两个变量,一个是副本不会变,一个原来的数据会+1。
++i 则是直接在原数据上+1,不会产生新的中间变量。

return i++ 或可这样理解:
var temp= i; i = i + 1; return temp;
返回的是中间变量
编辑于 2023-11-08 23:58:52 回复(0)
自增操作符的细节
发表于 2023-09-20 10:25:31 回复(0)
num = 0
console.log(num++) // 0
console.log(num) // 1
直接把num++ 看成一个数 会好理解一些
发表于 2023-06-13 15:15:39 回复(0)
let test=(function(){
    let num;
    return ()=>{
        return num++;
    }
}())//函数自调用,所以test()调用的是返回函数,即调用函数自增函数
for(let i=0;i<20;i++){
    test()//此时num为19
}
console.log(test())//此时num为20,后置运算符++,返回的是增加之前的值

发表于 2022-08-19 15:42:08 回复(0)
这题问的是两个数值 一个是console.log打印结果 另一个是num实际数值
其实理解num++ 和++num就差不多行了 一个是先执行后加1  另一个是先加1 后执行
发表于 2022-06-06 17:10:07 回复(0)
哈哈
发表于 2022-03-19 10:02:56 回复(0)
循环20次,每次返回的num依次序是:0 1 2...19,而根据后自增的特性,num变成了20。 此时,console.log中再次执行test(),返回的num是20,而实际num值成了21
发表于 2022-02-13 21:17:13 回复(0)
怎么感觉解析的很复杂,就是前加加和后加加的区别,就这么一个重要的考点吧
发表于 2022-02-08 13:29:17 回复(0)