JS引擎

编译与执行

  Javascript引擎会在词法分析和代码生成阶段对运行性能进行优化,包含对冗余元素进行优化(例如对语句在不影响结果的情况下进行重新组合)。

  对于Javascript来说,大部分情况下编译发生在代码执行前的很短时间内,涉及的概念有引擎、编译器、作用域。

  变量声明例如var a = 2这条表达式,编译阶段会先查询作用域是否有同名变量,如果有就忽略声明(仅仅忽略var的声明),继续编译。如果没有,会在当前作用域的变量集合中创建一个变量,命名为a。

    {//编译阶段找不到a 执行var avar a = 1;//运行阶段执行 a = 1console.log(a); //1//编译阶段找到了变量a 忽略此条语句var a = 2;//运行阶段执行 a = 2console.log(a); //2}

LHS查询与RHS查询

  当变量被使用时,会进行查询操作,例如赋值操作a = 1是LHS查询,另外一种称为RHS查询。

  简单理解就是,对于赋值操作(包括隐性的)为LHS,作为变量进行引用时时RHS查询。

    {//赋值操作 LHS查询var a = 1;function fn(a) {//进入函数体存在一个隐性的a = 2操作//log使用RHS查询
            console.log(a);}//函数调用发生RHS查询 2作为引用传入
        fn(2);}

作用域嵌套  

  一个块或函数嵌套在另一个块或函数中时,就会形成作用域嵌套,在当前作用域无法找到某个变量时,就会在外层作用域继续查找,直到找到该变量;或者没找到,抛出一个错误,查询停止。

