05-js讲义(闭包、作用域)

闭包

变量作用域

  • 变量作用域的概念:就是一个变量可以使用的范围
  • JS中首先有一个最外层的作用域:称之为全局作用域
  • JS中还可以通过函数创建出一个独立的作用域,其中函数可以嵌套,所以作用域也可以嵌套
var age=18;     //age是在全局作用域中声明的变量:全局变量

function f1(){
    console.log(name);      //可以访问到name变量
    var name="周董" //name是f1函数内部声明的变量,所以name变量的作用域就是在f1函数内部

    console.log(name);      //可以访问到name变量

    console.log(age);       //age是全局作用域中声明的,所以age也可以访问
}
    //多级作用域
    //-->1级作用域
    var gender="男";
    function fn(){
        //gender:可以访问
        //age:  可以访问,值为undefined
        //height: 不能访问

        //-->2级作用域
        return function(){
            //gender:   通过一级一级作用域的查找,发现gender是全局作用域中声明的变量
            //age:      可以访问,值为undefined
            //height:  可以访问,值为undefined
            console.log(gender);

            //-->3级作用域
            var height=180;
        }
        var age=5;
    }
  • 注意:变量的声明和赋值是在两个不同时期的
    function fn(){
        console.log(age);   //undeinfed
        var age=18;
        console.log(age);   //18
    }
- fn函数执行的时候,首先找到函数内部所有的变量、函数声明,把他们放在作用域中,给变量一个初始值:undefined    -->变量可以访问
- 逐条执行代码,在执行代码的过程中,如果有赋值语句,对变量进行赋值

作用域链

  • 由于作用域是相对于变量而言的,而如果存在多级作用域,这个变量又来自于哪里?我们把这个变量的查找过程称之为变量的作用域链
  • 作用域链的意义:查找变量(确定变量来自于哪里,变量是否可以访问)
  • 简单来说,作用域链可以用以下几句话来概括:(或者说:确定一个变量来自于哪个作用域)
    • 查看当前作用域,如果当前作用域声明了这个变量,就确定结果
      • 查找当前作用域的上级作用域,也就是当前函数的上级函数,看看上级函数中有没有声明
        • 再查找上级函数的上级函数,直到全局作用域为止
          • 如果全局作用域中也没有,我们就认为这个变量未声明(xxx is not defined)
function fn(callback){
    var age=18;
    callback()
}
    
fn(function(){
    console.log(age); //undefined
    var age = 15;
    //分析:age变量:
    //1、查找当前作用域:并没有
    //2、查找上一级作用域:全局作用域
    //-->难点:看上一级作用域,不是看函数在哪里调用,而是看函数在哪里编写
    //-->因为这种特别,我们通常会把作用域说成是:词法作用域
})

闭包概念

能够读取其他函数内部变量的函数。
或简单理解为定义在一个函数内部的函数,内部函数持有外部函数内变量的引用。

闭包问题的产生原因

  • 函数执行完毕后,作用域中保留了最新的a变量的值

闭包的应用场景

  • 模块化
  • 防止变量被破坏

函数的4种调用方式

  • 1、函数调用
  • 2、方法调用
  • 3、new调用(构造函数)
  • 4、上下文方式(call、apply、bind)

猜你喜欢

转载自www.cnblogs.com/vicky123/p/12911228.html