JavaScript的数据类型,及其如何区分?
1,原始(值)类型 (Number、String、Boolean、Null、Undefined)
2,引用类型(Object,Array,Function)
JavaScript提供typeof方法检测数据类型,但是有两点需要注意:
- null类型进行typeof检测后,结果是object,原因在于,null类型被当做是一个对空对象的引用。
- typeof 无法检测引用类型中的Array类型,但可以检测出Function类型
JavaScript提供instanceof方法检测引用数据类型:
instanceof
运算符本身用来测试一个对象在其原型链中是否存在一个构造函数的 prototype
属性。但是正好可以利用此特性来进一步检测一个对象的原型链的prototype属性是否是Array.
例:Array类型的判断操作
var dataType=[];
typeof dataType==="object" && dataType instanceof Array; //true
JavaScript的堆、栈和数据类型的关系
1. 基本类型:五种基本数据类型可以直接访问,他们是按照值进行分配的,存放在栈(stack)内存中的简单数据段,数据大小确定,内存空间大小可以分配。
2. 引用类型:即存放在堆(heap)内存中的对象,可以保存多个数据,数据个数随用可变。变量(栈内存)实际保存的是一个指针(地址),这个指针指向堆中的对象。
对象是引用类型,但是对象的值却是原始类型,深拷贝就是根据此特性进行操作。
根据上面的陈述,基本类型拷贝的时候只是在内存中又开辟了新的空间,和它的拷贝对象属于互不想干的东西。
因此深浅拷贝是相对于引用类型的,以便于我们对引用类型拷贝对象的保存!
- 浅拷贝只是复制了一份拷贝对象保存在栈中的地址(指针);
- 深拷贝就是要取出一个对象内的所有值(包含嵌套的对象内的值),复制给另一个对象。
举个栗子,证明一下吧:
var father1 = {name:'shangdi',age:1000,job:['teacher','cook']};
function copy(obj){
var childs = {};
for(var key in obj){
childs[key] = obj[key];
}
return childs;
}
var child1 = copy(father1);
console.log(child1); //{ name: 'shangdi', age: 1000 , job: ["teacher", "cook"]}
console.log(typeof child1); //object
上面的例子可以清晰的看出,copy方法复制了father1对象的所有属性。
child1.name = 'bangbang';
console.log(father1); //{ name: 'shangdi', age: 1000 , job: ["teacher", "cook"]}
console.log(child1); //{ name: 'bangbang', age: 1000 , job: ["teacher", "cook"] }
此时当我修改child1的name属性时,father1对象的name属性却没有跟着修改。此时的name、age属性属于深度拷贝。
child1.job.push('programer');
console.log(father1); //{ name: 'shangdi',age: 1000,job: [ 'teacher', 'cook', 'programer' ] }
console.log(child1); //{ name: 'shangdi',age: 1000,job: [ 'teacher', 'cook', 'programer' ] }
注意:这次改变child1对象的job属性,发现father1对象的job属性也跟着添加了数值!此时job属性的拷贝属于浅拷贝!因为child1的job属性
的地址和father1的job属性的地址是一样的,指向同一个引用类型数据--数组,所以它们的值就是一样的了。
相信据此,看官们应该明白,深浅拷贝的差异了。
那么如何处理深度拷贝嵌套对象的问题,个人感觉需要用递归调用可以更好的解决吧!
function deepCopy(p,c){
c = c || {};
for (var i in p){
if(p.hasOwnProperty(i)){
if(typeof p[i] === 'object'){
c[i] = Array.isArray(p[i]) ? [] : {};
deepCopy(p[i],c[i]);
}else{
c[i] = p[i];
}
}
}
return c;
}