作用域、作用域链

作用域

在 JavaScript 中, 作用域为可访问变量,对象,函数的集合。

作用域下浏览器的操作

  1. 预解析(找var function 参数)
  2. 逐行解读代码
alert(a);  //function a(){alert(4)}
var a = 1;
alert(a); //1
function a(){alert(2);}
alert(a); //1
var a = 3; 
function a(){alert(4);}
alert(a); //3
  • 预解析
    ①var a = undefined;
    ②a = function a(){alert(2);}==> a = function a(){alert(2);}
    ③a = function a(){alert(4);}==>a = function a(){alert(4);}
  • 逐行解读代码
    ①alert(a); 此时预解析里a的值是function a(){alert(4);},因此弹出function a(){alert(4);}
    ②a = 1; a的值变为1;
    ③alert(a); a的值是1
    ④function a(){alert(2);} 不变
    ⑤alert(a); a的值是1
    ⑥var a = 3; a的值变为3
    ⑦function a(){alert(4);} 不变
    ⑧alert(a); a的值为3

~ 直接写{}没有用(除let)
~ for循环声明的变量是全局变量,意味着声明的这个变量后面使用的时候就是最后一次循环的值。
~ 在函数里面{}是有用的,{}里面的变量外面不能访问到,但是可以访问到外面的全局变量

作用域链

子级作用域返回到父级作用域的过程叫做作用域链

var a = 1;
function fn1(){
    alert(a);  //undefined
    var a = 2;
}
fn1();
alert(a);  //1
  • 每执行一个函数就到了一个新的作用域下
  • 函数:由里到外找
  • 局部的赋值可以改变外部的值
var a = 1;
function fn1(){
  alert(a); //1 ,内部找不到定义到父级找
  a = 2; //改变外部变量a的值
}
fn1();
alert(a); //2
  • 定义一个参数未调用的情况
var a = 1;
function fn1(a){  
    alert(a); //预解析的时候有一个参数a是未定义,弹出undefined
    a = 2; //本函数内a的值为2
}
fn1();
alert(a);  //外部a没有变化
  • 调用参数的情况
var a = 1;
function fn1(a){   //这里相当于fn1(var a = 1),1来自外部变量
  console.log(a); //1,这个a是局部的
  a = 2; //改变内部变量a
}
fn1(a);
console.log(a); //1 ,这个a是全局的

你可能感兴趣的:(作用域、作用域链)