概述
时隔两年后二刷JavaScript高级程序语言,纯手打读书笔记+思维导图,让自己有一个比较全面的知识体系,后面有遇到例子的时候会慢慢补充更多的用法。有不足之处欢迎大家评论区指出,共勉!!
第四章 变量、作用域和内存
一、变量
1、基本类型和引用类型
基本类型存的是值,引用类型存的是地址,地址指向堆内存的对象。
传参:按值传参,引用类型的话值就是地址。
引用类型的类型检测:instanceof 如 arr instanceof Array //true
2、变量声明
提升让同一作用域中的代码不必考虑变量是否已经声明就可以直接使用
使用 var 声明的迭代变量会泄漏到循环外部(函数作用域)
3、变量声明的三种方式
1)var
声明为此函数作用域中的变量,var是函数作用域。
声明提升:var关键字声明的变量会自动提升到函数作用域 顶部
2)Let:块作用域
let不能在块作用域中重复声明,let 声明的变量不会在作用域中被提升
使用 let 在全局作用域中声明的变量不会成为 window 对象的属性(var声明的变量则会)。
For(var i 0 0;;) //i是在for外部的变量,而let声明的话,i就是for函数作用域内的变量
而在使用 let 声明迭代变量时,JavaScript 引擎在后台会为每个迭代循环声明一个新的迭代变量。
暂时性死区:
如果块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成封闭作用域。凡是在声明之前就使用这些变量,就会报错。
var | let | const |
函数作用域 | 块作用域 | |
声明提升 | 否 | |
可重复声明 | 否 | |
全局是window的属性 | 否 | |
for(i),i是同一个变量 | 每个迭代都是新的变量 | |
暂时性死区 | ||
声明必须初始化且不可改变值 |
二、执行环境及作用域
1、执行上下文:
分为全局上下文/函数上下文/块级上下文
2、函数上下文
函数每调用一次,都会产生一个新的执行上下文环境,因为不同的调用可能就有不同的参数。
this是执行上下文的成分,根据调用不同指向。
执行上下文栈:处于活动状态的执行上下文环境只有一个。
每个上下文都有一个关联的变量对象,存储这个环境中定义的所有变量和函数
3、作用域:
函数定义时就已经定义了,它是一个地盘,静态的,没有变量。
4、作用域链:
上下文中的代码在执行的时候,会创建变量对象的一个作用域链,链接上下文的变量对象,用来寻找变量的值。
5、块级上下文
某些语句会导致在作用域链前端临时添加一个上下文,这个上下文在代码执行后会被删除
q try/catch 语句的 catch 块
q with 语句:(var声明变量是属于函数作用域的,而let/const则是属于这个with指定的对象的)
三、内存管理
1、垃圾回收
标记清理:标记内存中存储的所有变量,去掉执行上下文变量和被引用的变量,然后销毁带标记的所有值并收回它们的内存。
引用计数:有循环引用的问题。(IE 6, 7 对DOM对象进行引用计数回收)
2、内存管理
1)、通过const/let声明变量
2)、隐藏类和删除:创建一个对象后再动态添加属性和使用delete动态删除对象属性的结果都是一样的,都会造成使用不同的隐藏类,消耗性能,所以应该避免这两种情况的发生。最要在构造函数内一次性声明所有属性,将不用的属性设置为null。
3)、内存泄露:不用var声明变量会成为window对象的属性,window不销毁变量内存就不会释放。闭包也会导致内存泄露。
4)静态分配与对象池
频繁创建和删除对象会提高垃圾回收的频率影响性能。
避免在方法内创建临时对象,而使用静态对象,同时使用对象池实例化对象。
对象池:管理一组可回收的对象,可以向对象池请求一个对象、设置其属性、使用它,然后在操作完成后再把它还给对象池。
贪婪算法:单调递增的静态的内存,有对象则使用,无则创建新的,但要创建充足的数组长度。
3、数组实现原理
数组:数组是用Oject实现的,index其实是字符串key
数组分为快数组和慢数组,一般情况下根据空洞划分(i不连续)。
1)快数组:存储的索引是连续的,为了节省寻找事件就开辟连续的内存,可以节省查找时间,可以动态扩容和收缩。
2)慢数组:存储的索引不连续,空洞多或大,为了防止连续内存造成的空间浪费,使用字典的形式。
快慢数组之间可以自动转化。
最后
以上就是健忘豌豆为你收集整理的JS高级程序设计精简版(第四章:变量、作用域和内存)附思维导图的全部内容,希望文章能够帮你解决JS高级程序设计精简版(第四章:变量、作用域和内存)附思维导图所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复