gpt4 book ai didi

javascript - Javascript 和 Lua 闭包的区别

转载 作者:可可西里 更新时间:2023-11-01 02:09:25 26 4
gpt4 key购买 nike

为什么这两段看似相同的代码在 Javascript 和 Lua 中表现不同?

路亚:

function main()
local printFunctions={}
local i,j
for i=1,10 do
local printi = function()
print(i)
end
printFunctions[i]=printi
end
for j=1,10 do
printFunctions[j]()
end
end
main()

Javascript:

function main()
{
var printFunctions=[]
var i,j;
for(i=0;i<10;i++)
{
var printi = function()
{
console.log(i);
}
printFunctions[i]=printi;
}
for(j=0;j<10;j++)
{
printFunctions[j]();
}
}
main()

Lua 中的示例打印 0 1 2 3 4 5 6 7 8 9,但 Javascript 中的示例打印 10 10 10 10 10 10 10 10 10 10。谁能解释导致这种情况发生的 Javascript 和 Lua 闭包之间的区别?我来自 Javascript 背景,所以请关注 Lua 方面。

我试图在 my blog 上对此进行解释, 但我不确定我的解释是否正确,所以如有任何澄清,我们将不胜感激。

编辑

谢谢大家,我明白了。这个稍作修改的 Lua 代码版本按预期打印 10,10,10,10,10,10,10,10,10,10

function main()
local printFunctions={}
local i,j,k
for i=1,10 do
k=i
local printi = function()
print(k)
end
printFunctions[i]=printi
end
for j=1,10 do
printFunctions[j]()
end
end

main()

最佳答案

就这么简单:

Lua local 变量的范围仅限于最近的 do-end block ,而使用 var 声明的 JavaScript 变量的范围仅限于最近的函数界限。闭包通过将它们放在函数中自己的独立范围内来解决这一点,从而解决了范围问题。

关于你关于 local i, j 在外部作用域中的问题,Lua 中的 for 语句创建了在 block 作用域中使用的计数器的作用域,即使在外部范围。文档说 ( reference ):

The loop variable v is local to the loop; you cannot use its value after the for ends or is broken. If you need this value, assign it to another variable before breaking or exiting the loop.

这意味着 var 初始化是在 for 循环范围内进行的,因此将 local i, j 放在外部范围内没有任何效果。这可以在文档中给出的等同于 Lua 的 for 语句中看到:

do
local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
if not (var and limit and step) then error() end
while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
local v = var
block
var = var + step
end
end

但是,JavaScript 的 for 语句差异很大 ( reference ):

IterationStatement : for ( var VariableDeclarationListNoIn ; Expressionopt ; Expressionopt ) Statement

Because the declaration of the for loop is the same as any ordinary variable declaration, it's equivalent to placing it outside the loop, much different to how the Lua for loop works. The next version of ECMAScript (ES6) plans to introduce the let keyword, which in a for loop will have a similar meaning to how Lua's for loop works:

for (let i = 0; i < 10; ++i) setTimeout(function () { console.log(i); }, 9); // 0,1,2,3,4,5,6,7,8,9
for (var i = 0; i < 10; ++i) setTimeout(function () { console.log(i); }, 9); // 10,10,10,10,10,10,10,10,10,10

关于javascript - Javascript 和 Lua 闭包的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19236783/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com