Javascript学习笔记(第四章)

第四章 变量、作用域与内存

变量,松散类型,可以理解为特定时间点一个特征值的名称

4.1原始值与引用值

原始值:简单的数据,按值访问,js中string属于值类型
引用值:多个值构成的对象,按引用访问,操作对象时是操作的对对象的引用,而不是对象本身。

4.1.1 动态属性

引用值,也就是对象,随时给他不存在的属性赋值,从而在之后使用这个属性。

4.1.2 复制值

原始值复制将值本身赋值给新变量,两个变量没有任何关系。
引用至赋值到新变量是将引用复制给这个变量,两个变量指向同一个对象。

let obj1 = new object();
let obj2 = obj1;
obj1.name = "joker";
console.log(obj.name);//"joker"

4.1.3 参数传递

在js中不论原始值和引用值都是通过值传递而非引用传递的。
原始值在传入函数后,经过对这个值处理并不会对这个原始值产生影响。
对象作为参数传递是,是将每个变量的引用值作为值类型传递的,而非直接传递引用。

function setName(obj){
	obj.name = "Joker";
	obj = new Object();
	obj.name = "Jack";
	}
let person = new Object();
setName(person);
console.log(person.name);//"Joker"

上面的例子输出的是“Joker”,而非将新创建的对象赋给person。新生成的Object变成了指向本地对象的指针,在函数执行结束时被销毁。
这样的机制有什么优势么,在C#中都是通过引用传递的

4.1.4 确定类型

使用typeof可以判断变量的类型,但对于对象只能得到他是Object类型,而不能得到他是哪种对象。
使用instanceof可以获取他是哪种类型的对象

4.2 上下文与作用域

变量或函数的上下文决定他们可以访问哪些数据,每个上下文都有一个关联的变量对象,这个上下文中定义的所有变量和函数都存在与这个对象上。(其他语言的上下文是否也是这样的原理?
全局上下文是最外层的上下文,ES根据宿主环境不同全局上下文的对象可能不同,如浏览器的全局上下文是windows对象。
每个函数都有自己的上下文,函数执行时上下文会被推到一个上下文栈上,函数执行完后,上下文栈会弹出这个函数的上下文,并将控制权交给之前的上下文。ES程序的执行刘就是通过这个上下文栈控制的。

4.3 垃圾回收

JS是垃圾回收的语言,就是说执行环境负责在代码执行时管理内存。C和C++等语言中,跟踪内存使用对开发者而言是个很大的负担。 JS通过自动内存管理实现内存分配和闲置资源回收。
基本思路:确定那个变量不会再用,就释放它的内存,这个过程是周期性的,即垃圾回收程序每隔一段时间(或者说在代码执行过程中某个预定的收集时间,如一个上下文执行结束?)就会自动运行。
一个变量会不会再使用,是很难分辨的。如何标记未使用的变量,浏览器发展史上主要有两种标记策略:标记清理和引用计数

4.3.1 标记清理

JS最常用的垃圾回收策略是标记清理,对上下文中或上下文变量引用的变量,和离开上下文的变脸分别标记。标记的方式有很多种,比如进入上下文时反转某一位;或者维护“在上下文”和“不在上下文”两个表。垃圾回收程序执行时,做一次内存清理,释放不在上下文的变量收回内存。

4.3.2 引用计数

引用计数不太常用,存在一些问题。
思路是对每个值都记录他被引用的次数,每多一次引用加1,一个引用被覆盖掉减1,若为0的话表示这个值无法被访问了,也就是可以清理了。
这个方法当循环引用时导致永远不会为0,内存也就无法被清理。
在早期浏览器中使用到引用计数的方式,为了避免循环引用导致的问题,需要给这个值赋值为null,就会被回收掉。

4.3.3 性能

垃圾回收周期性运行,如果内存中分配了很多变量,可能会影响性能,垃圾回收的时间调度很重要。现在通常会采用根据垃圾回收程序回收的内存大小动态分配变量、字面量或数组槽位(这些是什么?)等会触发垃圾回收的阈值。
字面量是指不可改变的值,也可以理解为常量,比如1,2…可以直接使用,本身永远不会发生改变。

4.3.4 内存管理

在使用垃圾回收的编程环境中,通常不用关心内存管理,但是计算机分配给浏览器的内存要比桌面应用程序少得多,这是为了避免大量网页导致系统崩溃的问题。所以使内存占用量保持在较小值可以让页面性能更好。优化内存最佳的方式是在执行代码时只保存必要的数据,数据不再必要就将他设置为null,这称为解除引用。这个建议最适合全局变量和全局对象的属性,因为局部变量会在超出作用域后自动解除引用。

4.4 小结

  • 6种原始值:Undefined、Null、Boolean、Number、String、Symbol
  • 原始值保存在内存上,引用值保存在内存
  • 原始值复制是复制的值本身,引用值复制是复制了指向该对象的指针
  • typeof获取变量的原始类型,instanceof获取值的引用类型
  • 任何变量都存在与某个执行上下文(作用域),这个上下文决定了变量的生命周期以及访问范围
  • 代码执行流没进入一个新上下文就会创建一个作用域链,用于搜索变量和函数
  • 局部上下文可以访问内部和全局上下文的变量,全局上下文只可以访问全局上下文的变量不可以直接访问局部上下文的任何数据
  • 主流的垃圾回收算法是标记清理,即给当前不适用的值加上标记,再回来回收他们的内存。
  • 引用计数的垃圾回收算法存在循环引用的问题,解除变量引用不仅可以消除循环引用而且对垃圾回收也有帮助。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值