Access to copied integer variable in javascript anonymous method

I am a C # developer and used to work in C #. I currently have to work with anonymous javascript functions and experience a problem with the following snippet:

function ClosureTest() { var funcArray = new Array(); var i = 0; while (i < 2) { var contextCopy = i; funcArray[i] = function() { alert(contextCopy); return false; }; i++; } funcArray[0](); funcArray[1](); } 

I expect the first call to funcArray() say 0 , and the second to 1 . However, both of them say 1 . How is this possible?

We write var contextCopy = i to make sure that I create a copy of i -variable. Then in each while iteration, I create a completely new function pointer. Each function refers to its own copy of i , which is contextCopy . However, both created functions for one reason or another refer to the same contextCopy -variable.

How does it work in javascript?

+6
source share
3 answers

JavaScript has lexical closures, not locks. Despite the fact that you assign me contextCopy, contextCopy itself is a lexical member of ClosureTest (which is different from C #, where {} gives you a new cloud block). Try the following:

 while (i < 2) { funcArray[i] = (function(value) { return function(){ alert(value); return false; } })(i); i++; } 
+11
source

In curly brackets ( {} ), variables are not written in JavaScript, as in C #.

Only closures (functions) introduce a new scope and capture variables.

 var i = 0; while (i < 2) { var contextCopy = i; ... } 

actually interpreted as:

 var i, contextCopy; i = 0; while (i < 2) { contextCopy = i; ... } 

To get a copy of the variable, you need to wrap the code with a closure:

 var i; i = 0; while (i < 2) { (function (contextCopy) { ... }(i)); } 
+7
source

You are not making a copy of the variable i. Instead, you make this variable GC-dependent on closures that use it. This means that when the while loop exits, the i-variable continues to live in its last state (1), and both closures refer to it.

Another way: closing a variable does not copy it to your close (it does not make sense for objects), it just makes you refer to this variable and ensures that this variable will not be GCed until it is closed.

0
source

Source: https://habr.com/ru/post/902018/


All Articles