首頁 > web前端 > js教程 > 主體

匿名函數、巢狀函數、閉包分別是什麼

一个新手
發布: 2018-01-27 13:58:09
原創
2210 人瀏覽過

匿名函數: 之前的文章也有講到,指的是 沒有函數名稱的函數

function (){ 
console.log('匿名函数') 
}
登入後複製

巢狀函數呢 ?  請看程式碼:

function test (){
   var  sum = 20;
   //内嵌函数
   demo = function(){
        alert(sum);
        console.log('我是嵌套函数');
    }
}
登入後複製

如程式碼所示,函數內部嵌入函數,稱為巢狀函數。

那閉包又是什麼呢?  

不多說,看程式碼

function demo(){
   var num = 0;
   
   // 返回一个函数 
   return function(){
      alert( num+1 );
   }
} 
//将返回的函数赋值给 add 变量
var add = demo();
// add就是一个闭包
add();
登入後複製

這麼看,感覺像是,只要是巢狀函數,且能存取上一層作用域的變數就是閉包。 是這樣嗎?

我們知道,js中,分成全域作用域,局部作用域,每個函數也就相等於一個局部作用域。

同理,變量,也分為全域變數和局部變數。 有什麼區別呢?

在瀏覽器中,全域作用域物件是 window,也就是說頁面一打開,window物件就存在。

在js中,每個函數是局部作用域,局部變數會隨著 函數的執行建立和執行完畢後銷毀。

而全域變量,只要頁面不關閉,就會一直存在。並不會隨著函數的執行完畢而銷毀。

那麼跟閉包有什麼關係呢? 

在 “javaScript高級程式” 這本書有講到過「作用域鏈」的概念, 特殊之處,在於函數內部可以直接讀取全域變數。

而函數外部卻無法讀取函數內部的變數。

也就是說,作用域鏈就像是只能往上不能往下的階梯。我們看段程式碼理解

var  name = "window";
var  age    =  20;
dmeo();
function demo(){
     var age = 21;
     console.log(name);  // window
     console.log(age);     //21
}
登入後複製

在執行 demo() 函數時,就會建立一個通往全域作用域鏈,保存著目前作用域的變量,以便尋找回傳。

在執行console.log( name ) 這段程式碼時,會搜尋目前作用域( demo函數) 中是否存在name 變量,因目前作用域不存在,所以在往上找到全域變數name ,因此返回window;

在執行console.log( age ) 這段程式碼時, 也會搜尋目前作用域(demo函數) 中是否存在age 變量,因為存在,所以返回21。

既然機制是只能往上讀, 那麼考慮一個問題,怎麼在外部讀取內部函數的變數呢?

辦法不是沒有,稍微變通即可。這就需要用到閉包的概念,

function  f1(){
   var num = 0 ;
   //定义内部函数
   function f2(){
      return  num + 1;
   }
   //返回 f2函数引用
   retufn  f2;
}

// bar 变量也指向 f2 函数,在此也是一个闭包
var bar = f1();

//执行
bar();   // 1;
登入後複製

我們知道,函數中的變數會隨著函數的執行完畢後會被銷毀。而如上程式碼,f1()函數執行完畢後,將f2函數賦值給一個全域變量,而f2函數的變數又依賴f1的num變量,因此,f1

中的num變數並不會隨著f1的函數執行完畢後而銷毀。

這裡借用 「阮一峰」 大神的題目藉此解析加深理解。

連結: 學習javaScript閉包

var name = "the window";
  
 var obj = {
      name : 'the obj',
      getName : function(){
          return funciton(){ 
               return this.name;
          }
      }
}

//执行 getName返回的函数
alert(obj.getName()());
登入後複製

 我們看呼叫函數分析, 分成兩部分執行。 先來看 obj.getName();  此時getName函數由 obj物件調用,因此this的值是 obj。 但此時並不是輸出而是回傳一個函數。

再加上一個(); 執行返回的函數,但此時返回的函數並沒有任何物件調用,當不是物件本身調用,this的值會被提升到 window物件。因此輸出的是 “the window" 

var name = "the Window";
var obj = {
    name : "the obj",
    getName : funciton(){
        var that = this;
        return function(){
             return that.name;
         }
    }
}
//执行 getName 返回的函数
alert(obj.getName()());
登入後複製

以上是匿名函數、巢狀函數、閉包分別是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!