概述:
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围
就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突
变量的作用域
变量作用域的分类
在JS中,根据作用域的不同,变量可以分为两种:
-
全局变量
在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)
-
全局变量在代码的任何位置都可以使用
-
在全局作用域下var 声明的变量也是全局变量(不建议使用)
-
-
局部变量
在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)
-
局部变量只能在该函数内部使用
-
在函数内部var声明的变量是局部变量
-
函数的形参也是局部变量
-
全局变量和局部变量的区别
-
全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
-
局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间
JS中没有块级作用域
作用域链
-
只要是代码,就至少有一个作用域
-
写在函数内部的就是局部作用域
-
如果函数中还有函数,那么在这个作用域中又可以诞生一个作用域
-
根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定那些数据能被内部函数访问,就称为作作用域链
案例1:结果是几?
与上一层的num 是同级
案例2:结果是几?
var a = 1;
function fn1() {
var a = 2;
var b = '22';
fn2();
function fn2() {
var a = 3;
fn3();
function fn3() {
var a = 4;
console.log(a); //a的值?
console.log(b); //b的值?
}
}
}
fn1();
先观察是否都调用
结果:a=4 b=‘22’
JS预解析
JS代码是由浏览器中JS解析器来执行的,JS解析器在运行JS代码的时候分为两步,预解析和代码执行
预解析案例
案例1:结果是几?
// 案例1
// var num = 10;
// fun();
// function fun() {
// console.log(num);
// var num = 20;
// }
// 相当于执行了以下操作
// var num;
// function fun() {
// var num;
// console.log(num);
// num = 20;
// }
// num = 10;
// fun();
// 案例2
// var num = 10;
// function fn() {
// console.log(num);
// var num = 20;
// console.log(num);
// }
// fn();
// 相当于执行以下代码
// var num;
// function fn() {
// var num;
// console.log(num);
// num = 20;
// console.log(num);
// }
// num = 10;
// fn();
// 案例3
// var a = 18;
// f1();
// function f1 () {
// var b = 9;
// console.log(a);
// console.log(b);
// var a = '123';
// }
// // 相当于以下代码
// var a;
// function f1 () {
// var b;
// var a;
// b = 9;
// console.log(a);
// console.log(b);
// a = '123';
// }
// a = 18;
// f1();
// 案例4:
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;
// a = b = c = 9;
// // 相当于var a = 9; b = 9; c = 9; b 和 c直接赋值 没有var声明 当全局变量看
// // 集体声明 var a = 9, b = 9,c = 9;
// console.log(a);
// console.log(b);
// console.log(c);
// }
// f1();
// console.log(c);
// console.log(b);
// console.log(a);