词法作用域

  作用域有两个工作模型,一种是词法作用域,另一种叫动态作用域。

    //全局作用域//包含f1function f1(a) {var b = a * 2;//f1的作用域//包含a,b,f2,function f2(c) {//f2的作用域//包含cconsole.log(a, b, c); // 2,4,4
        }f2(b)}f1(2)

  变量查找会先从最内部的作用域开始查找,找不到会去上一级嵌套的作用域。

  无论函数在哪里被调用,也无论如何被调用,词法作用域都只由函数被声明时所处的位置决定。(闭包)

    function outer() {//找到后返回avar a = 1;//保留对outer作用域中a的引用function inner() {//被调用时开始查询变量a
            return a;}return inner();}function f1() {//outer作用域决定于声明处//所以不会查找到f1的avar a = 2;//在这里调用词法作用域依然不会变
        outer();}f1(); //1

  顺便讲一下闭包为什么会改变变量的生命周期,闭包需要两个条件。

  1、外部函数内部有另外一个函数,并对外部函数的某个变量保持了引用。

  2、外部函数提供一个内部函数的访问接口。

  而内部函数对外部作用域的引用保持就叫闭包。

  生命周期的问题还要提到GC回收问题,一般常见的回收算法有两种:引用计数算法、标记算法,由于引用计数会出现循环引用问题,这里以标记算法举例简单讲一下。标记算法会将代码构建成类似于DOM树之类的结构,根节点为window,第一轮先开始向下遍历,可以被根节点引用的变量上一个标记(假设为false)。遍历完后,第二轮开始清除操作,所有标记为true将会被垃圾回收。看不懂的话,还是看代码注释吧。

    function fn1() {var a = 1;//闭包条件1function fn2() {a = a + 1;return a;}//闭包条件2return fn2;}var fn = fn1();// a变量并没有被回收// window.fn => fn2 => a 可以获取到a 保留console.log(fn()); //2console.log(fn()); //3function fn3() {var b = 1;b++;//此函数没用function fn4() {console.log(b);}return b;}//window.fn3 => ??? b无法被引用 消除console.log(fn3()); //2console.log(fn3()); //2 被回收了并再次初始化

   另外,可以通过eval和with语法强行修改作用域,但并不推荐使用,主要是性能方面的问题。因为引擎在编译时会对词法作用域进行分析优化,保证代码运行时能更快的找到对应的变量,但是如果有eval问题就不一样了,无法保证会传入什么代码,有可能会影响现有的作用域导致优化失败,所以引擎可能会根本不优化,

转载于:https://www.cnblogs.com/QH-Jimmy/p/6444185.html

读书笔记-你不知道的JS上-词法作用域相关推荐

  1. 读书笔记-你不知道的JS上-混入与原型

    继承 mixin混合继承 function mixin(obj1, obj2) {for (var key in obj2) {//重复不复制if (!(key in obj1)) {obj1[key ...

  2. 读书笔记-你不知道的js(上卷)

    你不知道的js 该书不是全面的讲解,这本书可以作为扫过基础知识后的提升和补充. 作者站在js原生语言的角度(而不是站在js营销的角度,营销使得js扭曲本身的含义去迎合其他语言的理解和使用习惯)去从新定 ...

  3. 读书笔记-你不知道的JavaScript(上)

    本文首发在我的个人博客:http://muyunyun.cn/ <你不知道的JavaScript>系列丛书给出了很多颠覆以往对JavaScript认知的点, 读完上卷,受益匪浅,于是对其精 ...

  4. JS深入--词法作用域、执行上下文与闭包

    文章目录 词法作用域 执行上下文与词法环境 闭包 闭包练习 作用域链 REF   个人博客文章同步地址 词法作用域   JS 使用的是词法作用域(或称为静态作用域),函数的作用域在定义的时候就决定了, ...

  5. 你不知道的JavaScript之词法作用域

    词法作用域 总结一下作用域的定义:作用域就是一套规则,这套规则用于引擎如何进行查找变量以及在哪找到变量(可以看看之前我博客写的引擎和作用域之间的对话). 作用域分为词法作用域(也叫静态作用域)和动态作 ...

  6. 深入学习js之——词法作用域和动态作用域

    开篇 当我们在开始学习任何一门语言的时候,都会接触到变量的概念,变量的出现其实是为了解决一个问题,为的是存储某些值,进而,存储某些值的目的是为了在之后对这个值进行访问或者修改,正是这种存储和访问变量的 ...

  7. Javascript读书笔记(六)函数作用域,声明提前,作用域链,闭包

    参照内容来自<JavaScript权威指南>,<JavaScript高级程序设计> 函数作用域 类似C语言的编程语言中有块级作用域,JavaScript中没有块级作用域,取而代 ...

  8. js变量提升_学习笔记:JS中的作用域和预解析

    知识总结:谢静贤.汤昊 在javascript中作用域是非常重要的,本文将会说明作用域以及我们在工作,以及面试中的一些面试题,如果有不足的地方希望大家可以评论指出来,自己一定会及时的改正错误,避免大家 ...

  9. ES6读书笔记--对js对象爱的深沉

    1.尾调用优化 允许某些函数的调用被优化,以保持更小的调用栈.使用更少的内存,并防止堆 栈溢出.当能进行安全优化时,它会由引擎自动应用.不过你可以考虑重写递归函数,以便 能够利用这种优化 // 尾调用 ...

最新文章

  1. SAP MM 盘点流程中上不了台面却很实用的方案建议
  2. yum源的超级简单配置
  3. 选择排序-直接选择排序
  4. BZOJ3246 IOI2013Dreaming
  5. 【修正】销售开票BAPI实例:BAPI_BILLINGDOC_CREATEMULTIPLE
  6. MSSQL 如何采用sql语句 获取建表字段说明、字段备注、字段类型、字段长度
  7. 从技术小白到老司机,这20本书帮你“快进”20年
  8. python str函数isdigit、isdecimal、isnumeric的区别
  9. 剑指offer没有java版吗_剑指Offer(Java版) 持续更新中
  10. 188. 买卖股票的最佳时机 IV
  11. C#基础知识(收藏)
  12. [置顶] C#中给Label控件设置BackgroundImage属性
  13. Find n‘th number in a number system with only 3 and 4
  14. Matlab滤波函数
  15. nodejs 实现 磁力链接资源搜索 BT磁力链接爬虫
  16. c语言字母表输出大写字母,c语言输入一个大写字母,输出字母表中它前面的字母和后面的字母.如果...
  17. 使用uiautomatorviewer报错Error obtaining UI hierarchy
  18. Android Studio模拟器报错:Could not initialize DirectSoundCapture
  19. html文件的图标显示缩略图,HTML5上传图片base64编码显示缩略图
  20. iframe中的方法

热门文章

  1. PowerShell简介
  2. 配置node.js默认的npm安装目录
  3. [转]2020年4月github上最热门项目-java
  4. 读书笔记_打开量化投资的黑箱01
  5. 如何用敏捷搞垮一个IT团队?
  6. 学习精华——成长篇(三)
  7. android 状态栏一体化 fragment,单Activity多Fragment动态修改状态栏颜色功能
  8. dell装双系统linux系统,记录DELL灵越7590/7591安装Ubuntu+Win10双系统
  9. java in array_ArrayList to Array Conversion in Java
  10. Python中的浅复制(shallow copy)和深复制(deep copy)