Javascript 在谷歌';达特朗酒店

Javascript 在谷歌';达特朗酒店,javascript,dart,closures,Javascript,Dart,Closures,在调用第一个函数之前,我希望这个Dart程序中的整数“I”被设置为9。然而,这个程序的输出是 0,2,4,6,8,10,12,14,16,18 typedef int TestFun(int x); void main() { List<TestFun> functionList = new List<TestFun>(); for ( int i = 0; i < 10; i++) { functionList.

在调用第一个函数之前,我希望这个Dart程序中的整数“I”被设置为9。然而,这个程序的输出是

0,2,4,6,8,10,12,14,16,18

typedef int TestFun(int x);

void main()
{
    List<TestFun> functionList = new List<TestFun>();

    for ( int i = 0; i < 10; i++) {        
        functionList.add( (int x) => x + i );      
    }

    for ( int j = 0; j < 10; j++) 
    {
        print(functionList[j](j));
    }    
}
当我通常期望10、11、12、13。。。。就像JavaScript、C#等一样

镖郎输出:0、2、4、6、8、10、12、14、16、18

typedef int TestFun(int x);

void main()
{
    List<TestFun> functionList = new List<TestFun>();

    for ( int i = 0; i < 10; i++) {        
        functionList.add( (int x) => x + i );      
    }

    for ( int j = 0; j < 10; j++) 
    {
        print(functionList[j](j));
    }    
}
typedef int TestFun(int x);
void main()
{
列表函数列表=新列表();
对于(int i=0;i<10;i++){
functionList.add((int x)=>x+i);
}
对于(int j=0;j<10;j++)
{
打印(功能列表[j](j));
}    
}
等效JavaScript。。。。输出10,11,12

var functionList = new Array;

for ( var i = 0; i < 10; i++) {
    functionList[i] = function (x) { return x + i } ;
}

for ( var j = 0; j < 10; j++) {
    alert( functionList[j](j) );
}
public delegate int TestDel(int x);

public static void Main(string[] args)
{
    IList<TestDel> functionList = new List<TestDel>();

    for ( int i = 0; i < 10; i++) 
    {
        functionList.Add((int x) => x + i);      
    }

    for ( int j = 0; j < 10; j++) 
    {
        System.Console.WriteLine(functionList[j](j));
    }    
}
var functionList=新数组;
对于(变量i=0;i<10;i++){
functionList[i]=函数(x){返回x+i};
}
对于(var j=0;j<10;j++){
警报(功能列表[j](j));
}
等效C#。。。。输出10,11,12

var functionList = new Array;

for ( var i = 0; i < 10; i++) {
    functionList[i] = function (x) { return x + i } ;
}

for ( var j = 0; j < 10; j++) {
    alert( functionList[j](j) );
}
public delegate int TestDel(int x);

public static void Main(string[] args)
{
    IList<TestDel> functionList = new List<TestDel>();

    for ( int i = 0; i < 10; i++) 
    {
        functionList.Add((int x) => x + i);      
    }

    for ( int j = 0; j < 10; j++) 
    {
        System.Console.WriteLine(functionList[j](j));
    }    
}
公共委托inttestdel(intx);
公共静态void Main(字符串[]args)
{
IList functionList=新列表();
对于(int i=0;i<10;i++)
{
functionList.Add((int x)=>x+i);
}
对于(int j=0;j<10;j++)
{
System.Console.WriteLine(functionList[j](j));
}    
}

这是飞镖虫吗?有人能给我解释一下这种行为吗?

我觉得你的结论很奇怪

您添加的第一个闭包实际上是(i=0)

functionList[i]=函数(x){return x+0};
在第二个
for
循环(第一次迭代)中,使用参数
0
执行第一个函数。如何将此结果转换为
10

编辑

为了避免lrn提到的行为,可以将变量放入对象中

typedef int TestFun(int x);
类Int{
int-val;
Int(this.val);
}
void main(){
列表函数列表=[];
for(Int i=new Int(0);i.val<10;i.val++){
functionList.add((int x)=>x+i.val);
}
对于(int j=0;j<10;j++){
打印(功能列表[j](j));
}
}
Dart在这里故意避免JavaScript的易出错行为。 声明自己变量的for循环在每次迭代中都会有该变量的新版本。这既适用于(var x=…;;)的
,也适用于(var x in…
(在后一种情况下,变量甚至可以是最终变量)

显示每次迭代引入新自变量的示例:

类框{
最终功能集;
最终函数get;
盒子(this.get,this.set);
字符串toString()=>“[${get()}]”;
}
main(){
变量框=[];
对于(int i=0;i<5;i++){
添加(新框(()=>i,(x){i=x;}));
}
打印(框);//[[0]、[1]、[2]、[3]、[4]]
对于(int i=0;i<5;i++){
盒[i].集(i*2+1);
}
打印(框);//[[1]、[3]、[5]、[7]、[9]]
}

似乎有一个bug
(int x)=>x+1
。我想你想要
(intx)=>x+I
是的,复制并粘贴错误的示例代码。它现在已经修复了,thanksperhaps您应该尝试一下:d变量i的作用域被限制在for循环中,直到它被折叠到闭包中。但是,在调用匿名函数之前,我一直在进行迭代。当数组中的第一个函数被调用时。。。“i”的值应该是9。试一试,我发布的javascript示例只在firefox测试版中测试过,但我相信它在浏览器中也会以同样的方式工作。C#/JS还通过值传递int等本机类型。然而,闭包不是这样工作的。“闭包(也称为词法闭包或函数闭包)是一个函数或对函数的引用以及一个引用环境—一个存储对该函数的每个非局部变量(也称为自由变量或upvalues)的引用的表。[1]闭包不同于普通函数指针,它允许函数访问这些非局部变量,即使在其直接词法范围之外调用。因此,当使用闭包在有限范围内折叠值时,不会传递任何信息。如果您希望在for循环中使用相同的变量,也可以这样做,而无需装箱。您只需在循环外部声明变量:
inti;对于(i=0;i<10;i++)函数列表,添加((int x)=>x+i)将使所有函数加10。这也适用于
for in
中的
for-只有在
for
语句中声明的变量才能在每次迭代中获得新版本。如果您认为for(…)循环等效于[0,1,2,3,4,…],则可能会有所帮助。forEach((i)=>存在差异,但它说明了变量。