内存泄漏
内存泄漏也称作“存储泄露”,用动态存储分配函数动态开辟的空间,在使用完之后未释放,结果导致一直占据该内存单元,直到程序结束,(内存空间使用完了之后没有回收)这就是内存泄漏。
内存泄漏形象的比喻是“操作系统可提供给所有进程的存储空间正在被某个进程榨干”,最终结果是程序运行时间越长,占用存储空间越来越多,最终用尽全部存储空间,整个系统崩溃。所以“内存泄漏”是从操作系统的角度来看的。
这里的存储空间并不是指物理内存,而是指虚拟内存大小,这个虚拟内存大小取决于磁盘交互区设定的大小。
内存泄漏并不是指内存物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。
内存泄露的分类:
- 常发性:
发生内存泄漏的代码会被多次执行到,每次执行的时候都会导致一块内存泄露。 - 偶发性:
发生内存泄漏的代码只有在某些特定环境操作过程下才会发生。 - 一次性:
发生内存泄露的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅一块发生内存泄漏。 - 隐式:
程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。
值类型和引用类型
值类型:(基本类型):字符串(string)、数值(number)、布尔值(boolean)、undefined、null
这5种基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值
引用类型:对象(Object)、数组(Array)、函数(Function)
值类型:
保存与复制的是值本身
使用typeof监测数据的类型
基本类型数据是值类型
引用类型:
保存与复制是指对象的一个指针
使用instanceof检测数据类型 返回值为true
使用new()方法构造出的对象是引用型
// 值类型:Number、string、bollean、undefined
var a = 100
var b = a
a = 200
console.log(b) // 100 保存与复制的是值本身
// 利用typeof来区分
typeof undefined // undefined
typeof 'abc' // string
typeof 123 // number
typeof true // boolean
// typeof 区分不出来引用类型(除了函数)
typeof {} // object
typeof [] // object
typeof null // object
typeof console.log //function
// 引用类型:对象、数组、函数、null(空指针)
// 可以扩展属性
var a = {age:20}
var b = a
b.age = 21
console.log(a.age) // 21 保存和复制的是指对象的一个指针
// 用instanceof来区分引用类型
// 如果变量是给定引用类型(根据它的原型链来识别)的实例,那么instanceof 操作符就会返回 true。
console.log(person instanceof Object); // 变量 person 是 Object 吗?
console.log(colors instanceof Array); // 变量 colors 是 Array 吗?
console.log(pattern instanceof RegExp); // 变量 pattern 是 RegExp 吗?
什么是声明提升?
引擎在解释JS代码之前,首先要对JS代码进行编译,其中编译的一部分工作就是找到所有的声明,包括变量和函数的所有声明都会在任何代码执行之前被处理。
例如:var a=1这句话会被浏览器读成var a和a=1两句话执行,其中var a会在编译阶段就先执行了,而a=1这段代码会在原地等待执行阶段
变量的提升
console.log(a);
var a=2;
如果按照顺序由上而下执行,那么执行到console.log(a);时,a还没有声明,所以会报一个找不到a的错,实际上时打印了一个undefined,说明a被声明了,但是没有被赋值,那么结合上一段的文字,我们可以得出代码实际运行是这样的
var a;
console.log(a);
a=2;
函数的提升
f1();//可以执行
function f1(){
}
函数声明:包括函数的代码块都会被提升,所以调用函数的时候,函数声明已经被执行过了
f2();//报错 f2不是一个函数
var f2=function(){}
以给匿名函数赋值的形式定义函数,只会提升函数声明,但是函数表达式不会被提升。变量f2被提升,但是并没有赋值,我们书写的f2无法运行,实际执行顺序如下:
var f3;
f3();
f3=function(){};
函数优先提升
f4();
var f4=function(){};
f4();
function f4(){}
函数会被优先提升,然后才是变量提升,但是当函数提升后,发现还有一个变量声明和函数声明一样的名称,这个就是重复声明,var f4是直接忽略的。实际代码运行顺序如下:
function f4(){];
f4();
f4=function(){};//因为重复声明而直接忽略
f4();
代码作用域的声明,都会在代码执行前被首先处理,所有的声明都会被移动到各自作用域的最顶端,这个过程叫做声明提升。
JS事件流
事件:文档或浏览器窗口中发生特定交互瞬间
事件流:描述从浏览器中接收事件的顺序
- 事件冒泡:从触发事件的具体元素开始,逐渐向上传播到document对象
- 事件捕获:从document对象开始,事件沿DOM树向下传递到具体目标
JS节点类型
获取节点类型:nodeType
| 节点类型 | nodetype返回值 |
|---|---|
| 元素节点 | 1 |
| 属性节点 | 2 |
| 文本节点 | 3 |
| 注释节点 | 8 |
| document | 9 |
本文深入探讨内存泄漏的概念,将其比喻为操作系统资源被榨干的过程。详细分析内存泄漏的四种类型:常发性、偶发性、一次性及隐式,并阐述值类型与引用类型的内存管理区别。此外,还讲解了内存泄漏如何从操作系统角度影响程序运行,以及JavaScript中声明提升的机制。
3万+





