js中的预编译和作用域链

2023-05-16

预编译目的

1. 定义作用域中的初始化词法环境,而词法环境中有定于作用域,从而规定了变量的作用域

2. 先是在为undefined,减少运行时报错

形参去实参的区别

1.形参变量只有在被调用时才分配内存单元,在调用结束时, 即刻释放所分配的内存单元。因此,形参只有在函数内部有效。 函数调用结束返回主调函数后则不能再使用该形参变量。

2.实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形参。 因此应预先用赋值,输入等办法使实参获得确定值。

function add(a,b) {
    return a + b
};
add(1,2);
// a,b是形参,1.2是实参

JavaScript运行三部曲

脚本执行js引擎都做了什么呢?

  1. 语法分析
  2. 预编译
  3. 解释执行

1.语法分析:分析语法是不是错了

2在语句执行的时候会先进行预编译

3.在编译完了进行语句执行

下面就是编译的主要步骤

预编译的过程(分四步):

1.(对函数)创建AO对象;(对全局的时候也就是Window)创建GO对象

2.找形参和变量声明,将变量名和形参名作为(AO对象,或GO对象)的属性值 初始值为undefined

3.将实参值传递形参统一

4.在函数体里面找函数声明,值赋予函数体

A0,GO就是执行期的上下文定义了一个函数的执行环境(词汇环境),当一个函数在执行的前一刻,会创建一个执行期上下文(执行上下文创建的时间),并且每次在函数执行的时候这个执行期上下文都是不相同的,因为没一次都是全新的

在预编译和执行的过程会对赋值语句会对AO,GO中的变量进行覆盖,应该以执行结束后的结果为最终的变量标准。

当出现同命的时候函数为什么会覆盖变量应为函数是第4步变量是第二步就复制了,所以会函数的优先级高

下面是一个例子的全过程:

    <script type="text/javascript">
		global = 100;
		function fn(){
			console.log(global); //undefined
			global = 200;
			console.log(global); //200
			var global = 300;
		}
		fn();
		var global;
	</script>

 第一阶段全局预编译

1.首先全局对象创建GO执行上下文
GO{
    2.对形参和变量声明,将其作为属性名,值为undefined
    global:undefined
    3.全局对象没有形参
    4.在函数体里找函数声明,值赋予函数体
    fn:function fn(){};
}

第二阶段执行代码

1. global = 100
2.fn();(先预编译fn(),在执行)

第三阶段 :由于fn函数要执行了先对其进行预编译

1. 对函数产生AO环境
AO{
 2.对形参和变量声明,将其作为属性名,值为undefined
    //当局部变量AO中存在的时候先找局部变量AO里的变量,这个时候虽然GO全局中存在global为100,但局部中已经有global为undefined
    global:undefined --fn的AO执行到第二句-->200 --fn的AO执行到第四句-->300
 3.没形参
 4.没函数声明
}

第四步:执行fn() 

A0执行{
    第一句:console.log(global); //undefined在AO的执行上线中global:undefined;
    第二句:global = 200;
    第三句:console.log(global); //在AO中找global已经变成了200
    第四句:global = 300; //
}

最终结果 

    GO{
      global:100
      fn:function fn(){ };
    }
    AO{
      global:300
    }

只有把这个看懂了(看懂一点也没关系)下面我们来写什么是作用域链 ,看完了什么是

作用域链

函数也是一个对象在这个对象中有些我们可以访问的属性比如prototype,name,不可以访问的有[[scope]]属性

[[scope]]属性:指的就是我们所说的作用域,其中储存了运行期上下文(执行期上线下文A0 G0)的集合

作用域链:[[scope]]中储存的执行期上下文对象的集合,这个集合呈链式链接,也叫作用域链

下面看一个例子

function a() {
  function b() {
    var b = 234;
  }
  var a = 123;
  b();
}
var glob = 100;
a();

图一:在b定义的时候a马上快执行完的时候的图像

图二:在b自己执行的时候会变成

    

当b执行的时候:首先b会继承了aAO和GO,这里的aAO全等于a中的aAO

scope chain(栈的形式:先进后出)中的数值代表数值的key,key代表:

  • 0 ---自己的AO(Activation Object)
  • 1---a的AO
  • 2---GO(Clobal Object)

由于由作用链的关心才可以说(0--自己OA中没有的变量)可以向上(1---a中的OA)找或者(2---GO)中找,也为以后闭包产生做铺垫

子 - 父 -祖宗--全局 这样一个(作用域链)的过程

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

