Day 3
变量和作用域
1.0 原始值和引用值
在给一个变量赋值时,js会确定这个是「原始值」还是「引用值」
原始值(primitive value)就是最简单的数据,
大小值固定,保存在栈内存
保存原始值的变量是按值访问的,操作的就是存储在比变量中的实际值
不能有属性,初始化只能用字面量的形式,用new会变成一个对象
引用值(reference value)则是由多个值构成的对象
存储在堆内存
引用值是保存在内存中的对象。与其他语言不同,JavaScript不允 许直接访问内存位置
在操作对象时,是对对象引用的的操作,而非本身
可以随时添加,修改和删除其属性
复制值:
- 原始值在通过一个变量赋值到另外一个变量上时,会在一个新的的位子产生,两个变量可以独立使用,
引用值在通过赋值时,只是复制了他的指针的指向,无论哪个变量进行改变,都会影响最终的对象
1.1 传递参数
ECMAScript中所有函数的参数都是按值传递的。这意味着函数外的值会被复制到函数内部的参数中,就像从一个变量复制到另一个变 量一样。如果是原始值,那么就跟原始值变量的复制一样,如果是引 用值,那么就跟引用值变量的复制一样
function addTen(num) {
num += 10;
return num;
}
let count = 20;
let result = addTen(count);
console.log(count); // 20*,没有变化*
console.log(result); // 30
- 这里num是原始值,所以对num的操作不会影响count本身
function setName(obj) {
obj.name = "Nicholas";
}
let person = new Object(); setName(person);
console.log(person.name); // "Nicholas"
- 这里的obj是对象,所以函数内的操作会改变外部本身的值
1.3 执行上下文和作用域
执行上下文(以下简称“上下文”)的概念在JavaScript中是颇为重 要的。变量或函数的上下文决定了它们可以访问哪些数据,以及它们 的行为
var color = "blue";
function changeColor() {
let anotherColor = "red";function swapColors() {
let tempColor = anotherColor;
anotherColor = color;
color = tempColor;
// 这里可以访问「color」、「anotherColor」和**tempColor
}
// 这里可以访问「color」和「anotherColor」,但访问不到
tempColor
swapColors();
}
// 这里只能访问**color
changeColor();
- 具体细节,后续的unknown总结里会具体探讨,这是一个大块
1.4 变量声明
- 在使用 var 声明变量时,变量会被自动添加到最接近的上下文。
- let 关键字跟 var 很相似,但它的作用域是块级 的,这也是JavaScript中的新概念。块级作用域由最近的一对包含 花括号 {} 界定。换句话说, if 块、 while 块、 function块,甚至连单独的块也是 let 声明变量的作用域
1.5 垃圾回收
- JavaScript为开发者卸下了这个 负担,通过自动内存管理实现内存分配和闲置资源回收。基本思路很 简单:确定哪个变量不会再使用,然后释放它占用的内存。这个过程 是周期性的
- 离开作用域的值会被自动标记为可回收,然后在垃圾回收期间被 删除。
- 主流的垃圾回收算法是标记清理,即先给当前不使用的值加上标 记,再回来回收它们的内存。
- 解除变量的引用不仅可以消除循环引用,而且对垃圾回收也有帮 助。为促进内存回收,全局象全局对象的属性和循环引用都 应该在不需要时解除引用。
总结自问:
原始值和引用值和复制值存在的关系,分别有什么不同
执行上下文和作用域,可以用于确定什么时候释放内存
垃圾回收机制的探讨
本文使用 mdnice 排版