JS函数的预处理

(一)函数声明、变量的定义

/*函数表达式*/
var fun1 = function(){
     //.....
}
/*函数声明*/
function fun2(){
    //......
}
/*变量声明*/
var a = 1;
/*不带var的变量声明*/
b = 2; //不带var的变量声明会作为全局变量

(二)预处理

当进入一个js环境时,并不是直接从上到下开始执行代码,而是会先扫描所有js,将var声明的变量通过函数声明方式声明的函数集合在一起组成一个词法环境(LexicalEnvironment,简称LE)。

预处理包括全局的预处理和函数的预处理。

全局预处理

总所周知执行js代码最先进入的是全局,所有会先创建全局执行环境,所有会先进行全局的预处理。

示例代码
console.log(a) //undefined
console.log(b) //报错
console.log(fun1)//函数的引用
console.log(fun2) //报错
var a = 1;
b = 2;
function fun1(){
  //......
}
fun1 = 4;
var fun2 = function(){
  //......
} 
console.log(a) // 1
console.log(b) // 2
console.log(fun1) // 4
console.log(fun2) // 函数的引用
说明

全局的预处理一开始创建的LE:

LE{
  a:undefined,
  fun1:函数的引用
}

我们可以通过预处理的LE得到以下结论:

  1. 可以综合前面提到的“var声明的变量通过函数声明方式声明的函数......”结合起来看,b和fun2是不符合条件的因此不会在预处理的过程中加入到LE中去。所以一开始运行的console代码中,b和fun2会报错
  2. 通过上面的LE也可以看出,预处理对于变量的处理,只是保存了变量,而没有保存变量的值。所以一开始运行的console代码a为undefined。
  3. 对于fun1,在代码中有两处声明,分别是变量和函数,遇到这种情况遵循函数大于变量的原则。

全局预处理完成以后再往下执行代码,通过一些赋值语句来改变原来LE中对应的值或者在LE中新增一些通过其他声明方式声明的变量或函数,因此在最后执行的console之前LE更改为:

LE{
  a:1,
  fun1:4,
  b:2,
  fun2:函数的引用
 }
函数预处理

函数的预处理和全局的预处理大致一致,区别在于函数有参数。

示例代码
function test(a,b){
   console.log(a);//4
   console.log(b);//函数的引用
   console.log(c);//报错
   console.log(d);//undefined
   var a = 1;
   function b(){
     //......
   }
   c = 2;
   var d = 3;
   console.log(a);//1
   console.log(b);//函数的引用
   console.log(c);//2
   console.log(d);//3
}
test(4,5);
说明

当函数运行到“test(4,5)”时进入到test函数,此时创建再增加一个新的执行环境,进行预处理得到LE:

LE{
  a:4,
  b:函数的引用,
  d:undefined,
  /*arguments表示参数的长度*/
  arguments:2
 }

我们可以通过预处理的LE得到以下结论:

  1. 函数的预处理LE中会多一个表示参数长度的arguments。
  2. 参数加入LE中,不仅仅是新增了一个参数,而且会对它进行赋值。这一点区别于函数体内普通的变量。
  3. 参数与函数体内的函数命名冲突时也是遵循上面提到的原则,函数优先。

函数执行到下一组console的时候,LE更改为:

LE{
  a:1,
  b:函数的引用,
  d:3,
  arguments:2,
  c:2
}

以上是预处理的内容,其实如果把全局的环境也看作是一个没有参数的函数,那么也就不需要特别区分了全局预处理和函数预处理了。函数在执行是还有其他一系列操作,欢迎查看指正另一篇博文《JS作用域链和函数执行》


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值