js的作用域和变量使用规则
作用域
一、在js中,变量的定义并不是以代码块作为作用域的,而是以函数作为作用域。也就是说,如果变量是在某个函数中定义的,那么,它在函数以外的地方是不可见的。但是,如果该变量是定义在if或者for这样的代码块中,它在代码块之外是可见的。
二、在js中,术语“全局变量”指的是定义在所有函数之外的变量(也就是定义在全局代码中的变量),与之相对的是“局部变量”,所指的是在某个函数中定义的变量。其中,函数内的代码可以像访问自己的局部变量那样访问全局变量,反之则不行。
全局作用域
- 全局作用域是最大的作用域
- 在全局作用域中定义的变量可以在任何地方使用
- 页面打开的时候,浏览器就会自动给我们生成一个全局作用域window
- 这个作用域会一直存在,直到关闭页面就销毁了
- 在函数内部不使用var定义的变量是全局作用域
- 如果一个变量的作用域是全局作用域,这个变量我们叫全局变量
局部作用域
- 局部作用域就是在全局的作用域下面又开辟出来的一个相对小一些的作用域
- 在局部作用域中定义的变量只能作用在这个局部作用内部使用
- 在js中只有函数能生成一个局部作用域,别的都不行
- 每一个函数,都是一个局部作用域
- 如果一个变量的作用域是局部作用域,这个变量我们叫做局部变量
作用域案例
一、Javascript的变量的scope是根据方法块来划分的(也就是说以function的一对大括号{ }来划分)。切记,是function块,而for、while、if块并不是作用域的划分标准,可以看看以下几个例子:
function test2(){
alert ("before for scope:"+i);
// i未赋值(并不是未声明!使用未声明的变量或函数全抛出致命错误而中断脚本执行)
// 此时i的值是underfined
for(var i=0;i<3;i++){
alert("in for scope:"+i); // i的值是 0、1、2, 当i为3时跳出循环
}
alert("after for scope:"+i); // i的值是3,注意,此时已经在for scope以外,但i的值仍然保留为3
while(true){
var j = 1;
break;
}
alert(j); // j的值是1,注意,此时已经在while scope以外,但j的值仍然保留为1
if(true){
var k = 1;
}
alert(k); //k的值是1,注意,此时已经在if scope以外,但k的值仍然保留为1
}
test2();
//若在此时(function scope之外)再输出只存在于test2 这个function scope里的 i、j、k变量会发生神马效果呢?
alert(i); //error! 没错,是error,原因是变量i未声明(并不是未赋值,区分test2函数的第一行输出),导致脚本错误,程序到此结束!
alert("这行打印还会输出吗?"); //未执行
alert(j); //未执行
alert(k); //未执行
二、Javascript在执行前会对整个脚本文件的声明部分做完整分析(包括局部变量),从而确定实变量的作用域。怎么理解呢?看下面一个例子:
var a =1;
function test(){
alert(a);
//a为undefined! 这个a并不是全局变量,这是因为在function scope里已经声明了(函数体倒数第4行)一个重名的局部变量,
//所以全局变量a被覆盖了,这说明了Javascript在执行前会对整个脚本文件的定义部分做完整分析,所以在函数test()执行前,
//函数体中的变量a就被指向内部的局部变量.而不是指向外部的全局变量. 但这时a只有声明,还没赋值,所以输出undefined。
a=4;
alert(a); //a为4,没悬念了吧? 这里的a还是局部变量哦!
var a; //局部变量a在这行声明
alert(a); //a还是为4,这是因为之前已把4赋给a了
}
test();
alert(a); //a为1,这里并不在function scope内,a的值为全局变量的值
三、当全局变量跟局部变量重名时,局部变量的scope会覆盖掉全局变量的scope,当离开局部变量的scope后,又重回到全局变量的scope,而当全局变量遇上局部变量时,怎样使用全局变量呢?用window.globalVariableName。
var a =1;
function test(){
alert(window.a); //a为1,这里的a是全局变量哦!
var a=2; //局部变量a在这行定义
alert(a); //a为2,这里的a是局部变量哦!
}
test();
alert(a); //a为1,这里并不在function scope内,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
本文地址:https://blog.csdn.net/weixin_45528272/article/details/107279842
下一篇: MD5j技术加密