05.作用域

一.作用域

1. 函数能封闭住定义域

一个变量如果定义在了一个function里面,那么这个变量就是一个局部变量,只在这个function里面有定义,出了这个function,就如同没有定义过一样

function fn(){
    var a = 3;//定义在函数里的变量,那么这个变量 就是局部变量,只有在函数里面有定义
console.log("我是函数里面的语句,所以我知道a值是'' + a ");
}
fn();
console.log("我是函数外面的语句,我认为a的值是'' + a");  //undefined
expng.png

a被var在了function里面,所以现在这个a变量只在函数内定义

JavaScript变量作用域非常的简单,没有块级作用域,管理住作用域的只有一个东西,函数

如果一个变量,没有定义在任何的function中,那么它将在全部程序范围内都有定义:就是你在JS的任何位置都能够使用它。

var a = 10;//定义在全局范围内的一个变量,全局变量,在程序任何一个区域都有定义
function fn(){
      console.log("我是函数里面的语句,我认识全局变量a ,它的值为'' + a");
}
fn();
console.log("函数外面的语句,我也认识a,它的值为'' +  a");
quan.png

总结:

  • 定义在function里面的变量,叫做局部变量,只在function里面有定义,出了function没有定义的
  • 定义在全局范围的 ,没写在任何function里面的,叫做全局变量,全局都认识

2.作用域链

当遇见一个变量时,JS引擎会从其所在的作用域依此向外层 查找,查找会在找到第一个匹配的标识符的时候停止

function outer(){
    var a = 3;      //a的作用域就是outer
    function inner(){
        var b = 5;      //b的作用域就是inner
        console.log(a); //能够正常输出3,a在本层没有定义,就是找上层
        console.log(b);   //能够正常输出5
    }
    inner();
}

outer();
console.log(a);     //报错,因为a的作用域outer

多层嵌套,如果有同名的变量,那么就会发生”遮蔽效应“

var a =2;//全局变量
function fn(){
  var a = 3;//就把外层的a给遮蔽了,这个函数内部看不见外层的a了,
  console.log(a);//输出3,变量在当前作用域寻找,找到a的定义为3
}
fn();
console.log(a);//输出为2, 变量在当前作用域寻找,找到a的定义值为2

作用域链:一个变量在使用的时候,就会在当前层寻找它是否被定义,如果找不到,就去找上一层function,知道找到全局变量,如果全局页面没有,就报错。

var a = 1;//全局变量
var b = 2; //全局变量
function outer(){
    var a = 3; //遮蔽了外层a,a局部变量
     function inner(){
      var b = 4;//遮蔽了外层的b,b局部变量
      console.log(a);//① 输出3,a现在在当前层找不到定义,所以就上一层寻找
      console.log(b); //②  输出4
      }
      inner();  //调用函数
      console.log(a);  //③ 输出3
      console.log(b);  //④ 输出2 b现在在当前层找不到定义就上一层寻找
}
outer();  //执行函数,控制权交给了outer
console.log(a); //⑤ 输出1
console.log(b); //⑥ 输出2

3. 不写var就自动成全局变量

// var a, 相当于在全局var了一个a
    function fn(){
    a  =  3; //这个a第一次赋值的时候,并没有var过
                // 所以就自动的在全局的范围帮你var了一次
}
fn();
console.log(a);

这是JS的一个机理,如果遇见了一个标识符,从来没有var过,并且还赋值了:

 num = 12;

那么就会自动帮你在全局范围内定义 var num;

4. 函数的参数,会默认定义为这个函数的局部变量

function fn(a,b,c,d){
          // var a, b, c, d; 相当于在函数内部var四个变量,是局部变量
}

a, b, c, d就是一个fn的局部变量,出了fn就没有定义

5. 全局变量的作用

5.1 通信,共同操作一个变量

两个函数同时操作同一个变量,一个增加,一个减少,函数和函数通信

var  num = 0;
function add(){
    num++;
  }
function remove(){
    num--;
}
5.2 累加,重复调用函数的时候,不会重置
var num = 0;
function baoshu(){
    num++;
    console.log(num);
}
baoshu(); //1
baoshu();//2
baoshu();//3

如果num定义在baoshu里面,每次执行就会把num重置为0,

function baoshu(){
    var num = 0;
    num++;
    console.log(num);
}
baoshu(); //1
baoshu();//1
baoshu();//1

6.函数的定义也有作用域

//这个函数返回a的平方加b的平方
function pingfanghe(a,b){
    return  pingfang(a) + pingfang(b);
    //返回m的平方
    function pingfang(m){
        return Math.pow(m,2)
    }
}

// 现在相求4的平方,想输出16
pingfang(4);    //报错,因为全局作用域下,没有一个函数叫做pingfang

机理:

function big{
    function small{
    
      }
    small();//可以运行
}
small(); //不能运行,因为小small函数定义在了big函数里面,离开big函数没有作用域

二.闭包

1. 闭包

function outer(){
    var a =33;
    function inner(){
        console.log(a);
      }
      return inner;
}
var inn = outer();
inn();  //弹出33

推导过程:
inner()这个函数不能在outer外面调用,因为outer外面没有inne的定义

function outer(){
      var a = 88;
      function inner(){
        console.log(a);
    }
}
//在全局调用inner 但是全局没有inner定义,所以会报错
inner();

但是我们现在就想在全局作用域下,运行outer内部的inner,此时我们必须想一些奇奇怪怪的方法。

有一个简单可行的办法,就是让outer自己return掉inner:

function outer(){
      var a = 3; 
      function inner(){
          console.log(a);
      }
      return inner;//outer返回了inner的引用
}

var inn = outer(): //inn就是inner函数了
inn(); //执行inn,全局作用下没有a的定义
//但是函数闭包,能够把定义函数的时候的作用域的时候一起记忆住
//能够输出33

这就说明了,inner函数能够持久保存自己定义是的所处环境,并且及时自己在其他的环境被调用的时候,依然可以访问自己定义时所处环境的值

一个函数可以把它自己内部的语句,和自己声明时所处的作用域一起封装乘了一个密闭的环境,我们称之为“闭包”(Closures)

每一个函数都是闭包,每个函数天生就能记忆自己定义时所处的作用域环境。但是,我们必须将这个函数挪到别的作用域,才能更好的观察闭包。这样才能实验它有没有把作用域给“记住”

2. 闭包的性质

每次重新引用函数的时候,闭包时全新的。

function outer(){
    var count = 0;
    function inner(){
        count++;
        console.log(count);
    }
  return inner;
}
var inn1 = outer();
var inn2 = outer();
inn1();//1
inn1();//1
inn1();//1
inn1();//1
inn2();//1
inn2();//2
inn1();//1

无论它在何处被调用,它总是能访问它定义时所处作用域中的全部变量

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容