Javasript 闭包 stange 行为

Javasript closure stange behaviour

提问人:Luca 提问时间:8/9/2023 最后编辑:Luca 更新时间:8/9/2023 访问量:41

问:

强调文本嗨,我正在学习 Javascripts 闭包和 tjis 代码对我来说很有趣:

function Unique_id2() {
    let counter = 0;
    function f() { return counter++; };
    return f();
}

console.log("UID2");
let f = Unique_id2;
console.log(typeof f);
console.log(f());
console.log(f());
console.log(f());
console.log(f());
console.log(f());

结果是:

UID2
functions.js:65 function
functions.js:66 0
functions.js:67 0
functions.js:68 0
functions.js:69 0
functions.js:70 0

这对我来说是扼杀,因为计数器每次都是递增的......

你能解释一下出了什么问题吗

编辑

function Unique_id2() {
        let counter = 0;
        function f() { return counter++; };
        return f;
    }

    console.log("UID2");
    let f = Unique_id2;
    console.log(typeof f);
    console.log(Unique_id2()());
    console.log(Unique_id2()());
    console.log(Unique_id2()());
    console.log(Unique_id2()());
    console.log(Unique_id2()());

产生相同的结果

JavaScript 闭包

评论

2赞 deceze 8/9/2023
您可能只是想代替 ,然后调用多次返回的函数......return freturn f()
0赞 mykaf 8/9/2023
counter作用域为功能,因此每次调用它时都会重置。Unique_id2
0赞 deceze 8/9/2023
在你最近的所有编辑中,你仍然做错了。下面的答案向您展示了一种正确的方法。就这样做吧。

答:

2赞 Barmar 8/9/2023 #1

您不会返回闭包,您只是在每次调用时调用它。每次执行此操作时,它都会将计数器重置为 0 并返回该计数器。Unique_id2()

若要获得递增计数器,必须返回闭包,而不是调用它的结果。然后,您应该重复调用闭包以获取每个递增的值。

因此,在下面的代码中,调用并将其分配给一个变量,例如 或 。然后,当您调用时,您将获得递增的计数器值。Unique_id2()ff2f()

function Unique_id2() {
    let counter = 0;
    function f() { return counter++; };
    return f;
}

console.log("UID");
let f = Unique_id2();
console.log(typeof f);

console.log(f());
console.log(f());
console.log(f());
console.log(f());
console.log(f());

console.log("UID2");
let f2 = Unique_id2();
console.log(typeof f2);
console.log(f2());
console.log(f2());

评论

0赞 Luca 8/9/2023
我只是得到 f() { counter++;作为每次迭代的回报
0赞 slebetman 8/9/2023
@Luca 是的,你得到.这是一个功能。所以叫它f () {counter++}
0赞 Luca 8/9/2023
@slebetman它是 alteady 一个用 not args 调用的函数,如果我再次调用它,每次迭代都会产生 0
0赞 slebetman 8/9/2023
@Luca 你有没有像上面的答案一样打电话?f()f2()
0赞 Barmar 8/9/2023
@Luca 如果你这样做而不是.请注意变量名称后面的。console.log(f)console.log(f())()
0赞 Luca Fagioli 8/9/2023 #2

即使使用不同的名称和参考资料,您每次都会打电话。Unique_id2

每次调用它时,该函数都会将变量初始化为 0。Unique_id2counter

为了实现您要执行的操作,您需要将 的初始化移出范围,如下所示:counterUnique_id2

let counter = 0;

function Unique_id2() {    
    function f() { return counter++; };
    return f;
}

console.log("UID");
let f = Unique_id2();
console.log(typeof f);

console.log(f());
console.log(f());
console.log(f());
console.log(f());

这样,变量只初始化一次,并且由于闭包,可以访问它。counterUnique_id2