<strike id="cy2gs"><menu id="cy2gs"></menu></strike>
  • <del id="cy2gs"><dfn id="cy2gs"></dfn></del>
  • JS作用域、立即執行函數、閉包

    2018-4-25    seo達人

    如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

    作用域    

    首先先介紹一下作用域等一些基礎概念。

     每個JavaScript函數都是一個對象,對象中有些屬性我們可以訪問,但有些不可以,這些屬性僅供JavaScript引擎存取,[[scope]]就是其中一個。

    [[scope]] : 指的就是我們所說的作用域,其中存儲了執行期上下文的集合

    作用域鏈 : [[scope]] 中所存儲的執行期上下文對象的集合,這個集合呈鏈式鏈接,我們把這種鏈接叫做作用域鏈。

    運行期上下文  : 當函數執行時,會創建一個稱為執行期上下文的內部對象(AO)。一個執行期上下文定義了一個函數執行的環境,函數每次執行時對應的執行環境都是的,所以多次調用一個函數會導致創建多個執行上下文,當函數執行完畢,它所產生的執行上下文被銷毀。

    查找變量  :從作用域鏈的頂端依次向下查找。

    下面舉一些例子:

    [html] view plain copy
    1. function a(){  
    2.     function b(){  
    3.         function c(){  
    4.   
    5.         }  
    6.         c();  
    7.     }  
    8.     b();  
    9. }  
    10. a();  
    11.   
    12.   
    13. a defined a.[[scope]] ----> 0 : GO          //a定義的時候產生GO對象  
    14. a doing   a.[[scope]] ----> 0 : aAO           //a執行的時候新產生AO對象  
    15.                             1 : GO  
    16.   
    17. b defined  b.[[scope]] ----> 0 : aAO            //子級b定義會繼承父級a運行時產生的對象  
    18.                              1 : GO   
    19. b doing    b.[[scope]] ---->  0 : bAO            //子級b新產生AO對象  
    20.                               1 : aAO   
    21.                               2 : GO   
    22.                                 
    23. c defined  c.[[scope]] ---->  0 : bAO            //c定義時會繼承b運行時產生的屬性  
    24.                               1 : aAO   
    25.                               2 : GO                          
    26. c doing     c.[[scope]] ----> 0 : cAO            //c執行時同時又產生新的AO  
    27.                               1 ;bAO   
    28.                               2 : aAO   
    29.                               3 : GO   

    立即執行函數

    之前學過函數的定義、函數表達式,還有一種函數叫做立即執行函數。

    立即執行函數:函數執行過后立即被銷毀。

    立即執行函數的官方寫法:

    [html] view plain copy
    1. // 立即執行函數的官方寫法  
    2. (function() {} ());  W3C建議此種  
    3. (function() {})();  

    針對初始化功能的函數,可以有參數。

    [html] view plain copy
    1. var num = function (a,b){  
    2.     return a + b;  
    3. }(1,2);  
    4.   
    5. (function abc(){  
    6.     var a = 123;  
    7.     var b = 234;  
    8.     console.log(a+b);  
    9. }())  

    只有表達式才能被執行符號執行,能被執行符號執行的表達式,函數名字會被自動忽略。

    [html] view plain copy
    1. function test(){  
    2.     console.log("a");  
    3. }()    會出現語法解析錯誤,因為括號前面是函數聲明  
    4.   
    5. (+ function test( ){  
    6.     console.log('a');  
    7. }())                    -------->打印出a  

    下面是一道曾阿里面試題

    [html] view plain copy
    1. function test(a, b, c, d){  
    2.     console.log(a + b + c + d);  
    3. }(1, 2, 3, 4);  
    4.   
    5. // 不報錯也沒有執行        

    下面是幾道經典的例題,可以參考一下:

    [html] view plain copy
    1.   
    [html] view plain copy
    1. function test(){  
    2.     var arr = [];  
    3.     for(var i = 0; i < 10; i ++){  
    4.         arr[i] = function (){  
    5.             console.log(i);  
    6.         }  
    7.     }  
    8.     return arr;  
    9. }  
    10. var myArr = test();  
    11. for(var j = 0; j < 10; j++){  
    12.     myArr[j]();  
    13. }    
    [html] view plain copy
    1.   
    [html] view plain copy
    1. // 輸出:10個10  

    那么采用立即執行函數呢?會有怎樣的結果呢?

    [html] view plain copy
    1. function test(){  
    2.     var arr = [];  
    3.     for(var i = 0; i < 10; i ++){  
    4.         (function(j){  
    5.             arr[i] = function (){  
    6.             console.log(j + " ");  
    7.         }  
    8.         }(i))  
    9.     }  
    10.     return arr;  
    11. }  
    12. var myArr = test();  
    13. for(var j = 0; j < 10; j++){  
    14.     myArr[j]();  
    15. }   
    [html] view plain copy
    1.   
    [html] view plain copy
    1. // 輸出結果  0 1 2 3 4 5 6 7 8 9   

    大家可以自行思考一下。

    閉包

    閉包的現象:當內部函數保存到外部時會產生閉包。


    閉包會導致原有的作用域鏈不釋放,造成內存泄漏

    (內存泄漏:內存占用(比如:手握沙子,握得越緊手里剩得就越少))


    閉包觸發的情況:

        兩個或多個函數互相嵌套,把里面的函數保存到外部,這樣的情況一定會產生閉包。從外面還可以調用里面的函數。


    閉包的作用:

                實現公有變量

                        eg:函數累加器

                可以做緩存(存儲結構)

                        eg:eater

                   可以實現封裝,屬性私有化

                        eg:person()

                    模塊化開發,防止污染全局變量



    [html] view plain copy
    1. // 函數累加器  
    2. function add(){  
    3.     var count = 0;  
    4.     function demo(){  
    5.         count ++;  
    6.         console.log(count);  
    7.     }  
    8.     return demo;  
    9. }  
    10. var counter = add();  
    11. counter();  
    12. counter();  
    13. counter();  
    14. counter();  
    15. counter();  
    16. counter();  
    17.   
    18.   
    19. // eater  
    20. function test(){  
    21.     var food = "apple";  
    22.     var obj = {  
    23.         eatFood : function (){  
    24.             if(food != ""){  
    25.                 console.log("I am eating  " + food);  
    26.                 food = "";  
    27.             }  
    28.             else{  
    29.                 console.log("There is nothing!");  
    30.             }  
    31.         },  
    32.         pushFood : function (myFood){  
    33.             food = myFood;  
    34.         }  
    35.     }  
    36.     return obj;  
    37. }  
    38. var person = test();  
    39. person.eatFood();  
    40. person.eatFood();  
    41. person.pushFood('banana');  
    42. person.eatFood();  

    附加一個逗號操作符:

            先看前面的表達式,再看后面的表達式,把后面表達式的計算結構返回

    例題:

    [html] view plain copy
    1. var f =(  
    2.     function f(){  
    3.         return "1";  
    4.     },  
    5.     function g(){  
    6.         return 2;  
    7.     }  
    8. )();  
    9. console.log(typeof(f));   
    10.   
    11. // -------number  
    12.   
    13. var x = 1;  
    14. if(function f(){}){  
    15.     x += typeof f;  
    16. }  
    17. console.log(x);  
    18. // --------> 1undefined  
    19. 藍藍設計www.skdbbs.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務

    日歷

    鏈接

    個人資料

    藍藍設計的小編 http://www.skdbbs.com

    存檔

    主站蜘蛛池模板: 国产精品福利在线观看免费不卡| 精品国产免费一区二区三区| 香蕉国产精品频视| 四虎国产精品成人| 真实国产乱子伦精品免费| 日韩精品无码一区二区三区免费| 国产三级国产精品国产普男人 | 亚洲精品午夜无码专区| 欧美极品欧美精品欧美视频| 熟女精品视频一区二区三区| 久久精品国产精品亚洲下载| 四虎成人www国产精品| 69国产成人综合久久精品| 四虎国产成人永久精品免费| 亚洲av无码成人精品区在线播放 | 狠狠精品干练久久久无码中文字幕| 91原创国产精品| 久久亚洲私人国产精品| 亚洲欧美国产精品第1页| 精品无码国产污污污免费网站国产 | 日本一卡精品视频免费| 欧美精品亚洲精品日韩精品| 国产午夜精品理论片| 91精品国产福利在线观看麻豆| 国产精品久久久久久| 成人无码精品1区2区3区免费看| 日韩精品久久无码人妻中文字幕| 伊人久久精品影院| 一区二区三区精品高清视频免费在线播放 | 国产精品对白交换视频| 久久久无码人妻精品无码| 亚洲精品国产高清不卡在线| 日本五区在线不卡精品| 欧美亚洲日本久久精品| 亚洲一级Av无码毛片久久精品| 伊人精品久久久久7777| 亚洲精品国产美女久久久| 日韩人妻无码精品久久免费一| 亚洲精品二区国产综合野狼| 中文字幕日韩精品无码内射| 一本色道久久综合亚洲精品|