2021.6.11JavaScript高级程序设计第四版读书笔记-第四章 变量,作用域,内存(一)

本文深入探讨JavaScript中的原始值与引用值概念,解释如何通过变量访问对象。介绍了执行上下文,包括全局上下文和函数上下文,并阐述了变量作用域,特别是var、let和const的区别。此外,讨论了JavaScript的垃圾回收机制,包括标记清理和引用计数策略,以及可能导致内存泄漏的情况。最后,提到了内存管理和避免内存泄漏的注意事项。
摘要由CSDN通过智能技术生成

目标:
1.通过变量使用原始值 与 引用值
2.理解 执行上下文
3.理解垃圾回收

原始值引用值
原始值就是最简单的数据,引用值是由多个值构成的对象.

之前讨论了6种原始值:
Undefined ,Null,Boolean,Number,String,Symbol.原始值是按值访问的,我们操作的就是存储变量的实际值。

javaScript不允许直接访问内存,所以操作对象实际上操作的是该对象的引用。而非对象本身。
(这里其实我是有疑问的,像在C++里,引用其实就是对象的别名,从汇编层面看,所谓引用其实就是操作一个指针指向的对象,对象在内存中其实就是一块内存,本质也是操作内存对象。这里说操作对象的引用,那对象的引用是什么?)

动态属性

其实就是跟大众语言一样,简单变量直接复制,对象属性就是先new一个对象出来然后给属性复制。不同的是new出来的对象可以定义属性复制,比如let name2=new string(“helloworld”);
name2.age=22,这样是合法的。typeof name2是一个object,而let name1 =“hello”,
然后name1.age=23这条语句是不合法的。typeof name1是string

参数传递

ECMAScript简单变量安值传递,参数是对象的话。

确定类型
用typeof 如果不是null或者对象,就是具体的属性,要么返回object.
判断引用类型的话用instanceof。
例:person instanceof Object

执行上下文

每个上下文都有一个关联的变量对象,而这个上下文定义的所有变量和函数都存在于这个对象上。
全局上下文是最外层的上下文。根据ECMAScript实现的宿主环境,表示全局上下文的对象可能不一样,浏览器中全局上下文就是我们常说的window对象。所有通过var定义的全局变量和函数都会成文window对象的属性和方法。
每个函数都有自己的上下文,当代码执行流进入函数时,函数的上下文被推倒一个上下文栈上。在函数执行完之后上下文栈会弹出该函数上下文,将控制权返回给直线的执行上下文。
(这里我我看了好几遍,开始觉得很难理解他什么意思,后来回想了一下C的函数调用。感觉就理解了,在C里面调用函数的时候,其实就是先传参数,push xxx;然后call函数,这里函数其实就是一个地址,然后就跳到这个地址去执行这个函数了,就是该文中所谓的切换上下文。当函数执行完以后要恢复函数调用以前的状态,要平衡堆栈,就是pop xxx,然后ret返回,回到之前函数调用出的下一行,就是这里所谓的交还控制权。这样看就很简单了。)

另外所谓内部外部上下文访问变量其实就类似C一样。

var的函数作用域声明

在使用var声明变量时,变量会被自动添加到最接近的上下文。在函数中,最接近的上下文就是函数的局部上下文。
在这里插入图片描述
这里说的未验证。
在这里插入图片描述

使用let的块级作用域声明

ES6新增let关键字跟var相似,但是作用域是块级。那什么是块级?就是嘴瘾的一对{}界定的区域。(这里let定义的变量更像C)
另外一点let和var不同的是,var在同一作用域内重复声明会被忽略,而重复的let会抛出异常。(这一点就跟C十分相似了,难怪作者推荐let)
在这里插入图片描述

使用const声明常量。

除了let,ES6还同时增加了const关键字。const声明的变量必须同时初始化未某个值,在其生命周期内任何时候都不能重新赋予新值。(这不就跟C一样吗)
但是注意:
在这里插入图片描述
(就是说如果是对象,声明的变量不能再赋予新的对象,意思就是不能指向另一个新的对象,但是原对象的属性还是可以赋值的)

垃圾回收

基本思路:确定哪个变量不会再使用,然后释放他占用的的内存。这个过程是周期性的,即垃圾回收程序每隔一定时间就会自动运行。垃圾回收过程是一个近似且不完美的方案,因为某块内存是否还有用,属于“不可判定的”问题,意味着考算法是解决不了的。
主要有两种策略: 标记清理 引用计数
(是不是像极了JAVA?!)
在这里插入图片描述
(JAVA的引用计数是不是也有这个问题?作者还说了引用计数策略还有别的问题。)
在这里插入图片描述

内存管理

(似乎没什么好说的)

内存泄漏

(这个比较重要,之前写C/C++的时候要非常注意)
情况一:
意外声明的全局变量,例:
function setName(){
name=‘hello’
}
这里name没有任何修饰,解释器就把他当做window属性来创建了。只要window不被清理就不会消失,造成内存泄漏。

情况二:
定时器造成的内存泄漏,例:
let name=“hello”
setInterval(()=>{
console.log(name);
},100);
这样回调中一直引用name,name就不会被释放了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值