《JavaScript高级程序设计》笔记:变量、作用域、内存问题

2019-06-24 admin

一、写在前面

最近研究了创建Android虚拟机、vscode结合weex开发Android APP、Vmware装MAC虚拟机的事,看的内容不够多,接下来加油

二、变量、作用域和内存问题

2.1 基本类型、引用类型

  • 变量类型:

    • 基本类型: 简单数据段,按值访问的,可操作变量中的实际值
    • 引用类型:对象,按引用访问,操作对象的引用,能动态添加属性
  • 变量复制:

    • 基本类型:直接分配两个内存空间,互不影响
    • 引用类型:复制了指针,指向堆中同一对象,相互影响
  • 传参(见示例):

// 示例
function setName(obj) {
    // 指向person,添加属性name
    obj.name = "Nicholas";
    // 指针指向新的内存空间
    obj = new Object();
    obj.name = "Greg";

    // 函数执行完毕后,局部对象立即销毁
}

var person = new Object();
setName(person);
alert(person.name);    //"Nicholas"
  • 检测类型

    • typeOf特殊:null返回object
    • instanceof:引用类型检测,(某实例) instanceof (某类型)

2.2 执行环境、作用域

  • 执行环境:定义变量或函数有权访问的其他数据范围,决定行为。中有变量对象,保存环境中定义的所有变量和函数,环境销毁,变量、函数销毁

    • 全局执行环境,web中为window对象
    • 局部执行环境,执行流进入函数,函数环境被推入环境栈,执行后,栈将其环境弹出,控制权返回之前的执行环境
  • 作用域链: 在环境中执行代码,会创建变量对象的作用域链,保证(有权访问当前环境的)变量和对象有序访问

作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对象在最开始时只包含一个变量,即arguments对象(这个对象在全局环境中是不存在的)。作用域链中的下一个变量对象来自包含(外部)环境,而再下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象

  • 标识符解析:沿作用域链一级一级搜索标识符。从作用域链前端开始,逐级向后,直到找到标识符为止

  • 内外关系:

    • 内部环境可以通过作用域链访问所有外部环境,外部环境不能访问内部环境中的任何变量或函数
    • 每个环境可以向上级搜素,但不能向下搜索进入另一个执行环境

2.3 延长作用域链

在作用域链前端加临时变量对象,执行后移除

function aaa( ) {
    var qs = '?id=12';
    // 引用location,with内部可用location的所有属性和方法
    with(location) {
        // href为locaiton.href
        var url = href + qs;
    }
   // 在aaa( )内可拿到with( )内定义的url
    return url;
}
  • catch特殊情况:IE8以前catch的错误对象会添加至执行环境的变量对象,catch外也能访问(IE9修复了)

2.4 没有块级作用域

{ } 封闭的代码块中定义的变量,执行后没有被销毁,依旧存在于{ }外部执行环境中

  • 声明变量

    • var:自动添加到最接近的环境中。没有var直接声明,添加到全局环境中(严格模式下导致错误,不推荐)
  • 查询标识符

    • 从作用域链前端开始,向上逐级查询,直至匹配为止(先自身再向上)
    • 访问局部变量比访问全局变量更快

2.5 垃圾收集

执行环境管理着代码执行过程中使用的内存 自动垃圾收集机制:实现所需内存分配、无用内存回收,自动管理。固定时间间隔,周期性检索不再继续使用的变量,打标记,释放其占用的内存

  • 回收策略

    1. 标记清除(主流)

      • 变量进入环境、离开环境,标记不同
      • 标记方式:翻转某位,或以环境列表、离开环境列表区分,或其他
      • 运行机制:内存中全部变量加标记,再去掉环境中的、被环境中引用的变量的标记,剩下还有标记的,准备删除,垃圾收集器清除内存,销毁值,回收空间
    2. 引用计数(不常见)

      • 跟踪每个值被引用的次数

      • 计数规则:引用类型的值赋给一个变量,引用次数加一;已经引用的变量不再引用它,引用次数减一

      • 运行机制:垃圾收集器运行,释放引用次数为0的值所占的内存。

      • 特殊情况:

        • 循环引用(例:两对象间相互引用,则引用次数永不为0,无法销毁)
        • IE9之前,BOM、DOM对象以COM(使用引用计数策略)形式实现,循环引用后删除DOM,对应值也不会回收(通过赋值null,手动断开循环引用解决)。IE9后,BOM、DOM转为真正的js对象,避免了该问题
  • 性能问题

    • IE7之前:内存分配量达到任一临界值(256变量、4096对象数组、64K字符串)则回收,缺点:如一直在临界值之上,则一直回收
    • IE7修正:临界值动态修正,初始与之前相等,回收的分配量低于15%,临界值加倍,回收的内存分配量85%,临界值恢复初始
    • 手动触发方式(不推荐):
