【JS启示记】引用类型——地址

说“引用类型”,因为它有个弯儿不好理解——什么是引用?

JS数据类型分两种:基本类型和引用类型。

当我们定义变量的时候,实际是在计算机的内存中为数据分配一份存储空间。

表面上看:

1
2
var a = 3;
var b = [1,2,3];

我们将数字3赋给了变量a,将数组[3]给了变量b,二者并无区别。

多一个操作

1
2
var c = a;
var d = b;

打印如下

c:3
d: [1,2,3]

来一点改变

1
2
c = 5;
d[1] = [5];

再看打印结果

c:5
a:3
d: [1,5,3]
b:[1,5,3]

到此我们可以发现不同之处。

基本类型赋值前后的变化互不影响,而引用类型产生了影响

发生了什么?

基本类型在做赋值的时候,是找了一个新的存储空间,把自身的复制一份出去,然后两者相互独立,改一方不影响另外一方。

引用类型则不同,它是把存储值的地址放在了另外一个空间里,不论哪个地址的内容改了,就都会发生改变。打个比方,就像两人拿了同一个保险箱的钥匙,不论谁从那个箱子放东西、取东西,另外一人打开箱子都会看到变化。

那么引用类型有哪些?

常规对象:Object、Array、Date、RegExp、Function

基本包装类:Boolean、Number、String

单体内置对象:Global、Math

可以看出,种类很多,而且JS是一门基于对象的语言,对象恰恰是引用类型的值,当我们创建了一个对象,就可以有一系列丰富的特性和操作,譬如:

  • 属性,用于存取值
  • 方法,用于执行特定操作
  • 原型链,可以继承或者共享以上两者

更为方便的是,javaScript语言本身已经提供了颇为丰富的操作方法,在使用引用类型时,可以不定义就直接使用,这里不做深究,聊具体对象的时候再详述。

有这么几点需要说一下:

  • 引用类型看似并列关系,但所有类型都从Object继承了基本的行为——toString、valueOf等,且它们沿原型链向上追溯最终是到Object,可以理解为,Object是个基对象,其他类型添加了各自独有的属性或者方法做了扩展。

  • 函数是Function类型的实例,所以它也是对象,也有方法。

  • 每个包装类都可以对应到同名的基本类型,在读取基本类型的时候就会创建对应的对象,从而方便操作,但在操作的执行语句执行完之后,便立即销毁

意思是:

1
2
var a = 3;
a.name = "number";

当执行到第二条语句的时候,会自动创建一个Number()对象,然后把”number“赋给对象的name属性,但是这条语句执行完之后马上就销毁,所以并不能继续访问或者操作a.name。

  • 在所有代码执行之前,就已经存在两个对象,Global和Math,你可能对Global感到陌生,但一定对window不陌生,它就是web浏览器所定义的,用来承担Global角色的对象。

小结

”巧妇难为无米之炊“,基本类型是一门语言的基石,他们用于存储、计算、输出,但引用类型的存在才真正使JavaScript变得灵活和强大起来,理解和掌握它们就尤为重要,本文只是一篇小tips,后面我们继续探讨。