javaScript高级程序
- 和QA 一起测试 UI 2.0.6
- 了解tv guide 业务
- 和中间件分析一个GINGA 问题
let 和 const 作用
let
和const
不仅改善代码风格,- 而且同样有助于垃圾回收的过程,因为
let
和const
都以块为(而非函数)为作用域,相比var
这个两个关键字可能回更早的让垃圾回收程序介入,尽早回收应该回收的内存。 - 在块作用域比函数作用域更早的终止的请酷炫这就有可能发生。
[看javaScript高级程序第四版记录]
String类型
字符串的特点
ECMAScript 中的字符串是不可变的,也就说字符串一旦创建,它们的值就不能改变,要改变某个变量的字符串,首先要先销毁原来的字符串,然后用包含新值的字符串去填充当前变量,例如:
1
2var lang= "Java"
lang= lang + "Script"以上示例中的变量 lang 开始时包含字符串”Java”。而第二行代码把 lang 的值重新定义为”Java”
与”Script”的组合,即”JavaScript”。实现这个操作的过程如下:首先创建一个能容纳 10 个字符的
新字符串,然后在这个字符串中填充”Java”和”Script”,最后一步是销毁原来的字符串”Java”和字
符串”Script”,因为这两个字符串已经没用了。这个过程是在后台发生的,在某些旧版本的浏览器(例如版本低于 1.0 的 Firefox、IE6 等)中拼接字符串时速度很慢的原因所在。但这些浏览器后
来的版本已经解决了这个低效率问题。
Date类型
- ECMAScript 中的 Date 类型是在早期 Java 中的 java.util.Date 类基础上构建的。为此,Date
类型使用自 UTC(Coordinated Universal Time,国际协调时间)1970 年 1 月 1 日午夜(零时)开始经过的毫秒数来保存日期。在使用这种数据存储格式的条件下,Date 类型保存的日期能够精确到 1970 年 1月 1 日之前或之后的 285 616 年。
javascript 传递参数
ECMAScript 中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参
数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递如同基本类型变量的复制一样,而
引用类型值的传递,则如同引用类型变量的复制一样。有不少开发人员在这一点上可能会感到困惑,因
为访问变量有按值和按引用两种方式,而参数只能按值传递。
在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数,或者用
ECMAScript 的概念来说,就是 arguments 对象中的一个元素)。在向参数传递引用类型的值时,会把
这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部。请看下面
这个例子:
1 | function addTen(num) { |
但如果使用对象,就是引用类型的关系了。再举一个例子:
1 | function setName(obj) { |
当在函数内部为 obj 添加 name
属性后,函数外部的 person 也将有所反映;因为 person 指向的对象在堆内存中只有一个,而且是全
局对象。
1 | function setName(obj) { |
垃圾收集
JavaScript实现了内存自动回收,所以开发人员可以不必关心内存使用的问题。具体有两种回收方式:标记清除以及引用计数。常用的方式为标记清除。
标记清除
当变量进入环境时,将这个变量标记为“进入环境“,从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境就可能会用到它们。当变量离开环境时,则将其标记为“离开环境”。
垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,然后会去掉环境中的变量以及被环境中的变量引用的变量的标记,而在此后再被加上标记的变量视为准备删除的变量,因为环境中的变量已经无法访问到这些变量了,最后垃圾收集器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间。
引用计数
引用计数不太常用,这里就不说了。
管理内存
一般分配给Web浏览器的可用内存数量比桌面应用程序少,这样做的主要目的是为了防止JavaScript的网页耗尽全部的系统内存而导致崩溃。
为了占用最少的内存可以让页面获得更好的性能,优化内存占用的最佳方式就是为执行中的代码只保存必要的数据,一旦数据不再有用,就通过将值设置为null来释放其引用,这种做法叫做解除引用。这个方法适用于大多数全局变量和全局对象的属性,局部变量会在离开执行环境时自动被解除引用。
内存泄露例子
1.忘记声明的局部变量
1 | function a(){ |
b 没被声明,会变成一个全局变量,在页面关闭之前不会被释放.使用严格模式可以避免.
2.闭包带来的内存泄漏
1 | var leaks = (function(){ |
当然有时候我们是故意让这个变量保存在内存中的,但是要避免无意的时候造成的内存泄漏.
3.移除 DOM 节点时候忘记移除暂存的值
有时候出于优化性能的目的,我们会用一个变量暂存 节点,接下来使用的时候就不用再从 DOM 中去获取.但是在移除 DOM 节点的时候却忘记了解除暂存的变量对 DOM 节点的引用,也会造成内存泄漏
1 | var element = { |
与此类似情景还有: DOM 节点绑定了事件, 但是在移除的时候没有解除事件绑定,那么仅仅移除 DOM 节点也是没用的
4.定时器中的内存泄漏
1 | var someResource = getData(); |
如果没有清除定时器,那么 someResource 就不会被释放,如果刚好它又占用了较大内存,就会引发性能问题. 再提一下 setTimeout ,它计时结束后它的回调里面引用的对象占用的内存是可以被回收的. 当然有些场景 setTimeout 的计时可能很长, 这样的情况下也是需要纳入考虑的.
- 本文作者: Littleki
- 本文链接: https:/littleki.gitee.io/2019/12/31/JavaScript/javaScript高级程序设计/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!