ECMAScript有5种简单数据类型(也叫基本数据类型): Null 、 Undefined 、 Number 、String 、 Boolean
还有一种复杂数据类型:对象Object。ECMAScript提供了很多原生的引用类型,如Array、Object、Function.
基本数据类型保存在栈内存,引用类型的引用地址保存在栈内存,而引用的值保存在堆内存中。
我们常会遇到复制一个值的情况,直接复制一个基本数据类型值,能得到一个副本,栈内存中开辟了新的空间存放,
而直接复制一个引用类型值时,会为引用地址开辟一个栈内存存放,但引用的值还是同一块堆内存,新的引用地址和老的引用地址相同都指向这一块堆内存。
Object类型和Array类型是在程序计算复制过程最需要注意的,看两个例子。
|
|
|
|
然而有时候并不希望新的对象和老的对象的值一改变就会互相影响。
所以要想办法解决这个问题。
深拷贝实现
为了能对数组和对象进行深度复制,需要对他们的属性递归复制,直到属性是基本类型值才直接赋值,这样就需要实现一个深度赋值的函数。
|
|
借用JSON方法
|
|
但是这种方法有个缺点,JSON不支持变量、函数或对象实例,在使用JSON.stringify()序列化对象时所有函数及原型成员会被忽略,不体现在结果中。
所以object_new中的prototype指向了Object.prototype, sayHello函数也丢失了。
数组深拷贝
数组有一些自己的深拷贝方法
spread运算符
spread运算符是将数组或类数组对象展开成一系列用逗号隔开的值
|
|
concat()和slice()
Array的concat()方法:先创建当前数组的一个副本,然后将接收到的参数添加到副本的末尾,最后返回新构建的数组。
|
|
Array的slice()方法: 可以返回一个新数组,新数组是原数组的一个片段,接收1个或2个参数,第一个参数表示片段在原数组中的起始位置,第二个参数表示片段在原数组中的结束位置,如果第二个参数省略,结束位置在yuan数组的末尾项。
|
|
参考
- JavaScript高级程序设计 第3章 基本概念 3.4 数据类型
- JavaScript高级程序设计 第5章 引用类型 5.2.6 Array类型 操作方法
- JavaScript高级程序设计 第6章 面向对象的程序设计 6.1.3 属性特性 6.3.4 原型式继承 Object.create()
- JavaScript高级程序设计 第20章 JSON 20.2 解析与序列化