作用域链和域解析
1. 作用域链 : 内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 这种结构我们称为作用域链 ( 就近原则)
var num = 10; function fn() { // 外部函数 var num = 20; function fun() { // 内部函数 console.log(num); } fun(); } fn();
例子:
<script> // 案例1 : 结果是0 function f1() { var num = 123; function f2() { var num = 0; console.log(num); // 站在目标出发,一层一层的往外查找 } f2(); } var num = 456; f1(); // 案例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的值 4 console.log(b); //b的值 22 } } } fn1(); </script>
2.预解析
1. 我们js引擎运行js 分为两步: 预解析 代码执行
(1). 预解析 js引擎会把js 里面所有的 var 还有 function 提升到当前作用域的最前面
(2). 代码执行 按照代码书写的顺序从上往下执行
2. 预解析分为 变量预解析(变量提升) 和 函数预解析(函数提升)
(1) 变量提升 就是把所有的变量声明提升到当前的作用域最前面 不提升赋值操作
(2) 函数提升 就是把所有的函数声明提升到当前作用域的最前面 不调用函数
举例:
// 情况一 console.log(num); // undefined 坑 1 var num = 10; // 相当于执行了以下代码 // var num; // console.log(num); // num = 10; // 情况二 fun(); // 报错 坑2 var fun = function() { console.log(22); } // 函数表达式 调用必须写在函数表达式的下面 // 相当于执行了以下代码 // var fun; // fun(); // fun = function() { // console.log(22); // }
例子:
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);结果为undefined console.log(b);结果为9 a = '123'; } a = 18; f1();
面试题:
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);9 console.log(b);9 console.log(c);9 } f1(); console.log(c);9 console.log(b);9 console.log(a);结果报错