js閉包函數的一些嘗試

最近在研究閉包函數,看到一篇博客:閉包函數調用小記,嘗試跑了一下文中的代碼,有一些思考。

大家都知道閉包函數在操作循環變量時會有問題,因爲內部匿名函數並非立即執行,而是在函數被引用時纔會執行,所以內部函數用到的循環變量在執行的時候早就不是當初那個變量了。對於文章中的內部函數,是onfocus動作觸發的函數,所以只有當鼠標聚焦到某個輸入框內時,纔會觸發該函數,所以無論如何,該函數不會立即執行也不能立即執行,必須想辦法把item跟函數先鎖死。

文中對輸入框問題提出了三個解決方案,但細究的話,其實還是如何將當下循環的item變量提前傳入內部函數中,先綁死,等執行的時候自然就調用屬於自己的循環變量了,下面逐一分析一下:

解決一:

文中這個解決方案其實不是增加一層閉包的問題,而是把閉包獨立寫出來,並且通過傳參res將item.showcount跟閉包函數綁死,這樣,即使不立即執行閉包函數,參數也已經傳進去了。

解決二:

方案二與一其實本質一樣,但文中代碼有錯,匿名函數必須傳入當前的循環變量item,否則不起作用。

所以正確的代碼應爲:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>這是一個閉包測試</title>

</head>
<body>

<p id="showid">顯示焦點元素</p>
<p>Name: <input type="text" id="name"></p>
<p>E-mail: <input type="text" id="email"></p>
<p>Age: <input type="text" id="age"></p>

<script type="text/javascript">

   function setshowid() {
        var Text = [
            {'id': 'email', 'showcont': '正在輸入郵箱'},
            {'id': 'name', 'showcont': '正在輸入姓名'},
            {'id': 'age', 'showcont': '正在輸入年齡'}
        ];

        for (var i = 0; i < Text .length; i++) {
            var item = Text [i];
            (function(item){
                document.getElementById(item.id).onfocus = function(){
                    showiddom(item.showcont);
            }
            })(item);
        }
    }
    setshowid();
   
    function showiddom(res) {
        document.getElementById('showid').innerHTML = res;
    }

</script>
</body>
</html>

解決三:

就是通過區分塊作用域的 let 方式聲明變量,也可以解決問題。

發佈了29 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章