一、在js中,变量的定义并不是以代码块作为作用域的,而是以函数作为作用域。也就是说,如果变量是在某个函数中定义的,那么,它在函数以外的地方是不可见的。但是,如果该变量是定义在if或者for这样的代码块中,它在代码块之外是可见的。
二、在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的值为全局变量的值
一、有了作用域以后,变量就有了使用范围,也就有了使用规则
二、变量的使用规则分两种:访问规则和赋值规则
当我想读取一个变量的值的时候,我们管这个行为叫访问
获取变量值的规则:
变量的访问规则,也叫作作用域的查找机制
作用域的查找机制:只能是向上找,不能是向下找
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里面的代码
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
如对本文有疑问, 点击进行留言回复!!
荐 超强的入门文章 !!! JavaScript 速成计划第二篇(杂项详解:JS操作HTML 与 CSS、异常、事件)!
教你搭建 nodejs+mongoose+Graphql+Vue+Typescript 框架(上)
【Nginx】如何为已安装的Nginx动态添加模块?看完我懂了!!
网友评论