Js基礎(二) 做用域鏈與閉包相關

一、執行上下文閉包

在一段script 或者一個函數做用域中 都會生成一個執行上下文app

在全局執行上下文中 js會將 變量 與 函數聲明提取出來函數

在函數執行上下文中 在函數執行以前 會將函數內的變量定義 函數聲明 this arguments 提取出來this

 

 二、this指向spa

做爲構造函數執行指針

做爲對象屬性執行code

普通函數執行對象

call apply bind 方式執行blog

this只有在執行時纔會改變指針 定義時this不會指向任何對象 js是解釋型語言不是定義型ip

三、做用域鏈

函數做用域鏈與this偏偏相反 this是隻有在執行時候確認 而做用域鏈是函數在定義時就已經肯定了

自由變量 當前函數沒有定義的變量叫作自由變量 官方解釋: 閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即便已經離開了創造它的環境也不例外 上一段代碼解釋閉包

    <script>
        function fn1(){
            var a = 10
            return function(){
                return a
            }
        }
        var a = 100
        var fn = fn1()
        console.log(fn)
        console.log(fn())
        
    </script>

上面輸出結果是10 也就是說 函數定義的時候其做用域鏈就已經固定 而且 函數定義時 它的做用域和引用的自由變量就已經固定 不管這個函數 在任何位置引用 調用它內部的自有變量都不會再改變了 理論上說任何一個函數都是一個閉包 那麼閉包主要的應用場景就是 保護變量 返回函數 傳入函數

        function fn1(){
            var a = 10
            return function(){
                return a
            }
        }

        var fn = fn1()

        function fn2 (fn){
            var a = 1000
            console.log(fn())
        }

        fn2(fn)

輸出結果仍然是10 不管任何環境閉包的做用域和自由變量都已經定死了 下面舉兩個簡單的閉包案例

    <script>
        for(var i = 0; i < 10 ; i++){
            (function(i){
            var a = document.createElement('a')
            a.innerHTML = i + '<br/>'
            a.onclick = function(){
                alert(i)
            }
            document.body.appendChild(a)
            })(i)

        }
    </script>

上面每次執行咱們都建立了一個獨立的自執行函數 而後將 i 傳入 這個時候自執行函數會將 i 變量固定的保存下來 下面舉一個變量權限的例子

        function firstIndex(){
            var _list = []
            return function(id){
                if(_list.indexOf(id) >= 0 ){
                    return false
                }else{
                    _list.push(id)
                    return true
                }
            }
        }
        var fn = firstIndex()
        console.log(fn(10))
        console.log(fn(10))
        console.log(fn(20))
相關文章
相關標籤/搜索