js基础复习--引用类型

最近开始重新复习js基础知识,巩固自己的基本技能,重看高程三~在这里做下笔记

概念

  • 基本类型:按值访问,可以操作保存在变量中的实际的值。
  • 引用类型:值是保存在内存中的对象。JavaScript不允许直接访问内存中的位置, 也就是说不能直接操作对象的内存空间,而是操作对象的引用。

其具有以下几点区别:

1.属性

我们只能给引用类型值动态地添加属性,而基本类型不可以,像这样:

1
2
3
4
5
6
7
8
9
//引用类型
var a = {};
a.b = 1;
console.log(a.b) //=> 1
//基本类型
var str = 'aaa';
str.b = 1;
console.log(str.b) //=>undefined

2.复制

对于变量的复制,基本类型会分配一个新的位置存储值,而引用对象不会。
简单的说,就是在复制变量的过程中,基本类型直接将值赋值给新的变量,而引用类型将引用地址进行复制,两个对象将引用同一个对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//基本类型
var a = 1;
var b = a;
console.log(b); //=> 1;
a = 2;
console.log(b); //=> 1;
//引用类型
var a = { c: 1 };
var b = a;
a.c = 2;
console.log(b.c); //=>2;

3.传参

ECMAScript 中所有函数的参数都是按值传递的。基本类型将值赋给形参,而引用类型会把 这个值在内存中的地址复制给形参,效果和复制相似。形参接收到的,是传入的对象的引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//基本类型
var a = 1;
function change (x){
x = 2;
return x;
}
change(a);
console.log(change(a)) // 2;
console.log(a) // 1;
//引用类型
var a = {};
function changeObj(obj){
//原始引用
obj.b = 2;
//新的引用
obj = new Object();
obj.b = 3;
}
console.log(a.b); //=> 2;

执行环境及作用域

1.作用域链

每个执行环境都有一个与之关联的变量对象,js以函数区分执行环境,通过作用域链保证对执行环境有权访问的所有变量和函数的有序访问。看下书中的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var color = "blue";
function changeColor(){
var anotherColor = "red";
function swapColors(){
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
// 这里可以访问color、anotherColor和tempColor
}
// 这里可以访问color和anotherColor,但不能访问tempColor
swapColors();
}
// 这里只能访问color
changeColor();

作用域链

注意
对于try,catch,with等可以延长作用域链

2.没有块级作用域

在ES5中,是没有块级作用域的,像这样:

1
2
3
4
5
6
7
8
9
10
11
if(true) {
var a = 1;
}
console.log(a); //=> 1
for(var i=0; i<10; i++){
dosomething(i);
}
console.log(i); //=> 10

上例中,i仍会存在于全局环境中,可以在es6中,使用let关键字解决。

3.垃圾回收

JavaScript 是一门具有自动垃圾收集机制的编程语言,开发人员不必关心内存分配和回收问题。可 以对 JavaScript 的垃圾收集例程作如下总结。

  • 离开作用域的值将被自动标记为可以回收,因此将在垃圾收集期间被删除。
  • “标记清除”是目前主流的垃圾收集算法,这种算法的思想是给当前不使用的值加上标记,然
    后再回收其内存。
  • 另一种垃圾收集算法是“引用计数”,这种算法的思想是跟踪记录所有值被引用的次数。JavaScript引擎目前都不再使用这种算法;但在 IE 中访问非原生 JavaScript 对象(如 DOM 元素)时,这种算法仍然可能会导致问题。
  • 当代码中存在循环引用现象时,“引用计数”算法就会导致问题。
  • 解除变量的引用不仅有助于消除循环引用现象,而且对垃圾收集也有好处。为了确保有效地回收内存,应该及时解除不再使用的全局对象、全局对象属性以及循环引用变量的引用。