JavaScript基础类型
- Number
- String
- Boolean
- Array
- Object
- Function
- Date
- Null
- Undefined
- Symbol
让我们一个个分析这些基础类型在深度复制时的变化.
1. Number
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function print (old, copy, s) { console.log(`${s} change`); console.log('old -->', old); console.log('copy -->', copy); } var old = 1; var copy = old; print(old, copy, 'before'); old = 2; print(old, copy, 'after');
|
Number类型不会随着源对象修改而修改, 可以直接复制
2. String
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function print (old, copy, s) { console.log(`${s} change`); console.log('old -->', old); console.log('copy -->', copy); } var old = 'string'; var copy = old; print(old, copy, 'before'); old = 'change'; print(old, copy, 'after');
|
String类型在源对象赋值为新字符串时, 由于js中字符串不可修改, 所以'change'
为一个新字符串, old
指向了新字符串地址, 而copy
所指向字符串的地址并没有被修改, 仍然指向'string'
, 所以String类型也可以直接复制
3. Boolean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function print (old, copy, s) { console.log(`${s} change`); console.log('old -->', old); console.log('copy -->', copy); } var old = true; var copy = old; print(old, copy, 'before'); old = false; print(old, copy, 'after');
|
Boolean类型也和Number类型相同, 可以直接复制
4. Array
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function print (old, copy, s) { console.log(`${s} change`); console.log('old -->', old); console.log('copy -->', copy); } var old = [0, 1, 2, 3]; var copy = old; print(old, copy, 'before'); old[1] = 11; print(old, copy, 'after');
|
Array类型在修改源对象时复制对象也会变化, 因为它们指向的是同一块内存区域
深复制版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| function print (old, copy, s) { console.log(`${s} change`); console.log('old -->', old); console.log('copy -->', copy); } function deepcopy (array) { return array.slice(0); } var old = [0, 1, 2, 3]; var copy = deepcopy(old); print(old, copy, 'before'); old[1] = 11; print(old, copy, 'after');
|
5. Object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function print (old, copy, s) { console.log(`${s} change`); console.log('old -->', old); console.log('copy -->', copy); } var old = { a: 0, b: 1 }; var copy = old; print(old, copy, 'before'); old.a = 100; print(old, copy, 'after');
|
Object类型自然也需要深度复制
深复制版本:
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 26 27 28 29 30 31 32 33 34
| function print (old, copy, s) { console.log(`${s} change`); console.log('old -->', old); console.log('copy -->', copy); } function deepcopy (object) { var copy = {}; for (var attr in object) { if (object.hasOwnProperty(attr)) { if (Object.prototype.toString.call(object[attr]) === '[object Object]') { copy[attr] = deepcopy(object[attr]); } else { copy[attr] = object[attr]; } } } return copy; } var old = { a: 0, b: 1, c: { d: 4 } }; var copy = deepcopy(old); print(old, copy, 'before'); old.a = 100; old.c.d = 400; print(old, copy, 'after');
|
6. Function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function print (old, copy, s) { console.log(`${s} change`); console.log('old -->', old); console.log('copy -->', copy); } var old = function () { return 1 }; var copy = old; print(old, copy, 'before'); old = function () { return 100 }; print(old, copy, 'after');
|
Function类型与String类型类似, 为不可变量, 只能创建新Function对象, 而复制对象由于指向地址不变, 仍为原来的Function对象
7. Date
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| function print (old, copy, s) { console.log(`${s} change`); console.log('old -->', old.getTime()); console.log('copy -->', copy.getTime()); } var old = new Date; var copy = old; print(old, copy, 'before'); old.setTime(Date.now()); print(old, copy, 'after');
|
Date类型也属于Object类型, 需要深度复制
深复制版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| function print (old, copy, s) { console.log(`${s} change`); console.log('old -->', old.getTime()); console.log('copy -->', copy.getTime()); } function deepcopy (date) { return new Date(date); } var old = new Date; var copy = deepcopy(old); print(old, copy, 'before'); old.setTime(Date.now()); print(old, copy, 'after');
|
8. Null/Undefined/Symbol
这些类型与基本数值类型行为一致