JS学习之预解析(执行上下文)

预解析

在一段js代码拿过来真正一句一句运行之前,浏览器会做一些“准备工作”,就是执行上下文(预解析)
函数或者变量都会有提前解析的过程,JS会把函数或者变量提前解析一下,解析到它们对应的作用域最开始的地方
步骤:
1、先找var,function关键字以及参数
2、如果找到了var(声明的变量、参数)会给他赋一个undefined,如果找到了function,那会把整个函数都拿过来
3、把找到的东西放在对应作用域的最开始的位置
4、逐行执行代码

     /*
var c=undefined
function test(){
console.log(c);
c=20;
}
*/
1
var c=10; 2 function test(){ 3 console.log(c); 4 c=20; 5 } 6 test(); // 10 7 console.log(c); // 20 8 /* 9 原理: 10 1、找到了var c=undefined test(){} 整个代码块 11 2、逐行解读代码 c=10 函数test调用了 12 3、遇到一个新的代码块,找var,没有找到,逐行解读代码,console.log(c),往外找c 13 4、往下走c 被重新赋值 20 14 */
/*
var d=undefined
function test1(d){
console.log(d);
d=24;
}
*/
15 var d=12; 16 function test1(d){ 17 // var d=undefined;
console.log(d); // undefined 18 d=24; // 赋值的是test1作用域内的 d 19 } 20 test1(); 21 console.log(d); // 12 22 /* 23 1、找到var d=undefined 24 function test1(d){ 25 console.log(d); 26 d=24; 27 } 放在作用域最开始的地方 28 2、逐行解读代码,d被赋值12,函数test1()调用, 29 有形参d,赋值var d=undefined 放在函数test1的最上面, 30 d 被赋值24,注意是test1函数里的作用域内的d,并不是外面的d,函数调用完就被释放 31 */ 32 /*
var e=13;
function test2(e){
console.log(e);
e=54;
}
*/ 33 var e=13; 34 function test2(e){ 35 // var e=undefined;
console.log(e); // 13 36 e=54; // 更改的 37 } 38 test2(e); 39 console.log(e); // 13 40 /* 41 1、找var 跟函数 42 var e=undefined 43 function test2(e){ 44 console.log(e); 45 e=54; 46 } 放在作用域的最前面 47 2、逐行解读代码 e被赋值为 13 48 函数调用,逐行走函数 test2内代码 49 函数test2代码块内预解析,有形参e, 50 e=undefined 放在函数最开始的位置 51 函数调用的时候有实参e,就是13 被传进来 52 所以console.log(e)为13 ,之后e 又被赋值为54,但注意是test2作用域内的e 53 */

函数预解析

1、函数声明
     可以被预解析,可以先调用再声明
2、函数表达式
     函数表达式不会被预解析,只能先声明再调用,不能先调用再声明(不然报错)

 1      test();  // 不会报错
 2      function test(){
 3            console.log('test');
 4     }
 5      /*
 6     函数test()被预解析放在了作用域的最前面,所以可以调用
 7      */
 8       test1(); // 报错   test1 为undefined, undefined() 肯定报错
 9       var test1=function(){
10               console.log("test1");
11       }  
12       // 找到了var test1放在了作用域最前面并被赋值 undefined ,但函数表达式的函数不会被预解析
13      // 逐行解读代码 undefined();肯定会报错

我们总结一下,在“准备工作”中完成了哪些工作:

  • 变量、函数表达式——变量声明,默认赋值为undefined;
  • this——赋值;
  • 函数声明——赋值;

这三种数据的准备情况我们称之为“执行上下文”或者“执行上下文环境”。

原文地址:https://www.cnblogs.com/xubj/p/9871023.html