现在的位置: 首页 > 综合 > 正文

wed前端开发JS预编译及作用域链

2019年11月12日 综合 ⁄ 共 1320字 ⁄ 字号 评论关闭

  所谓预编译就是将变量声明提前,函数声明提前

  其中变量声明的优先级与函数声明的优先级需要弄清楚,大多数认为函数声明的优先级大于变量声明的优先级

  从浏览器的预解析说起:

  搜寻关键字(即var function)

  执行预解析

  a:先使var关键字声明的标识符有定义

  (标识符有定义后就不会报错,但未赋值)

  b:标识符中保存函数的引用

  从小案例开始

  为什么第一个控制台输出会是函数体?它没有被定义,应该会报错!

  为什么第三个控制台输出会是10?它前一行的函数没有用吗?

  首先,在js中所有的函数声明和变量声明都会提前,如果变量和函数在全局作用域中,js则会将其声明放在全局作用域的顶端,若是局部作用域中的变量,会将其声明放在局部作用域的顶端。

  其次,若变量与函数名同名,需要注意的是函数声明的优先级大于变量声明的优先级,因此会将变量中的undefined替换。

  最后,执行相应赋值等操作。

  预编译的具体步骤

  从小案例可以看出JS加载时会通篇扫描,将含有var和function关键字的声明,提到最前面,并将var声明的变量初始化为undefined,function则出示化为函数值

  从而依次执行

  在复杂的函数中,其预编译具体是怎么实现的呢(函数的预编译发生在函数执行的前一刻)

  函数执行时会创建一个(将所有的变量声明提前)

  AO(Activation Object 即活跃对象){

  a:undefined

  b:undefined

  c:undefined

  d:undefined

  }

  –>(将函数中的实参与形参统一)

  AO{

  a:3

  b:undefined

  c:undefined

  d:undefined

  }

  –>AO(将函数声明提升){

  a: function a(){}

  b:undefined

  c:undefined

  d:undefined

  }

  –>(预编译结束,函数执行,从上到下依次执行,若遇到错误,立即停止,之后的代码,便不在执行)

  AO{

  a: 10

  b:undefined

  c:20 -->tips:if(){}不管能否执行,其中声明的变量或者函数都会提前

  d:function d(){}

  }

  若在全局作用域中,预编译是怎么执行呢

  在上一个例子中,

  首先创建 GO(global object)函数作用域{

  test:function test(){…}

  }

  其次创建函数test 的AO(其分析与函数预编译一样)

  值得注意的是AO 中声明的变量是局部变量,在函数外部不能使用

  作用域链

  所谓作用域链,就是当声明一个函数时,局部作用域一级一级包裹起来,就是作用域链

  即:执行函数时,需要某个变量,自身局部作用域中没有,向上一级寻找,直到找到为止

  当执行show时,创建函数show的执行环境(AO),并将其放置与链表开头,其次时test的执行环境,最后是window,即 show AO–>test AO -->window GO

  在函数show中需要在控制台输出a,而自身本没有,因此需要向上一级寻找,找到了,a =3,找到之后就不在寻找,输出结果。

抱歉!评论已关闭.