首頁  >  文章  >  web前端  >  對於js閉包進一步理解

對於js閉包進一步理解

不言
不言原創
2018-07-18 17:16:141378瀏覽

這篇文章給大家分享的內容是關於對js閉包進一步理解,內容很不錯,有需要的朋友可以參考一下。

閉包這個概念  自我幾個月前開始學習JS開始  我就一直困惑

之前也有所理解  但是後來長時間不用就給忘記了

閉包:通俗的講  大多數人所接受的就是一個函數有權利使用另一個函數裡的局部變數

我看到了很多的不同之處

用最簡單的程式碼表示

<span style="font-size: 14px;">function out(){<br/><br/>var age=21;<br/><br/>function inner(){<br/>  <br/>  console.log(age);<br/><br/>}<br/><br/>return inner;<br/><br/>}<br/><br/>var fn=out();<br/> fn();  //22</span>

#很符合概念 

我覺得閉包就是在體現作用域

inner 函數實在out 函數裡面定義地 

所以console(age);

就會變數搜尋機制,先在自己(inner)函數作用域裡面找,沒找到就去out函數作用域裡面找

找到了  然後輸出  如果在out裡面沒有找到的話  會再往更大的作用域找

一直到window的作用域   下級作用域可以向上存取  上級作用域不能向下存取

作用域就是指

{  } 

且JS沒有區塊級作用域

#for(var i=0;i<5;i ){

  console.log(i);// 1 2 3 4 5

}

cosole.log(i );//5

i 不會因為出了for 迴圈就被銷毀了

##這一點要注意

好了  說了一點作用域方面的知識  現在回到了閉包

閉包核心的就是return 看看程式碼就知道了

我的理解就是  return 回傳的是inner的函數體   還有inner所能存取的作用域!

所以inner 在哪裡都可以存取到age 

範例:

<span style="font-size: 14px;">function  test(){<br/>               var age=23;<br/>                var fn=out();<br/>                 fn();  //21<br/>             <br/>             }<br/>    <br/>    test();//21</span>

 它得到的是21  而不是22  因為函數體和作用域一起返回了  那麼最近的作用域不就是out函數作用域嘍

 test 函數裡面定義了age也不可能被覆蓋滴  因為存在的作用域不同

# 它回傳了作用域  所以它所訪問的都是那個作用域裡面的變數跟你的函數現在所在的作用域無關哦

 閉包其實是一種現象   就是所有人玩DNF都在刷圖賣材料賺錢  這種現象叫搬磚

 總結一句話:跟你定義函數作用域有關,跟你執行函數的作用領域無關

 與this相反  this 是與定義時無關,與執行時有關  比較記憶

 所以你如果不能很好的理解閉包

 那你就可以像我這樣理解就好了 

 回傳的是函數本身和函數所能存取的作用域

舉一個  大家常用的  

#閉包Tab欄切換

<span style="font-size: 14px;"><!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <meta name="Generator" content="EditPlus®">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <title>Document</title>
  <style type="text/css">
  *{margin:0;padding:0<span style="font-size: 12px; color: rgb(0, 0, 0);">;}
   .box{
     width:140px;
     height:18px;
     position:relative;
     padding:6px 20px;
     margin:50px auto;
     background:#ff6666;
   }

   .box ul{
     list</span>-<span style="font-size: 12px; color: rgb(0, 0, 0);">style:none;
   } 

   .box li{
      width:18px;
      height:18px;
      background:#ff3300;
      line</span>-<span style="font-size: 12px; color: rgb(0, 0, 0);">height:18px;
      text</span>-<span style="font-size: 12px; color: rgb(0, 0, 0);">align:center;      </span><span style="font-size: 12px; color: rgb(0, 0, 255);">float</span><span style="font-size: 12px; color: rgb(0, 0, 0);">:left;
      margin</span>-<span style="font-size: 12px; color: rgb(0, 0, 0);">right:5px;
      cursor:pointer;
   }

   .current{
     background:#ffccff</span>!<span style="font-size: 12px; color: rgb(0, 0, 0);">important;
   }  </span></style>
 </head>
 <body>

  
  <p class="box">
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
    </ul>
  </p>
 
<script type="text/javascript">     <br/><span style="font-size: 12px; color: rgb(0, 0, 255);">function</span><span style="font-size: 12px; color: rgb(0, 0, 0);"> $(name){          <br/> <br/></span><span style="font-size: 12px; color: rgb(0, 0, 255);">return</span><span style="font-size: 12px; color: rgb(0, 0, 0);"> document.querySelectorAll(name);
       }        <br/> <br/></span><span style="font-size: 12px; color: rgb(0, 0, 255);">var</span>  list=$(".box ul li"<span style="font-size: 12px; color: rgb(0, 0, 0);">);        <br/><br/></span><span style="font-size: 12px; color: rgb(0, 0, 255);">var</span> len=<span style="font-size: 12px; color: rgb(0, 0, 0);">list.length;      <br/> </span><span style="font-size: 12px; color: rgb(0, 0, 255);">for</span>(<span style="font-size: 12px; color: rgb(0, 0, 255);">var</span> i=0;i<len;i++<span style="font-size: 12px; color: rgb(0, 0, 0);">){
           list[i].onmouseover</span>=(<span style="font-size: 12px; color: rgb(0, 0, 255);">function</span><span style="font-size: 12px; color: rgb(0, 0, 0);">(n){               
               </span><span style="font-size: 12px; color: rgb(0, 0, 255);">return</span> <span style="font-size: 12px; color: rgb(0, 0, 255);">function</span><span style="font-size: 12px; color: rgb(0, 0, 0);">(){                  <br/><br/></span><span style="font-size: 12px; color: rgb(0, 0, 255);">for</span>(<span style="font-size: 12px; color: rgb(0, 0, 255);">var</span> j=0;j<len;j++<span style="font-size: 12px; color: rgb(0, 0, 0);">){
                
                      list[j].className</span>=""<span style="font-size: 12px; color: rgb(0, 0, 0);">;
                
                  }
                list[n].className</span>="current"<span style="font-size: 12px; color: rgb(0, 0, 0);">;
               
               }
           })(i);


       }<br/><br/><br/><br/></span></script>



 </body>
</html></span>

for迴圈每當執行list[i].onmouseover的時候   函數都會立刻執行  傳入目前的變數i 

#回傳一個函數  這個就是形成了閉包唄  回傳函數和函數能夠存取到的作用域

#每當觸發onmouseover的時候  都會執行回傳的那個函數

然後執行代函數裡面的for迴圈把所有li的className 清空#

在執行list[n]  這句話是最重要的  這裡的n 是定義onmouseover的時候傳入的i 

因為當定義的時候函數立刻執行把 i 傳遞給了匿名函式這個 i 就在匿名函式的作用域裡面了

每個onmouseover都是保存各自的 i

所以當觸發 onmouseover的時候能夠讓li訪問到之前保存在作用域中的 i

#也實現了點誰誰背景顏色變化的需求

相關推薦:

對js函數的實參,形參以及閉包的理解

#

以上是對於js閉包進一步理解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn