1.作用域
一段代码中所用到的名字并不总是有效和可用的,限定这个名字的可用性的代码范围就是这个名字的作用域。
- 好处:提高了程序逻辑的布局性,增强了程序的可靠性,减少了名字冲突
- js的作用域(es6之前):全局作用域、局部作用域(函数作用域)
- 全局:整个script标签或者是单独的js文件
- 局部:再函数内部,只在函数内部起作用
2.变量的作用域
2.1 根据作用域的不同我们变量分为全局变量和局部变量
-
全局变量:全局作用域下的变量
-
注意:如果在函数内部 没有声明直接赋值的变量也属于全局变量
-
局部变量:在局部作用域下的变量
-
注意:函数的形参也可以看作是局部变量
var num = 10; // num就是一个全局变量
console.log(num);
function fn() {
console.log(num); //全局变量
}
fn();
function fun(aru) {
var num1 = 10; // num1就是局部变量 只能在函数内部使用
num2 = 20; //num2 是全局变量
}
fun();
- 从执行效率看:全局变量只有浏览器关闭的时候才会销毁,比较占内存资源;局部变量当我们程序执行完毕就会销毁, 比较节约内存资源
2.2 js在es6的时候新增的块级作用域
// 块级作用域 {} if {} for {}
// java
// if(xx) {
// int num = 10;
// }
// 外面的是不能调用num的
3.作用域链
// 作用域链 : 内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 这种结构我们称为作用域链 也就是就近原则
var num = 10;
function fn() { // 外部函数
var num = 20;
function fun() { // 内部函数
console.log(num);
}
fun();
}
fn(); //20
4.预解析
// 1
console.log(num);//报错
// 2
console.log(num); // undefined
var num = 10;
// 相当于执行了以下代码
// var num;
// console.log(num);
// num = 10;
// 3
fn(); //可以运行 11
function fn() {
console.log(11);
}
// 4
fun(); // 报错
var fun = function() {
console.log(22);
}
- js引擎运行js 分为两步: 预解析 、代码执行
- 预解析: js引擎会把js 里面所有的 var 还有 function 提升到当前作用域的最前面
- 代码执行: 按照代码书写的顺序从上往下执行
5.变量预解析和函数预解析
- 预解析分为:变量预解析(变量提升)、和 函数预解析(函数提升)
- 变量提升 就是把所有的变量声明提升到当前的作用域最前面 不提升赋值操作
- 函数提升 就是把所有的函数声明提升到当前作用域的最前面 不调用函数
6.预解析案例
// 案例
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(); // 9 9 9
console.log(c); // 9
console.log(b); // 9
console.log(a); // 报错