通过一个简单闭包,弄懂JS执行原理

<script>

function f1()
            {
                var age = 18;

function f2()
                {
                    alert(‘我今年:‘+age+‘岁‘);
                }

return f2;
            }
        
        var func3 = f1();

func3();
</script>
            闭包原理详解:----->JS的执行原理

首先,js执行分为两步骤,预编译阶段和执行阶段,明白了这个步骤,那么就以上述例子为例来慢慢分析(先花一点时间,看看上述代码,自己理解一下,再看下面的说明,效果更佳)

注:当我们在浏览器访问这个页面时,浏览器已经在瞬间完成了预编译和执行阶段

    ** 函数在声明时,会创建一个与之关联的活动对象(Active Object)也叫AO对象,AO里面包括很多东西,除了函数执行环境内的变量和函数的信息,还包括arguments对       象,scope属性,this对象等.

1. 预编译阶段:
             1.1  在全局层面创建VO对象,vo对象包含全句的变量声明和函数,
            伪代码:    VO={ f1:function(){.....}}
             1.2 进入函数f1 ,创建AO对象(AO对象和VO对象的角色一样,只是叫法不一样)
               1.2.1 首先分析形参,函数没有形参,
               1.2.2 再分析变量声明 有,AO{‘age‘:‘undefined‘}
               1.2.3 再分析函数声明 有,AO{‘f2‘:‘function(){..}‘}

此时整个VO对象为:
      VO和AO(活动对象)角色一样,只是叫法不一样,不用死扣.
               VO{
                    f1:function()
                    {AO
                            ‘age‘:‘undefined‘   
                            ‘f2‘:‘function()
                            {AO
                              scope:指向f1的AO对象   ###每个函数被声明时,都会创建一个与之关联的scope的属性
                                                     ##scope总是指向定义函数时所在的环境
                            }‘                      ##就因为有了scope,作用域链的效果才能体现出来,所以scope很伟大
                            scope:指向VO
                    }
               }

2.执行阶段
             2.1 f1(),执行,f1执行环境的AO对象:AO{‘age‘:18};
                  f2内的AO{‘age‘:18,scope:指向f1的执行环境}

2.2 func3(),执行,实际是在执行:f2(),而f2的AO{‘age‘:18,scope:指向f1的执行环境,alert(‘我今年:‘+age+‘岁‘)}
                所以func3() 能接受到局部变量age  因此就能打印出18.

注:考虑到能更简单/易懂了解到闭包,所以上述代码在执行细节和执行情况做了简化,没有牵扯到太晦涩难懂的知识点(环境栈等),若想了解JS更高级的部分,推荐<Javascript权威指南>

如果有朋友还是不太懂闭包,js执行原理,可以留言,一起探讨.

时间: 2024-12-25 02:34:27

通过一个简单闭包,弄懂JS执行原理的相关文章

摘录和再编:彻底弄懂JS执行机制

网文: https://juejin.im/post/59e85eebf265da430d571f89 并发模型和事件循环:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/EventLoop Node.js事件循环,Timers, process.nextTick() javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变.所以一切javascript版的

一个简单例子弄懂什么是javascript函数劫持

javascript函数劫持很简单,一般情况下,只要在目标函数触发之前,重写这个函数即可. 比如,劫持eval函数的代码如下: var _eval=eval; eval=function(x){ if(typeof x=='undefined') {return;} alert(x); //这里可以写任意多代码 _eval(x); } eval('alert(1)');//这时eval先弹出参数值,然后才是动态执行参数值 哈哈,是不是很简单.

从一个简单例子来理解js引用类型指针的工作方式

? 1 2 3 4 5 6 7 <script> var a = {n:1};  var b = a;   a.x = a = {n:2};  console.log(a.x);// --> undefined  console.log(b.x);// --> [object Object]  </script> 上面的例子看似简单,但结果并不好了解,很容易把人们给想绕了--"a.x不是指向对象a了么?为啥log(a.x)是undefined?".&

一个简单且丑陋的js切换背景图片基础示例

不多说,直接上代码,非常基础的一个原生js切换元素背景图片范例 <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>原生JS范例</title> <script type="text/javascript"> function changeBg()

如何继承Date对象?由一道题彻底弄懂JS继承。

前言 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正. ----------长文+多图预警,需要花费一定时间---------- 故事是从一次实际需求中开始的... 某天,某人向我寻求了一次帮助,要协助写一个日期工具类,要求: 此类继承自Date,拥有Date的所有属性和对象 此类可以自由拓展方法 形象点描述,就是要求可以这样: // 假设最终的类是 MyDate,有一个getTest拓展方法 let date = new MyDate(); // 调用Date的方法,输出GM

彻底弄懂 JavaScript 执行机制

本文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还不懂,可以揍我. 不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定的几行代码,我们需要知道其输出内容和顺序.因为javascript是一门单线程语言,所以我们可以得出结论: javascript是按照语句出现的顺序执行的 看到这里读者要打人了:我难道不知道js是一行一行执行的?还用你说?稍安勿躁,正因为js是一行一行执行的,所以我们以为js都是这样的: let a

这一次,彻底弄懂 JavaScript 执行机制

本文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还不懂,可以揍我. 文章转自:https://juejin.im/post/59e85eebf265da430d571f89 不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定的几行代码,我们需要知道其输出内容和顺序.因为javascript是一门单线程语言,所以我们可以得出结论: javascript是按照语句出现的顺序执行的 看到这里读者要打人了:我难道不知道js

Asp.net 在网页编写C#代码示例-- 一个简单的web MsSql 命令执行环境

在给一个客户做的系统上,因为要对数据库进行查看,但之前都是用TeamView来连接到客户的服务器进行数据库操作的 但最近客户那边的TeamView好像更改过密码导致我无法正常连接,而巧了客户的网官因为有事没有上班所以也法获取新的密码. 因为业务原因急需查看数据库,所以就写了一个简单的SQl命令并部署到客户的服务器来通过Web执行Sql命令 将ConnectonString更改为自己的数据库连接并保存为**.aspx即可 <!DOCTYPE html> <html> <head

一篇文章看懂JS执行上下文

 壹 ? 引 我们都知道,JS代码的执行顺序总是与代码先后顺序有所差异,当先抛开异步问题你会发现就算是同步代码,它的执行也与你的预期不一致,比如: function f1() { console.log('听风是风'); }; f1(); //echo function f1() { console.log('echo'); }; f1(); //echo 按照代码书写顺序,应该先输出 听风是风,再输出 echo才对,很遗憾,两次输出均为 echo:如果我们将上述代码中的函数声明改为函数表达式,