原型模式故事鏈(5)--JS變量做用域、做用域鏈、閉包

上一章 JS執行上下文、變量提高、函數聲明 傳送門:https://segmentfault.com/a/11...javascript

本次咱們主要講講變量做用域和閉包
變量做用域:
顧名思義:變量起做用的範圍。
變量分爲全局變量和局部變量。
全局變量:在任何地方都能用,在全部函數以外。
局部變量:只能在定義它的函數中,以及它的子函數中使用。html

當前做用域沒有定義的變量,稱爲自由變量。java

舉例子:segmentfault

<!DOCTYPE html>
<html>
<head>
    <title>dsfg</title>
</head>
<body>
<script type="text/javascript">
    var g = 'globle';
    function fn(){
        var p = 'part';    
        console.log(g);//globle
        console.log(p);//part
    }
    fn();
    console.log(g);//globle
    console.log(p);//報錯: p is not defined
</script>
</body>
</html>

在上述例子中,g是全局變量,不存在於任何函數中,能在任何地方使用。
p則是局部變量,只能在fn函數中使用。在外部使用則會報錯。閉包

做用域鏈:
函數的變量在尋找做用域時,不看在哪執行,只看在哪定義。異步

舉例子:函數

<!DOCTYPE html>
<html>
<head>
    <title>dsfg</title>
</head>
<body>
<script type="text/javascript">
    var a = 100;
    function fn1(){
        var b = 200;
        
        function fn2(){
            var c = 300;
            console.log(a);//100
            console.log(b);//200
            console.log(c);//300
        }
        fn2();
    }
    fn1();
</script>
</body>
</html>

以變量a來解析,上述例子中體現的做用域鏈。當執行console.log(a)時,先在fn2中尋找變量a,找不到則去到fn2的父級fn1中尋找,也找不到。再到fn1的父級中尋找,也就是全局變量中尋找,終於找到了。像這樣一層一層向上查找,就叫變量做用域鏈。
若是在其中任何一層找到了,則不會繼續向上查找。線程

閉包:
下個定義:能夠訪問另外一個函數做用域變量的函數。因此閉包實際上是個函數。code

爲何要用閉包呢?
局部變量沒法共享和長久的保存,全局變量則很容易形成變量污染。閉包則能長久保存變量,又不會污染。
閉包特色:佔用更多內存,不容易被釋放。
閉包使用場景:1.函數做爲返回值(retrun 一個函數)htm

2.函數做爲參數傳遞到另外一個函數中。

舉例子:

<!DOCTYPE html>
<html>
<head>
    <title>lalala</title>
</head>
<body>
<script type="text/javascript">
    function fn(){
        var a = 100;
        return function(){
            console.log(a);
        }
    }
    var f1 = fn();
    var a = 200;
    f1();//100
</script>
</body>
</html>

1.定義外層函數,封裝被保護的局部變量。
2.定義內層函數,執行對外部函數的變量操做。
3.外層函數返回內層函數的對象,且外層函數被調用時,結果保存在一個全局變量中。

執行f1()時,a在當前函數中未定義,往父級查找fn中a=100,因此a=100;
函數變量做用域不看在哪執行,只看在哪定義

好啦好啦,jS三座大山翻過兩座了,還剩一個異步,單線程~

相關文章
相關標籤/搜索