gpt4 book ai didi

javascript - 具有相同功能的多个事件监听器存储单独的局部变量?

转载 作者:行者123 更新时间:2023-12-01 09:47:22 25 4
gpt4 key购买 nike

我对javascript中的闭包相当陌生(当然是在将它们应用于事件处理程序时!),并试图掌握导致此代码行为的基本原理:

function showClick() {
var clicks = 0
return function(e) {
clicks++
console.log("click "+clicks+" at "+[e.clientX,e.clientY])
return clicks
}
}

document.getElementById("b1").onclick=showClick()
document.getElementById("b2").onclick=showClick()
<button id="b1">Record my Clicks</button> <!--only stores click history of b1, disregarding b2-->

<button id="b2">Record MY Clicks</button> <!--only stores click history of b2, disregarding b1-->



我可以看到,每次触发事件时,“clicks”的值都会被更新和存储(大概在事件处理函数 return 中?),但仅针对被单击的相应按钮执行此操作。这些值是如何存储的,为什么它们不在两个事件处理程序之间共享?如果我希望在两个按钮之间共享“clicks”的值,是否需要在两者范围之外分配一个变量?

最佳答案

你必须在“范围”中思考。当您调用 showClick()有一个范围。在这个范围内,它创建了一个变量,称为“clicks”。此变量在此函数和所有子函数/闭包中有效。

该函数返回一个新函数,即所谓的闭包。这个闭包保持对封装函数范围的访问。每次调用showClick()生成一个新的范围,在这个范围内变量 clicks .此外,还有创建和返回的闭包。范围,此范围内的变量和闭包是不一样的。每次调用 showClicks 时都会有所不同。

这就是为什么它们分别计算两个链接的原因。

如果您想同时计算两次点击...有多种解决方案。

  • 首先,您可以删除关闭。你不需要它。
  • 将闭包保存为 showClick 函数的上下文,并在每次调用 showClick 时使用它
  • 将点击保存在全局范围内(不推荐)

  • 编辑:就像这里的评论中所问的那样,有两种方法可以保存闭包并重用它:

    1)“Singleton-Approach I”(保存闭包本身)
    function showClick() {
    if(showClick.closure) return showClick.closure;
    var clicks = 0;
    return showClick.closure = function(evt) {
    clicks++;
    console.log(clicks+' at '+evt.clientX+' / '+evt.clientY);
    }
    }
    document.getElementsByTagName('a')[0].onclick = showClick();
    document.getElementsByTagName('a')[1].onclick = showClick();

    2)“Singleton-Approach II”(保存点击次数)
    function showClick() {
    showClick.clicks = showClick.clicks || 0;
    return function(evt) {
    showClick.clicks++;
    console.log(showClick.clicks+' at '+evt.clientX+' / '+evt.clientY);
    }
    }
    document.getElementsByTagName('a')[0].onclick = showClick();
    document.getElementsByTagName('a')[1].onclick = showClick();

    3)“Context-Approach”(将闭包保存为工厂函数的上下文)
    var showClick = (function showClick() {
    return this;
    }).bind((function() {
    var clicks = 0;
    return function(evt) {
    clicks++;
    console.log(clicks+' at '+evt.clientX+' / '+evt.clientY);
    };
    })());
    document.getElementsByTagName('a')[0].onclick = showClick();
    document.getElementsByTagName('a')[1].onclick = showClick();

    关于javascript - 具有相同功能的多个事件监听器存储单独的局部变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45807014/

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