值类型和引用类型,内存泄漏,函数,变量声明提升,事件流

本文深入探讨内存泄漏的概念,将其比喻为操作系统资源被榨干的过程。详细分析内存泄漏的四种类型:常发性、偶发性、一次性及隐式,并阐述值类型与引用类型的内存管理区别。此外,还讲解了内存泄漏如何从操作系统角度影响程序运行,以及JavaScript中声明提升的机制。

内存泄漏

内存泄漏也称作“存储泄露”,用动态存储分配函数动态开辟的空间,在使用完之后未释放,结果导致一直占据该内存单元,直到程序结束,(内存空间使用完了之后没有回收)这就是内存泄漏。

内存泄漏形象的比喻是“操作系统可提供给所有进程的存储空间正在被某个进程榨干”,最终结果是程序运行时间越长,占用存储空间越来越多,最终用尽全部存储空间,整个系统崩溃。所以“内存泄漏”是从操作系统的角度来看的。

这里的存储空间并不是指物理内存,而是指虚拟内存大小,这个虚拟内存大小取决于磁盘交互区设定的大小。
内存泄漏并不是指内存物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

内存泄露的分类

  • 常发性
    发生内存泄漏的代码会被多次执行到,每次执行的时候都会导致一块内存泄露。
  • 偶发性
    发生内存泄漏的代码只有在某些特定环境操作过程下才会发生。
  • 一次性
    发生内存泄露的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块且仅一块发生内存泄漏。
  • 隐式
    程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。

值类型和引用类型

值类型(基本类型):字符串(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
document9
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值