码迷,mamicode.com
首页 > 其他好文 > 详细

变量提升和执行环境对象

时间:2016-08-20 17:55:59      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:

相关知识点:《单页Web应用》28页,高程111页以及underscore源码

  高程111页讲过函数声明和函数表达式的唯一区别:解析器会率先读取函数声明,并使其在执行任何代码前可用;至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。看下面两个例子:

alert(sum(10,10));    //20
    
function sum(num1, num2){
    return num1 + num2;
}     
 alert(sum(10,10));    //causes an error
    
 var sum = function(num1, num2){
       return num1 + num2;
 }; 

 

  然后我在看underscore源码的时候遇到了困惑的地方,提炼后的源码如下:

(function() {
    var root = this;
    var _ = function(obj) {
        return new wrapper(obj);
    };
    root[‘_‘] = _;
    .....
    var wrapper = function(obj) {
        this._wrapped = obj;
    };

}).call(this);

  困惑点:函数_先定义的,函数wrapper后定义的,那函数_执行的时候,岂不是在返回wrapper实例时,因为无法获得wrapper函数内容报错了。困惑了我好长时间。

  现在疑惑解决了,其实本身不是应该困惑的东西。咱们假设是按照常规的<script>方式引入underscore.js脚步,我们自己写的js代码肯定是放在了underscore.js的后面,所以当浏览器读到我们自己写的代码的时候,underscore的所有代码已经执行了一遍。执行的具体细节,见下面。

  单页Web应用也有相关的知识点:JS引擎在进入作用域时,会对代码分两轮处理。第一轮,初始化变量;第二轮,执行代码。在第一轮,JS引擎分析代码,并做了以下3件事情:

  (1)声明并初始化函数参数。

  (2)声明局部变量,包括将匿名函数赋值给一个局部变量(苏盏注:即函数表达式,此时是undefined),但并不初始化它们。

  (3)声明并初始化函数((苏盏注:确切的说是函数声明函数)。

  对于第二轮,该书只是说执行代码,我认为不只是执行代码,第二轮还包括初始化第一轮未初始化的局部变量和函数表达式。

  

  可以这么理解,在浏览器读到咱们自己写的代码的之前,underscore的所有代码已经执行了一遍,函数wrapper在执行第二轮中已经完成了初始化,所以当浏览器读到咱们自己写的调用函数_时,函数_已经可以引用wrapper函数了。

  等等,函数_怎么能引用wrapper函数呢,在underscore.js的立即执行函数完成后,局部变量wrapper已经被垃圾回收机制给回收了,怎么还能被_应用呢。嗯,闭包机制嘛。真正使我困惑是:浏览器怎么知道在初始化_的时候,_内部引用了一个外部函数,根据我以前的理解,初始化函数时,浏览器不会执行函数内部的内容,既然不执行,怎么知道内部有个函数。后来看单页Web应用32页译者注释写到:JS函数作用域链是通过词法来划分的,意即在定义函数的时候作用域链就固定了。有更详细的内幕么?

 

  

变量提升和执行环境对象

标签:

原文地址:http://www.cnblogs.com/zhansu/p/5790807.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!