作用域和闭包

本文详细介绍了JavaScript中的执行上下文概念,包括全局与函数上下文的区别、this的确认方式及其不同调用形式的影响、作用域与作用域链的工作原理,并通过实例展示了闭包的应用场景。

###1. 执行上下文

  • 范围:一段script 或者一个函数

  • 全局:变量定义,函数声明 (一段script)

  • 函数:变量定义,函数声明,this,arguments (函数)

      console.log(a) // undefined
      var a=100;
      
      fn('zs')//zs,name
      function fn(name){
           age =20;
           console.log(name,age)
           var age;
       }
    

###2. this

  • this在执行时确认,定义时无法确认

  • 作为构造函数执行

  • 作为对象属性执行

  • 作为普通函数执行

  • call,apply,bind

      function Foo(name){
          this.name=name;
      }
      var  f = new Foo('zs')
      var a={
          name:'A',
          fn:function(){
              console.log(this.name)
          }
      }
       a.fn()// this===a
       a.fn.call({name:"B"})// this==={name:"B}
       var fn1 = a.fn;
       fn1() //this===window
       function fn2(name) {
          alert(name)
          console.log(this)
       }
        fn2.call({x:100},'zs')  // name:zs   this:{x:100}   第一个参数为this,第二个参数为传入的参数
        // bind 函数表达式
      var fn3=function(name,age){
          alert(name);
          console.log(this); // this:{y:200}
      }.bind({y:200})
      fn3('zs',20)
    

###3.作用域

  • 没有块级作用域,只用函数和全局作用域

  • 一个函数的作用域是在函数定义的时候确定的,不是在执行的时候确定的

      // 无块级作用域
      if(true){
      	var name = "zs"
      }
      console.log(name)
      //函数和全局作用域
      var a = 100;
      function fn(){
          var a= 200;
          console.log('fn',a)
      }
      console.log('global',a) // 100
      fn() //  200
    

###4.作用域链

  • 自由变量

  • 作用域链,自由变量的查找

  • 闭包的两个场景

     var a =100;
     function fn(){
           var b=200;
           // 当前作用域没有定义的变量,即自由变量
           console.log(a)
           console.log(b)
       }
       fn()
    
       function F1(){
           var b=200;
           function F2(){
               var c=300;
               console.log(a)
               console.log(b)
               console.log(c)
           }
           F2()
       }
       F1()
    

###5.闭包

  • 封装变量,收敛权限

  • 函数作为返回值

  • 函数作为参数传递

      function F1() {
               var a =100;
               // 返回一个函数(函数作为返回值)
               return function(){
                   console.log(a) // 自由变量,父作用域中寻找
               }
       }
      var f1 = new F1();
       var a=200;
       f1()// 100
       // F1()(); // 100
    
       function F2(fn) {
           var a=200;
           fn()
       }
       F2(f1) // 100
    
  • 创建10个a标签,点击弹出对应的序号

       //错误写法
       var i, a
      for (i = 0; i < 10; i++) {
          a = document.createElement('a');
          a.innerHTML = i + '<br>'
          a.addEventListener('click', function (e) {
              e.preventDefault()
              alert(i) // 自由变量
          })
    
          document.documentElement.appendChild(a)
      }
      //正确写法
      var i
      for (i = 0; i < 10; i++) {
          (function (i) {
              // 传递i,作为函数内部变量
              a = document.createElement('a');
              a.innerHTML = i + '<br>'
              a.addEventListener('click', function (e) {
                  e.preventDefault()
                  alert(i) // 自由变量
              })
    
              document.documentElement.appendChild(a)
          })(i)
      }	
    
    
      // 判断是否第一次登陆
      function isFirstLoad(){
          var _list =[]
          return function (id){
              if(_list.indexOf(id)>=0){
                  return false;
              }else{
                  _list.push(id)
                  return true
              }
          }
      }
    
      //使用
      var firstLoad= isFirstLoad();
      firstLoad(10)//true
      firstLoad(10)//false
      firstLoad(20)//true
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值