// 手动触发方式
// IE
window.CollectGarbage();
// Opear7~
window.opera.collect();
  • 管理内存

    • 内存分配:给web浏览器的少于给桌面应用的,防止系统崩溃
    • 优化内存占用:只保存必要数据,不用的置null(解除引用,给全局中的用,局部的会自动销毁),等待下一次垃圾回收

[转载]原文链接:https://segmentfault.com/a/1190000019569688

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-68086.html

文章标题:《JavaScript高级程序设计》笔记:变量、作用域、内存问题

相关文章
JavaScript教程:JS中的原型
Keith Peters 几年前发表的一篇博文,关于学习没有“new”的世界,其中解释了使用原型继承代替构造函数。两者都是纯粹的原型编码。 标准方法(The Standard Way) 一直以来,我们学习的在 JavaScript 里创建对...
2015-11-12
canvas图片绘制跨域问题解决方案Tainted canvases may not be exported
图片跨域问题的一般解决方法 当使用canvas绘制网络图片的时候,经常会出现“Tainted canvases may not be exported”报错,上网搜一下解决方案,应该给的都是给img添加crossOrigin属性,尝试了一下...
2018-04-19
javascript是什么意思
avaScript是Netscape开发的一个对象脚本语言,它使用在世界各地数以百万计的网页和服务器应用程序上。 网景的JavaScript是ecma - 262版的标准脚本语言,和公布的标准只有轻微的差异。 与广为流行的错误理解相反,Ja...
2015-11-12
21天学通javascript
简介: 本书是Javascript入门教程。Javascript是Web开发中应用最早、发展最成熟、用户最多的脚本语言。其语法简洁,代码可读性在众多脚本语言中最好,它在使用时不用考虑数据类型,是真正意义上的动态语言。本书总分为四篇,共21章...
2015-11-16
JavaScript的组成
一个完整的JavaScript由3个部分组成:核心(ECMAScript) 文档对象模型(DOM) 浏览器对象模型(BOM) ECMAScript 描述了该语言的语法和基本对象 ; DOM 描述了处理网页内容的方法和接口 ; BOM 描...
2015-11-12
javaScript+turn.js实现图书翻页效果实例代码
为了实现图书翻页的效果我们在网上可以看到很多教程 在这里推荐turn.js 网上的turn.js 有api 不过是英文的  很多人看起来不方便 .关于代码也是奇形怪状在这里我将详细讲解如何使用turn.js实现翻页效果 ,本篇文章只是讲解 ...
2017-03-16
JavaScript 事件流、事件处理程序及事件对象总结
JS与HTML之间的交互通过事件实现。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以使用监听器(或处理程序)来预定事件,以便事件发生时执行相应的代码。这种在传统软件工程中被称为观察员模式,支持页面的行为与页面的外观之间的松散耦合。...
2017-04-05
JavaScript变量的声明
声明变量 变量在脚本中的首次亮相是在其声明中。 在变量首次出现时将会在内存中设置它,因此您稍后可在脚本中引用它。 应在使用变量之前先声明变量。 可以使用 var 关键字实现此目的。 <span id=“mt9” class=“sent...
2015-11-12
7个提高效率的JavaScript调试工具
鐜板湪鐨凧avaScript浜嬪疄涓婂凡鐒舵垚涓轰簡娴佽�岀殑web璇�瑷€锛屽嵆浣垮畠骞朵笉瀹岀編銆傚緢澶氱▼搴忓憳涓嶅枩娆㈢敤JavaScript鍐欎唬鐮侊紝鏄�鍥犱负鍐欏埌鍚庢潵鎬讳細鍑虹幇鍚勭�嶈帿鍚嶅叾濡欑殑bug锛岃€屼笖鍦ㄥ紑...
2015-11-11
JavaScript短路原理精简代码
js中||和&&的特性帮我们精简了代码的同时,也带来了代码可读性的降低,虽然高效,但请灵活使用。 在js逻辑运算中,0、""、null、false、undefined、NaN都会判为false,其他都为t...
2015-11-12
回到顶部