1.9.1 值类型和引用类型
所需要的内存是否固定。基本的值类型在内存中具有固定大小,而引用类型所需要的内存大小并不固定,所以它是存个地址。
JavaScript 中的引用类型,只能读。JavaScript 不能直接操纵变量中存放的地址值,它的变量只能作为引用类型来使用。而 C++ 是既可以将变量作为引用,也可以用指针来直接操作变量中存放的地址。
特例:字符串类型。从实现机制上来说,字符串应该是使用引用的方式存储的,比如字符串显然具有可变大小,所以它不可能直接存储在具有固定大小的变量当中,比如出于效率的考虑我们不希望复制字符串时是复制完整的内容,而是希望只复制字符串的引用。但是字符串在大部分行为上却表现得反而和值类型相近,比如对字符串的比较也是直接比较的它们的内容,而不是引用的地址(如下)。所以可以把字符串归为值类型。
1. 操作数据的三种方式
JavaScript 可以采用三种重要的方式来传播和操作一个数据。
可以复制它,比如将它赋给一个新变量
可以将它作为参数传递给一个函数或方法
可以把它和其他值进行比较
要理解任何一种语言,就必须理解在该语言中这三种操作是如何被执行的。无论用哪一种方式操作数据,使用值和使用引用通常对应两种截然不同的行为。
复制数据时
一个全新的副本。副本和原数据的值相同,但存储在不同的位置(两者互不影响)
实际上复制的是数据引用的副本
参数传递
同上
同上
比较数据时
比较值
当且仅当它们引用的是同一个值时,等号才会返回 true,否则就是 false(对引用数据进行比较通常是没有意义的)
2. 装箱和拆箱
值和引用的互相转换:装箱和拆箱。
JavaScript 为基本数据类型提供了对应的引用类型对象(如同 Java 为每一种值类型都提供了对应的对象类型),使得这些基本数据类型可以进行值和引用类型的转换。把基本数据类型转换为对应的引用类型的操作被称为装箱(boxing)。把引用类型转化为对应的值类型被称为拆箱(unboxing)。
装箱的最大作用就是将值作为对象来处理。通常情况,JavaScript 环境在必要时会自动地完成数值和包装对象的转换。另外因为和 Java 等语言不同,JavaScript 的包装对象并不提供对值的写操作,所以人为的装箱其实意义不大。
与装箱相反的操作是拆箱,对包装对象拆箱非常简单,只要调用它们的 valueOf 方法就能得到原始值。事实上,通常拆箱操作也是由 JavaScript 环境在必要时自动完成的,人为的处理意义也不大。
当然,对象包装器还有一个用处,就是作为普通函数调用的时候会进行类型转换。这种用法的用处更大。
最后,从值和引用的实现原理来看,程序操作值类型的数据通常比操作引用类型的数据快得多(不用额外的寻址,或是有特定的优化)。所以应尽量地使用值类型,尤其是在执行次数很多的循环中或是对性能要求较高的场合。
Last updated