js中的预编译和作用域链 的相关文章

  • css小测--两栏布局

    目标效果 这个题得分我是6分中国题是针对表格布局 xff0c flex布局 xff0c inline block布局 xff0c absolute布局来完成 xff0c 大家突然问题来了为什么没float xff0c 嗯 xff0c 这个看
  • Vue $nextTick

    使用场景 1 当改变了DOM中的数据后 xff0c 立马去获取DOM中的数值 2 当我们在watch侦听器中改变了数据 xff0c 立马用这一些数据去做一些操作 xff0c 这里为什么不可以呢 xff1f 因为watch其实应该也算是会被推
  • javaScript 快速排序

    简单理解 首先我觉得我们要明确一般算法都是需要递归的 xff0c 所以我们首先完成第一循环 第一个循环我们找到一个主元 xff08 数组的中间 xff09 xff0c 我们把大于的放右边 xff0c 小于的放左边 然后在分别把主元左边的和右
  • for..in 和 for..of的区别

    in xff1a 支持IE6 43 xff08 老 xff09 枚举对象枚举字符串 xff08 IE9 43 后支持 xff09 枚举数组 xff0c 但是数组只身的方法 xff0c 和原型上的方法也会枚举出来 xff0c xff08 可以
  • 垂直水平居中的方法

    垂直水平居中 HTML解构 lt div class 61 34 container 34 gt lt div class 61 34 box box 11 34 gt 1 lt div gt lt div gt lt div class
  • line-height理解

    行高的单位 百分比 xff1a 突出了行高和字体大小的基佬关系当字体行高的单位为百分比的时候 xff0c 行高以字体大小为依据 em xff1a em这个单位 xff0c 当作用在行高的时候是以当前文字大小为依据 xff0c 当作用在字体大
  • 剖析Vue数据劫持的实现原理

    原文 xff1a https github com DMQ mvvm xff08 包含原文源码 xff09 由于源码的注释比较少 xff0c 我自己加了注释的地址 xff1a https github com zengqingxiao MV
  • css弹性动画

    通过css让生硬的动画变得更加自然 下面我们会通过javaScript和css分别实现 效果图 xff1a 我们知道没一个物体运动都有一个运动轨迹 xff0c 例如上面的小球是模拟的弹簧运动从而让动画更加自然 xff0c 而上图的运动轨迹图
  • C#利用服务器实现客户端之间通信

    这篇文章主要为大家详细介绍了C 利用服务器实现客户端之间通信 xff0c 感兴趣的小伙伴们可以参考一下 先来讲述下我自己对于整个Socket通信过程的理解 xff0c 毕竟初学 xff0c 说错见谅 xff0c 知道错了会改正 1 首先在服
  • js中的节流和防抖

    在学习Element ui源码的过程中有注意到题目使用的节流防抖居然是引用的一个npm包 xff0c 而不是自己写的一个utils为什么我会这样想呢 xff0c 因为在看Data组件的时候E没有使用一些常见的比如 moment 这样的组件库
  • 设计模式

    订阅发布者 事件监听 xff0c 发布 class Pubsub constructor this handles 61 事件的订阅 64 param String type 发布的事件类型 64 param Function handle
  • JS中的变量提升和函数提升问题

    学习完后的总结 Js代码分为两个阶段 xff1a 编译阶段和执行阶段 Js代码的编译阶段会找到所以的申明 xff0c 并用合适的作用域将他们关联起来 xff0c 这个是词法作用域的核心内容 包括变量申明和函数声名都会在代码被执行前的编译阶段
  • this的由来

    JS的数据结构 xff1a var obj 61 foo 5 面的代码将一个对象赋值给变量obj JavaScript 引擎会先在内存 xff08 堆 xff09 里面 xff0c 生成一个对象 foo 5 xff0c 然后把这个对象的内存
  • div中动态文字内容的处理(内容在文字少的时候文字居中,在文字多的时候局左)

    如何实现板块中的内容在文字少的时候文字居中 xff0c 在文字多的时候局左 HTML lt div class 61 34 box2 34 gt lt p class 61 34 content 34 gt 当文字少的时候 lt p gt
  • css流体布局下发宽度分离原则与box-sizing的使用

    学习完了CSS世界的总结 因为默认的box sizing 为content box宽度作用在内容 所以当出现 box width 100px border 1px solid red 或 box width 100px padding 20
  • css任意高度收缩动画技术

    弹性动画学习 学习css世界后 xff1a 利用max height和overflow hidden来实现 HTML lt div class 61 34 box 34 gt lt input id 61 34 check 34 type
  • 学校CSS世界第三章总结

    1 块级元素 块级元素并不等于display xff1a black xff1b li的默认display xff1a list item xff1b table的display默认是table xff1b 他们都符合块级元素的基本特征 x
  • padding属性详细分析

    lt p gt 1 padding会增加元素的尺寸 lt p gt lt p gt 2 padding对内联元素的影响 xff0c 对内联元素的垂直方向的影响是有的但视觉是没有 lt p gt lt a href 61 34 javasvr
  • 利用margin来实现两端对起

    为什么会对齐一般我们给li标签设置margin left最后一个总是会有一个不需要的left那为什么如何去除呢 xff1f 答案是 xff1a margin xff1a 负值 如果ul右边多了20px xff0c 那么给ul设置个margi

