深拷贝&浅拷贝

堆和栈的区别

堆(stack)系统自动分配的地址,由系统自动释放
栈(heap) 动态分配的内存,不会自动释放

ECMAScript数据类型

基本数据类型(5个)

string, number, boolean, null, undefined
存放在栈中的简单数据段,直接存值,所以直接访问

基本类型不可改变,通常情况下重新复制,不是改变基本数据类型的值

引用数据类型

object
存放堆内存中,在栈内存中存放的是指针

‘==’比较相关转化

数据类型相同时直接比较
数据类型不同的情况下:
对基本类型值boolean, string, number先转换为number,然后进行比较
对于null和undefined,只有 x,y分别是它们时才相同,其他都为false
string ‘’ ‘xx’ ‘0’ undefined null true false new Object() function
number 0 NaN 0 NaN 0 1 0 NaN NaN

浅拷贝和赋值

1
2
3
4
5
6
7
8
9
function shadowCopy(obj){
var dis = {}
for (var prop in obj){
if(obj.hasOwnProperty(prop)){
dis[prop] = obj[prop]
}
}
return dis
}
和原数据是否指向同一对象 第一层数据为基本数据类型 原数据中包含子对象
赋值 改变会使原数据一同改变 改变会使原数据一同改变
浅拷贝 不是 改变会使原数据不会改变 改变会使原数据一同改变
深拷贝 不是 改变会使原数据不会改变 改变会使原数据不会改变

深拷贝

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
35
36
37
38
// Zepto 中深拷贝
// 内部方法:用户合并一个或多个对象到第一个对象
// 参数:
// target 目标对象 对象都合并到target里
// source 合并对象
// deep 是否执行深度合并
function extend(target, source, deep) {
for (key in source)
if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
// source[key] 是对象,而 target[key] 不是对象, 则 target[key] = {} 初始化一下,否则递归会出错的
if (isPlainObject(source[key]) && !isPlainObject(target[key]))
target[key] = {}

// source[key] 是数组,而 target[key] 不是数组,则 target[key] = [] 初始化一下,否则递归会出错的
if (isArray(source[key]) && !isArray(target[key]))
target[key] = []
// 执行递归
extend(target[key], source[key], deep)
}
// 不满足以上条件,说明 source[key] 是一般的值类型,直接赋值给 target 就是了
else if (source[key] !== undefined) target[key] = source[key]
}

// Copy all but undefined properties from one or more
// objects to the `target` object.
$.extend = function(target){
var deep, args = slice.call(arguments, 1);

//第一个参数为boolean值时,表示是否深度合并
if (typeof target == 'boolean') {
deep = target;
//target取第二个参数
target = args.shift()
}
// 遍历后面的参数,都合并到target上
args.forEach(function(arg){ extend(target, arg, deep) })
return target
}