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
相关文章
相关标签/搜索