JavaScript閉包

以前講閉包的文章,不少初學者,仍是沒懂,仍是在寫一篇。原文地址:http://www.w3cfuns.com/blog-5471724-5409375.html
先說句題外話,你看完以後,以爲講得清楚的話,點個贊,只要兩個就能上今日推薦,讓更多人看到。若是認爲我講的很差,甚至講錯了,歡迎指正。
本文開始,先看最簡單的代碼。
function a(){
    function b(){
        x++;
        return x;
    }
    console.dir(b);
}
a();html

我再來講說閉包,保證初學者能看懂
從上面能夠看出,b函數中是保存a做用域中的x的,雖然從chrome中能夠看出,x保存在b的closure中,
可是咱們也不會吧b叫作閉包的。由於此時b不能在a的做用域以外調用從而訪問a中的變量x;chrome

咱們先看看在a中調用b的情形
function a(){
    var x = 0;
    function b(){
        x++;
        return x;
    }
    b();
    b();
    console.dir(b);
}
a();瀏覽器

我再來講說閉包,保證初學者能看懂
b中的確實保存了x的最新值。再一次聲明,b不能叫作閉包,在我看來就是做用域鏈的問題。就像你說女人是人,是正確的。若是你把女人當人的定義來講。我就不一樣意了。
做用域鏈能解釋明白的事情,就不必發明閉包這個概念。緩存

做用域鏈是產生閉包這個現象的核心條件之一,還差另外一個重要的因素,纔是咱們說的閉包現象。那就是你這個b函數必須在a的做用域以外調用才行。
怎麼能在a的做用域以外調用b呢,兩個辦法。1.把b作爲a的返回值結構的一部分。2.把b綁定dom的事件上。
對於第一種,a能返回b,運行完a以後,保存a的返回結果,天然拿到b函數,而後再調用b,這樣確實是在a的做用域以外調用b了。
至於第二種,把b綁定dom的click事件上,咱們點擊dom觸發b運行,也能夠說在a的做用域以外,調用了b。
多說一句,js中爲啥有閉包現象,函數能當參數傳,能當返回值,這纔是核心緣由,也是js這麼屌的緣由。閉包

這裏主要來講說第一種狀況
function a(){
    var x = 0;
    function b(){
        x++;
        return x;
    }
    return b;
}
var c =a();
c();
c();
console.dir(c);dom

我再來講說閉包,保證初學者能看懂
從打印來看c正是a中的b,c運行兩次,至關在a中運行了b兩次。函數

而初學者,之因此容易弄不明白,總以爲運行兩次c,認爲裏面的x仍始終是1;
緣由很簡單,c()這麼調用不是運行a,實際是運行b,而a呢,你始終運行了一次。如代碼中var c = a()這句話。
初學者之因此以爲x始終是1,其實像以下代碼調用,纔是你錯誤理解的方式
function a(){
    var x = 0;
    function b(){
        x++;
        return x;
    }
    return b;
}
var c =a();
c();
var d =a();
d();
console.dir(c);
console.dir(d);測試

我再來講說閉包,保證初學者能看懂
c和d其實都是b,注意這裏兩個b不是同一個b,是長的如出一轍的雙胞胎,由於a運行了兩次,於是是兩個。建議你研究研究,值類型和引用類型的區別。
至於綁定dom,本身敲敲代碼吧。

htm

c和d其實都是b,注意這裏兩個b不是同一個b,是長的如出一轍的雙胞胎,由於a運行了兩次,於是是兩個。建議你研究研究,值類型和引用類型的區別。
至於綁定dom,本身敲敲代碼吧。
本文完。
<script>
  var a =function(){
  var x =0;
       function f(){
          alert(++x);
      }
      f();
      f();
      try{
          return f
      }
      finally{
          f();
          f();
      }
  }
var b =a();//返回裏面的f
b();
b();blog

//用於對比
function g(){
alert(++x);
}
console.dir(b);
console.dir(g);
</script>

我也來講說閉包,續例
finally能夠忽略,只是演示一下,返回完之後運行的狀況。其餘很少說了,此時無聲勝有聲。在來一個綁定到dom上閉包情形
<section>
    <button id="btn1">按鈕1</button>
    <button id="btn2">按鈕2</button>
</section>
<script>
var c = function(){
    var x =3;
    var b1=document.getElementById('btn1');
    b1.onclick = function(){alert(x)};
    console.dir(b1.onclick);
}
c();
var d = function(){
    var x =3;
    var b2=document.getElementById('btn2');
    b2.onclick =function(){alert("沒有用任何上層變量")};
    console.dir(b2.onclick);
}
d();
</script>

我也來講說閉包,續例
若是c和d合併一個函數,b2.onclick也保存了變量3.不知是chrome瀏覽器特有?沒有拿其餘瀏覽器測試。反正函數裏既然沒有使用到變量,瀏覽器作不作成閉包,緩不緩存局部變量。對於咱們使用者來講,沒啥影響。這裏就不上代碼和圖了

 

注意:摘抄於https://www.qdfuns.com/article/17398/68357db148a3aea1b7ac9d7ae071fc2d.html

相關文章
相關標籤/搜索