JS基礎-做用域、做用域鏈與閉包 Part three

1.做用域閉包

執行上下文 (變量提早、函數聲明提早、肯定this值、arguments)app

範圍:一段<script>或者一個函數(都會生成一個執行上下文)

    全局(一段<script>):變量定義、函數聲明
    函數:變量定義、函數聲明、this、arguments(參數集合)

變量提早代碼解析:函數

consol.log(a) //undefined
var a = 100
(執行過程:(1)變量定義提早 var a = undefined
          (2)consol.log(a) //undefined
          (3)a = 100 //賦值
)

函數聲明提早代碼解析:this

函數聲明:function fn(){}
函數表達式:var fn = function(){}

fn() 
function fn(){} 
(執行過程:(1)function fn(){}
         (2)fn() )
              
fn() 
var fn = function(){}             
(執行過程:(1)var fn = undefined
         (2)fn() 
         (3)fn = function(){}   )

this (執行時才能確認,定義時沒法確認)code

this執行場景:

(1)做爲構造函數執行
   function Foo(name){
       // this = {}
       this.name = name
       // returen this
    }
    var fn = new Foo("lala")
    
(2)做爲對象屬性執行
   var obj = {
       name:"lala",
       printName: function(){
           console.log(this.name)
       }
   }
   obj.printName();//  對象屬性執行,this就是對象obj
            
(3)做爲普通函數執行
   function fn(){
       console.log(this) // window
   }
   
(4)call、apply、bind
   function fn(name,age){
       alert(name)
       console.log(this) //{x:100}
   }
   fn.call({x:100},"lala",13) //{x:100}當this
   fn.apply({x:100},["lala",13])

   var fn = function fn(name,age){
       alert(name)
       console.log(this) //
   }.bind({x:100}) //函數表達式.bind
   fn("lala",13)

做用域 JS沒有塊級做用域,只有函數和全局做用域對象

(1)無塊級做用域
    if(true){
        var a = 10
    }     
    console.log(name) //name  
    
(2)函數做用域和全局做用域
    var a = 10 //全局做用域(均可以訪問獲取)
    function fn(){
        var a = 20
        console.log(a) // 20 函數做用域(從外面得不到,也改不了)
    }
    console.log(a) //10
    fn()

2.做用域鏈ip

自由變量:當前做用域沒有定義的變量
函數父級做用域:函數定義時的做用域(函數在哪定義,父級做用域在哪)

var a  = 10
function fn1(){
    var b = 20
    function fn2(){
        var c = 30
        console.log(a) //10 a是自由變量
        console.log(b) //20 b是自由變量
        console.log(c)
    }
    fn2()
}
fn1()
做用域鏈:自由變量不斷向父級做用域中尋找,造成鏈式

3.閉包
應用場景:(1)函數做爲返回值作用域

function fn(){
    var a = 10
    return function(){
        console.log(a) //10
    }
}
var f1 = fn()
var a = 20
f1()

(2)函數做爲參數傳遞(函數傳遞到另外一個函數中執行)開發

function fn(){
    var a = 10
    return function(){
        console.log(a) //10
    }
}
var f1 = fn()
function f2(f){
    var a = 20
    f()
}
f2(f1)

相關問題:io

1.理解變量提高

  變量定義、函數聲明被提高(到包含他們做用域的最頂端)
 
2.建立10個a標籤,點擊時彈出對應的序號

  var i 
  for(i = 0; i < 10; i++){
     (function(i){
          var a = document.creatElement("a")
          a.innerHtml = i
          a.addEventListerner("click",function(e){
              e.preventDefault()
              alert(i)
          })
          document.body.appendChild(a)
     })()
  } 
 
 3.實際開發中閉包的應用:封裝變量,收斂權限 
  
   function isFirst(num){
       var _list = [] // _list 下劃線表示私有的
       return function(){
           if(_list.indexOf(num)){
               return false
           }else{
               _list.push(num)
               return true
           }
       }
   }
   var first = isFirst()
   first(10) // true
   first(10) // false
   first(20) // true
相關文章
相關標籤/搜索