美文网首页
第三章 js基础知识 中 作用域、闭包

第三章 js基础知识 中 作用域、闭包

作者: qqqc | 来源:发表于2018-06-07 14:24 被阅读0次

    3-1 作用域和闭包-执行上下文

    问题

    • 说一下对变量提升的理解
    • 说明 this 几种不同的使用场景
      作为构造函数执行
      作为对象属性执行
      作为普通函数执行
      call apply bind
    • 创建 10 个<a>标签,点击的时候弹出来对应的序号
    //错误方式
    var i a
    for(i=0; i<10; i++){
            a = docuemnt.creatElement('a')
            a.innerHTML = i + '<br>'
            a.addEventListener('click', function(e){
                e.preventDefault()
                alert(i)   // i为自由变量,要去夫级获取
          })
          document.body.appendChild(a)
    }
    // 自执行函数,就是不用调用,只要定义完成,立即执行的函数
    var i
    for(i=0; i<10; i++){
        (function (i){
            var a = docuemnt.creatElement('a')
            a.innerHTML = i + '<br>'
            a.addEventListener('click', function(e){
                e.preventDefault()
                alert(i)   // i为自由变量,要去夫级获取
          })
          document.body.appendChild(a)
      })
    }
    
    • 如何理解作用域
      自由变量
      作用域链,即自由变量的查找
      闭包的两个场景
    • 实际开发中闭包的应用
    // 闭包实际应用中主要用于封装变量,收敛权限
    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
    

    知识点

    • 执行上下文
    console.log(a)  // undefined
    var a =100
    
    fn('zhangsan')  // 'zhangsan' 20
    function fn(name){
      age = 20
      console.log(name, age)
      var age
    }
    
    // 范围: 一段<script>或者一个函数
    // 全局: 变量定义、函数声明
    // 函数: 变量定义、函数声明、this、arguments
    
    注意函数声明和函数表达式的区别
    
    
    ·一段代码块对应一个执行上下文,被封装成函数的代码被视作一段代码块,或者“全局作用域”也被视作一段代码块。
    当程序运行,进入到某段代码块时,一个新的执行上下文被创建,并被放入一个 stack 中。当程序运行到这段代码块结尾后,对应的执行上下文被弹出 stack。
    当程序在某段代码块中运行到某个点需要转到了另一个代码块时(调用了另一个函数),那么当前的可执行上下文的状态会被置为挂起,然后生成一个新的可执行上下文放入 stack 的顶部。
    stack 最顶部的可执行上下文被称为 running execution context。当顶部的可执行上下文被弹出后,上一个挂起的可执行上下文继续执行。
    
    // 全局
    console.log(a)
    var a = 100
    
    fn('zhangsan')
    
    // 函数声明
    function fn(name){
        // 函数表达式
        console.log(this)
        console.log(arguments)
    
        age = 20
        console.log(name, age)
        var age 
        
        bar(100)
        function bar(num) {
          console.log(num)
      }
    }
    
    
    函数声明与函数表达式的区别:例:
    //执行函数f1
    f1();
    //声明函数f1
    function f1(){}
    //函数表达式
    f2
    var f2 = function(){}
    这种情况会出现:f1函数正常执行,f2报未定义。
    这是因为执行上下文会将变量定义以及函数定义提到前面去,所以尽管f1()在前,而f1声明在后,函数调用仍然正常。而f2在执行上下文中将var f2提到前面,赋值在后,导致f2()运行报错。
    
    • this
      • this要在执行时才能确定值,定义时无法确认
    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
    
    1.作为构造函数执行
    2.作为对象属性执行
    3.作为普通函数执行
    4. call apply bind
    
    function Foo(name){
      this.name = name
    }
    var f = new Foo('zhangsan')
    
    var obj = {
      name: 'a',
    printName: function(){
        console.log(this.name)
      }
    }
    obk.printName()
    
    function fn() {
      console.log(this)
    }
    fn()
    
    //call apply bind
    function fn1(name) {
      alert(name)
      console.log(this)
    }
    fn1.call({x:100}, 'zhangsan')
    
    • 作用域
    //无快级作用域
    if(true) {
        var name = 'zhangsan'
    }
    console.log(name)
    
    // 函数和全局作用域
    var a = 100
    function fn() {
        var  a = 200
        console.log('fn', a)
    }
    console.log('global', a)
    fn()
    
    • 作用域链
    var a = 100
    function fn(){
        var b =200 
        //当前作用域没有定义的变量,即自由变量
        console.log(a)
        console.log(b)
    }
    fn()
    
    全局作用域:在全局范围内,定义的内容可以被任何获取或修改
    函数作用域:在函数范围内,函数范围内可获取修改,函数外获取不到
    作用域链:当前作用域没有的变量是自由变量,当要执行这个变量时,会先从自身查找,如果没有,会从定义时的父作用域查找,这样一层一层往上查找形成了一条作用域链
    
    • 闭包
    function F1(){
        var a = 100
    
        // 返回一个函数(函数作为返回值)
        return function() {
            console.log(a)
        }
    }
    // f1 得到一个函数
    var f1 = F1()
    var a = 200
    f1()
    
    // 函数作为返回值
    // 函数作为参数传递
    

    相关文章

      网友评论

          本文标题:第三章 js基础知识 中 作用域、闭包

          本文链接:https://www.haomeiwen.com/subject/sishjftx.html