js的作用域和变量使用规则

作用域

一、在js中,变量的定义并不是以代码块作为作用域的,而是以函数作为作用域。也就是说,如果变量是在某个函数中定义的,那么,它在函数以外的地方是不可见的。但是,如果该变量是定义在if或者for这样的代码块中,它在代码块之外是可见的。

二、在js中,术语“全局变量”指的是定义在所有函数之外的变量(也就是定义在全局代码中的变量),与之相对的是“局部变量”,所指的是在某个函数中定义的变量。其中,函数内的代码可以像访问自己的局部变量那样访问全局变量,反之则不行。

全局作用域

  • 全局作用域是最大的作用域
  • 在全局作用域中定义的变量可以在任何地方使用
  • 页面打开的时候,浏览器就会自动给我们生成一个全局作用域window
  • 这个作用域会一直存在,直到关闭页面就销毁了
  • 在函数内部不使用var定义的变量是全局作用域
  • 如果一个变量的作用域是全局作用域,这个变量我们叫全局变量

局部作用域

  • 局部作用域就是在全局的作用域下面又开辟出来的一个相对小一些的作用域
  • 在局部作用域中定义的变量只能作用在这个局部作用内部使用
  • 在js中只有函数能生成一个局部作用域,别的都不行
  • 每一个函数,都是一个局部作用域
  • 如果一个变量的作用域是局部作用域,这个变量我们叫做局部变量

作用域案例

案例1

f1();
console.log(c); 
console.log(b); 
console.log(a); 
function f1() {
    var a = b = c = 9;
    console.log(a); 
    console.log(b); 
    console.log(c); 
}

//分析:
    //第一个阶段是预解析:
    function f1() {
        var a = b = c = 9;
        console.log(a); 
        console.log(b); 
        console.log(c); 
    }

    //第二个阶段是代码执行:
    f1();
    //通过f1()执行函数,此处函数里面的代码才开始执行
    //这句代码可以写成:
    var a = b = c = 9;
    c = 9; b=c; var a = b;
    //c没有使用var定义,所以他是一个全局变量,b也没有使用var定义,所以他也是一个全局变量,
    //a使用了var定义,并且在函数里面,所以他是一个局部作用域
    //此时到了函数的外面,那么函数里面定义的局部变量就无法使用了
    console.log(c); 
    console.log(b); 
    console.log(a); 

案例2

f1();
console.log(c); 
console.log(b); 
console.log(a); 
function f1() {
    console.log(a); 
    console.log(b); 
    console.log(c); 
    var a = b = c = 9;
}

//分析:
    //第一个阶段是预解析:
    function f1() {
        var a;
        console.log(a); // undefined
        console.log(b); // 报错
        console.log(c); 
        a = b = c = 9;
    }

    //第二个阶段是代码执行:
    f1();
    //通过f1()执行函数,此处函数里面的代码才开始执行
    //由于var a被提前到函数内头部预解析,所以
    console.log(a); // undefined
    //当程序执行到console.log(b)时,由于b没有被定义,所以
    console.log(b); // 报错
    //程序报错后,后面得代码都不执行了

案例3

f1();
console.log(c); 
console.log(b); 
console.log(a); 
function f1() {
    var a=9,b=9,c=9;//逗号表示共享var这个关键字
    console.log(a);
    console.log(b);
    console.log(c);
}

//分析:
    //第一个阶段是预解析:
    function f1() {
        var a=9,b=9,c=9;
        console.log(a);//9
        console.log(b);//9
        console.log(c);//9
    }
    //第二个阶段执行代码:
    f1();
    //执行f1里面的代码
    //逗号表示共享var这个关键字
    //var a=9,b=9,c = 9; 就等价于 var a=9;var b=9;var c=9;那么a,b,c都是函数f1里面的局部变量
    //函数f1,执行完成以后,由于a,b,c是局部变量,在函数外面无法使用
    console.log(c); // 报错
    console.log(b); 
    console.log(a); 

变量使用规则

一、有了作用域以后,变量就有了使用范围,也就有了使用规则
二、变量的使用规则分两种:访问规则和赋值规则

访问规则

  • 当我想读取一个变量的值的时候,我们管这个行为叫访问

  • 获取变量值的规则:

    • 首先:在自己的作用域内部找,如果有,直接拿来使用
    • 如果没有,就去上一级作用域找,如果有,就拿来使用
    • 如果没有,就去上一级作用域找,如果有,就拿来使用
    • 如果到全局作用域都没有找到这个变量,那么就会报错(改变量 is not defined)
  • 变量的访问规则,也叫作作用域的查找机制

  • 作用域的查找机制:只能是向上找,不能是向下找

案例1

var num1 = 100;//全局作用域
function fn(){
    var num2=200;//fn的局部作用域,fn里面的局部变量
    function fn2(){
        var num3=300;//fn2的局部作用域,fn2里面的局部变量
        console.log(num1);//现在fn2里面,没有找到num1,继续去fn里面找,没有找到,继续去全局作用域找,找到了num1=100
        console.log(num2);//现在fn2里面,没有找到num1,继续去fn里面找,找到了num2=200
        console.log(num3);//现在fn2里面,找到了num3=300
        console.log(cc);//报错:cc is not defined
    }
    fn2();
}
fn();//执行fn里面的代码

案例2

function fn1(){
    var num =100;
}
fn1();
//num是函数fn1里面定义的,是fn1里面的局部作用域,只能在fn1里面使用,在函数外面无法使用
console.log(num);//报错:num is not defined

赋值规则

  • 当你想给一个变量赋值的时候,那么就先要找到这个变量,再给他赋值

  • 变量的赋值规则

    • 现在自己作用域内部查找,有就直接赋值

    • 没有就去上一级作用域内部查找,有就直接赋值

    • 没有就再去上一级作用域内部查找,有就直接赋值

    • 如果一直找到全局作用域都没有,那么就把这个变量定义为全局变量,再给他赋值

案例

function fn() {
  num = 100;
}
fn();

// fn 调用以后,要给 num 赋值
// 查看自己的作用域内部没有 num 变量
// 就会向上一级查找
// 上一级就是全局作用域,发现依旧没有
// 那么就会把 num 定义为全局的变量,并为其赋值
// 所以 fn() 以后,全局就有了一个变量叫做 num 并且值是 100
console.log(num); // 100
暂无评论

发送评论 编辑评论


				
上一篇
下一篇