随机推荐

  • 裸机通过u盘以hostengine的方式成功安装ovirt4.5

    本次安装是在两台服务器上进行 xff0c 采用hostengine的方式安装 xff0c 也就是一台机上先安装oVirt node xff0c 再安装oVirt engine xff0c 另外一台机安装oVirt node xff0c 并加
  • 关于paddin-bottom的中的未定义的问题

    css世界的学习后 xff1a padding的兼容问题一般遇不到 xff0c 滚轮什么时候出现 xff1a Chrome浏览器的滚轮是在子元素超过content box的时候显示 xff1b IE Firefox是在超过padding b
  • 流动性的深入学习

    何为 34 流 34 流 61 文档流 xff1b 当我们在一个容器中倒入足量的水时 xff0c 水一定会均匀平铺整个容器 所以流动性也就是100 自适应 但width 61 100 xff01 61 流动性自适应100 原因 xff1a
  • 如何用border来画三角形

    学习总结 HTML lt div class 61 34 son 34 gt lt div gt CSS son width 0px border 20px solid border color black transparent tran
  • window和document的区别

    window对象 它是一个顶层对象 而不是另一个对象的属性 xff0c 即浏览器的窗口 document 当前显示的文档 该属性本身也是一个对象
  • JS距离的理解

    偏移量 offsetWidth 元素在水平方向上占用的空间大 xff0c 包括元素的宽度 可见的垂直滚动条宽度 左边框高度和右边框高度 offsetWidth 61 width 43 padding 43 border offsetHeig
  • 汉堡按钮的制作以及其中的问题

    第一种自己写的 xff0c 下面的第二种是网上的用一个span使用做出来的 HTML lt div class 61 34 box 34 gt lt chang用来判断是否变换 gt lt span class 61 34 s1 34 gt
  • 对js动画和时间控制的使用

    JavaScript Document 打算移动的元素ID xff1b elementID 该元素的目的地的 34 左 34 位置 xff1b final x 该元素的目的地的 34 上 34 位置 xff1b final y 停顿时间 x
  • css动画小结

    一 转换 transform IE9 43 1 旋转rotate transform rotate 30deg ms transform rotate 30deg IE 9 webkit transform rotate 30deg Saf
  • Django 判断访问来源是PC端还是手机端

    pc or mobile py 判断访问来源是pc端还是手机端 import re def judge pc or mobile ua 34 34 34 param ua 访问来源头信息中的User Agent字段内容 return 34
  • 圆形进度条是学习

    学习网站 xff1a http www cnblogs com jr1993 p 4677921 html CSS margin 0px padding 0px box margin 50px auto 0 width 300px heig
  • 定位插件

    写了个等位插件 xff0c 点击nav中的LI xff0c 位移 xff08 与href有视觉效果 xff09 到达相应板块 xff08 这里的类比li中的类中多了个H字母 xff09 的位置 lt li class 61 34 wz 34
  • JQ复习

    一选择器 1 基本选择器 2 层级选择器 3 过滤选择器 first 选取第一个元素 last 选择最后一个元素 not 去除所有与给定选择器匹配的元素 39 input not first 39 even选取索引是偶数的元素 xff0c
  • 第7章艺术编程Ajax的学习

    终于学到Ajax以前一直没接触到一直以为很NB xff0c 对这些内容我基本上是个小白中的小白哎 xff0c 继续加油 Ajax可以做到只更新页面的一下部分 xff0c 其他部分不需要重新加载 下面就是根据书上的内容所写 HTML lt d
  • 函数是否加括号的问题

    lt a onclick 61 34 fun 34 gt lt a gt 这里有括号 document getElementById 34 ID 34 onclick 61 fun 这里不可以有括号 为什么会有这样的不同 首先加上括号是执行
  • this的详细分析加案例

    this对象是在函数运行时候基于函数的执行环境 xff08 上下文 xff09 绑定的 方法调用模式函数调用模式改造器调用模式apply call bind调用模式 1 方法调用模式 函数有所属对象 xff0c 也就是这个函数是myObje
  • 构造函数与原型链和面向对象的学习(一)

    什么是构造函数 构造函数就是一个普通的函数 xff0c 里面可以写任何语句 逻辑语句或DOM操作 xff0c 可以new出新的实例 xff0c 使其实例可以共享构造函数的原型 第一个例子 function Fun this name 61
  • 构造函数与原型链和面向对象的学习(二)

    原型链 proto proto 也就是对象的 prototype 属性 每一个函数都有一个属性叫做prototype 指向一个对象 不是函数就没有这个属性 这个对象叫原型对象 当这个构造函数被new的时候 xff0c 他的每一个实例对象的
  • 构造函数与原型链和面向对象的学习(三)

    小案例 xff08 红绿灯 xff09 下面对面向对象写个小案例 xff08 红绿灯 xff09 上面是原图 用来来实现点击图片 xff0c 红绿灯的颜色改变 xff0c 控制背景图片的定位来改变 点击一下 就是要完成上面的效果 如果只要实
  • js中的预编译和作用域链

    预编译目的 1 定义作用域中的初始化词法环境 xff0c 而词法环境中有定于作用域 xff0c 从而规定了变量的作用域 2 先是在为undefined xff0c 减少运行时报错 形参去实参的区别 1 形参变量只有在被调用时才分配内存单元