• 浅谈javascript函数执行过程


    javascript函数执行过程:

      1. 为函数创建一个执行环境

      2. 复制函数的 [[scopes]] 属性中的对象构建起执行环境的作用链域

      3. 创建函数活动对象并推入执行环境作用链域的前端

      4. 执行代码

      5. 销毁执行环境和活动对象(闭包情况下活动对象仍被引用没被销毁)

    用例子来说明:

    function Person(name) {
        this.getName = function() {
            return name;
        };
    
        this.setName = function(value) {
            name = value;
        };
    }
    
    var person = new Person("Candy");
    alert(person.getName()); //"Candy"
    person.setName("Greg");
    alert(person.getName()); //"Greg"
    

    以调用Person()构造函数、setName() 函数为例,函数执行过程中,各对象的关系如下:

    (1)未调用前,只存在全局变量对象

      全局变量中定义了Person() 构造函数,Person作为全局变量对象的一个属性,[[scopes]] 保存着Person() 构造函数的作用链域,因为Person() 构造函数是定义在全局变量对象里面的

      Person为什么会有 [[scopes]] 属性???

      在创建函数时,会创建一个预先包含全局变量对象的作用链域,这个作用链域被保存在内部的 [[scopes]] 属性中

    (2)new Person() 创建对象,调用之后,存在全局变量对象,Person对象

      用new调用构造函数会经过以下4个步骤:

        1. 创建一个新对象

        2. 将构造函数的作用域赋给新对象(因此this就指向这个新对象——person,这也是变量name为什么不是对象属性的原因)

        3. 执行构造函数中的代码(为新对象添加属性)

        4. 返回新对象

      重点说第3个过程,执行过程如图:

    调用(执行)函数时,会为函数创建一个执行环境,然后通过复制函数的 [[scopes]] 属性中的对象构建起执行环境的作用链域。此后,又有一个活动对象(Person的活动对象)被创建并推入执行环境作用链域的前端,所以图中的作用链域有2层。

      调用完毕后,返回Person对象

    Person执行环境在函数执行完毕后销毁,Person活动对象没有被销毁

      为什么Person活动对象没有被销毁???

        这种情况属于闭包:Person活动对象仍然被getName、setName的 [[scopes]] 引用,即仍在作用链域中,所以没有被销毁

      注意:

        Person() 构造函数中定义了getName()、setName() 两个函数,还有函数的参数name

        new Person() 创建的 Person对象 的属性只有getName()、setName(),没有name属性,name不是用this声明的,不是Person对象的属性

         

    (3)调用setName(),存在全局变量对象,Person对象

     创建setName() 的执行环境,然后通过复制函数的 [[scopes]] 属性中的对象构建起执行环境的作用链域。此后,又有一个活动对象(setName的活动对象)被创建并推入执行环境作用链域的前端,所以图中的作用链域有3层。

     函数执行完毕后:

    setName执行环境和setName活动对象都被销毁,因为setName活动对象没有被引用

    - 其他:

    通过这个例子,也很好理解为什么person.name是undefined,因为person对象没有name这个属性,getName、setName能访问name属性是因为它们通过作用链域访问到了Person活动对象中的name属性

    PS:用构造函数创建的对象是独立的

  • 相关阅读:
    http基础知识总结
    unittest单元测试流程
    python测试框架nose
    HTML,CSS,JS之间的关系
    无法远程连接mysql,连接后也没有权限创建数据库
    Android 导入导出CSV,xls文件 .
    Android Sqlite 导入CSV文件 .
    用java开发的网站或者程序
    111个知名Java项目集锦,包括url和描述
    Ruby简介,附带示例程序
  • 原文地址:https://www.cnblogs.com/bobo-site/p/9831554.html
Copyright © 2020-2023  润新知