简体   繁体   English

JavaScript传递引用如何解释此行为?

[英]How does JavaScript pass-by-reference explain this behavior?

I am new to JavaScript, and recently stumbled across this problem questioning what would be printed to the console. 我是JavaScript的新手,最近偶然发现了该问题,询问将在控制台上打印什么。 The correct answer is 4 4 4 4 , because of pass-by-reference. 正确的答案是4 4 4 4 ,这是因为引用传递。 However, I don't understand how this is the result. 但是,我不知道结果如何。 Why does pass-by-reference dictate the output if the output is simply a value of i that seems only dependent upon an iteration of a for-loop ? 如果输出只是i的值(似乎仅取决于for-loop的迭代),为什么按引用来决定输出?

const array = [10, 21, 31, 41];

for(i = 0; i < array.length; i++) {
  setTimeout(function print(array){
      console.log(i)}, 3000);
}

Okay, step by step: 好吧,一步一步来:

const array = [10, 21, 31, 41];

for(i = 0; i < array.length; i++) {
  setTimeout(function print(array) { /* stuff... */ }, 3000);
}

// When we get to here, the value of i is 4.

When this snippet runs, we iterate the array, and set a timeout for each iteration. 当此代码段运行时,我们将迭代该数组,并为每次迭代设置一个超时。 When the for loop is finished, we have called setTimeout four times, but none of the functions given to setTimeout have run. 当for循环完成时,我们已调用setTimeout四次,但没有运行给setTimeout的函数。 Indeed, they won't run for another 3 seconds. 确实,它们不会再运行3秒钟了。

Most importantly, at this point, the value of i is 4 . 最重要的是,此时i值为4

Three seconds later... 三秒钟后...

Finally, our function print that we gave to setTimeout is going to run. 最后,我们给setTimeout提供的函数print将运行。 So what does that function look like?: 那么该函数是什么样的呢?

function print(array) { console.log(i); }

Now recall the value of i is now 4. So it prints 4 , four times. 现在回想一下, i的值现在是4。因此它打印4次,四次。 This is because it is when the function actually executes that it reads the value of the variable i , not when the function was declared. 这是因为在函数实际执行时才读取变量i的值, 而不是在声明函数时。

Basically, i is 4 at the time that your function print is actually invoked, so therefore, it unsurprisingly prints 4 . 基本上,在实际调用函数print时, i为4,因此,毫不奇怪,它打印4

Look again at the inner function which is being called by the timeout. 再次查看超时所调用的内部函数。

function print(array){
    console.log(i);
}

At no point is the passed in array actually used for anything, in fact the following code will do exactly the same thing (print 4 4 4 4) 传入的数组在任何时候都不会真正用于任何事情,实际上,以下代码会做完全相同的事情(打印4 4 4 4)

for(i = 0; i < array.length; i++) {
  setTimeout(function print(){
      console.log(i)}, 3000);
}

The pass by reference part means that it isn't the value of i which is passed in to the print() function, but a reference to whatever value is held by i at the time console.log(i) is called. 通过引用传递部分意味着传递给print()函数的不是i的值,而是对i在调用console.log(i)时所保存的任何值的引用。 Since there is a 3 second delay, the loop has more than enough time to finish and the value of i is 4 by the time the first console.log(i) is called. 由于存在3秒的延迟,因此循环有足够的时间来完成,并且在调用第一个console.log(i)时,i的值为4。 You can even set the value of i after the loop and it will change the result. 您甚至可以在循环后设置i的值,它将改变结果。

for(i = 0; i < 4; i++) {
  setTimeout(function print(){
      console.log(i)}, 3000);
}

i = "foo";
// prints foo foo foo foo

您的setTimeout使您的代码异步,我们不再等待3000的超时,javascript循环在此之前结束,索引的最后一个值也是4。搜索“ js Eventloop”,您将发现更多关于浏览器简而言之。

There's only a single value of i . i只有一个值。 Calling setTimeout doesn't store the original value anywhere. 调用setTimeout不会在任何地方存储原始值。

Because the print function is called after the for-loop has finished running, the value of i will be 4 because it's the value it'll have at the end of the for-loop. 因为print函数是在for循环完成运行之后调用的,所以i的值为4因为它是在for循环结束时使用的值。

To be able to use 'i' value you need something called closure. 为了能够使用“ i”值,您需要一种叫做闭包的东西。 When the function execute at that time i value became 4 and it gets printed. 当函数在那个时候执行时,我的值变成4并被打印。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 尝试在JavaScript中复制通过引用行为:如何适当地修改我的代码 - Trying to replicate pass-by-reference behavior in JavaScript: How to modify my code appropriately 通过引用传递 JavaScript 对象 - Pass-by-reference JavaScript objects JavaScript 是按引用传递还是按值传递语言? - Is JavaScript a pass-by-reference or pass-by-value language? 使用包装程序在Python / Javascript中模仿按引用传递-良好做法? - Mimicking Pass-By-Reference in Python/Javascript Using Wrappers - Good Practice? JavaScript中的按值传递和按引用传递有什么区别? - What's the difference between pass-by-value and pass-by-reference in JavaScript? 是否可以通过引用传递或访问实际对象? - Is it possible to pass-by-reference or access the actual object? JavaScript:创建未知维多维数组函数时的按引用传递问题 - JavaScript : Pass-by-reference issues when creating an unknown dimension multi dimensional array function javascript如何通过引用工作传递? - How does javascript pass by reference work? javascript中的值传递和引用传递到底是如何工作的? - How exactly is does pass by value and pass by reference work in javascript? 在 javascript 中,数组显示“按值传递”行为而不是“按引用传递” - In javascript, array is showing 'pass by value' behavior instead of 'pass by reference'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM