说“引用类型”,因为它有个弯儿不好理解——什么是引用?
JS数据类型分两种:基本类型和引用类型。
当我们定义变量的时候,实际是在计算机的内存中为数据分配一份存储空间。
表面上看:
1 | var a = 3; |
我们将数字3赋给了变量a,将数组[3]给了变量b,二者并无区别。
多一个操作
1 | var c = a; |
打印如下
c:3
d: [1,2,3]
来一点改变
1 | c = 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 | var a = 3; |
当执行到第二条语句的时候,会自动创建一个Number()对象,然后把”number“赋给对象的name属性,但是这条语句执行完之后马上就销毁,所以并不能继续访问或者操作a.name。
- 在所有代码执行之前,就已经存在两个对象,Global和Math,你可能对Global感到陌生,但一定对window不陌生,它就是web浏览器所定义的,用来承担Global角色的对象。
小结
”巧妇难为无米之炊“,基本类型是一门语言的基石,他们用于存储、计算、输出,但引用类型的存在才真正使JavaScript变得灵活和强大起来,理解和掌握它们就尤为重要,本文只是一篇小tips,后面我们继续探讨。