作用域
作用域:
就是代码名字在某个范围内起的作用和效果,目的是为了提高程序的可靠性,减少命名冲突
全局作用域:整个script标签或者一个单独的Js文件
局部作用域:在函数内部就是局部作用域
变量的作用域:
全局变量:在全局作用域声明的变量是全局变量,window的属性是全局变量,在函数内部没有声明直接赋值的变量也属于全局变量
局部变量:其他的都是局部变量,函数的形参也可以看作局部变量
区别:
全局变量只有浏览器关闭的时候才会销毁,比较占内存,局部变量当程序执行完毕就会销毁
作用域链:
内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值,这种结构就称为作用域链
作用域规则:就近原则
var num = 10;
function fn(){ // 外部函数
var num = 20;
function fun(){ // 内部函数
console.log(num)
}
fun();
}
fn(); // 20
JS预解析过程
-
预解析
-
逐行执行代码
var name = "xm";
var age = 18;
function fn(argument) {
console.log(name); //输出未定义:undefined
var name = "xh";
var age = 12;
}
fn();
解析:
全局作用域,局部作用域,都是通过以下两个步骤进行预解析的。
1,先读取有var 的变量(没有使用var的变量是不会被预解析的),给赋值为:undefined。如果两个变量重名,并不影响预解析的过程,就写一个变量就行,因为都将变量赋值为undefined(在逐行读取时,只是不同的赋值而已。),如果有函数名和变量重名,那就直接去掉变量,不进行解析。如果函数中存在参数,那么参数也一样使用var进行解析。如:var argument = undefined;
2,再读取function后面的函数---fn,如果有多个函数名重复,那么取最后面一个函数进行声明。
上面实例有两个作用域,一个是window变量对象的全局作用域,一个是fn变量对象的局部作用域。
预解析过程如下:
1,window:
var name = undefined;
var age = undefined;
function fn(argument){
console.log(name);
var name = "xh";
var age = 12;
}
2,fn:
var name = undefined;
var age = undefined;
var argument = undefined;
预解析就完成了。然后就是逐行解读代码。
通过逐行解读代码进行赋值,改变变量属性值。如果遇到函数,那么就直接跳过,因为预解析时已经声明过。
所以,上面实例:console.log(name); 输出为: undefined。