1.基本数据类型,复杂数据类型,特殊的数据类型(三大引用类型)
es6新增数据类型,symbol,原始数据类型,值唯一性
2.判断数据类型
(1)typeof
typeof null //Object
typeof { } //Object
typeof [ ] //Object
typeof console.log() //Function
null类型进行typeof操作符后,结果是object,原因在于,null类型被当做一个空对象引用。
(2)instanceof
在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 "object"。ECMAScript 引入了另一个 Java 运算符 instanceof 来解决这个问题。instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。与 typeof 方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。
(3)constructor
(4)Object.prototype.toString.call()
3.三大引用类型
基本类型在赋值操作后,两个变量是相互不受影响的
引用数据类型--名存在栈内存中,值存在于堆内存中,
引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响。
(与简单赋值不同,这个值的副本实际上是一个指针,而这个指针指向存储在堆内存的一个对象)
4.深度拷贝
(1)如何区分深拷贝与浅拷贝?
简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明是浅拷贝,如果B没变,那就是 深 拷贝。深入点来说,就是B复制了A,如果B复制的是A的引用,那就是浅拷贝,如果B复制的是A的本体,那就是深拷贝。
浅拷贝是拷贝了对象的引用,所以基本数据类型是不存在深浅拷贝的。当 a=1,b=a时,栈内存会新开辟一个内存
深拷贝与浅拷贝出现的根源就在于引用数据类型。当我们定义a=[0,1,2,3,4],b=a时,其实复制的是a的引用地址,而并非堆里面的值。因为指向了相同的地址,所以当我们更改a时b会改变,更改b时a也会改变,这就是深拷贝。
(3)怎么实现深度拷贝?
js中引用类型有六种:object,array,date,regexp,function,err
对数组或对象进行深度拷贝
<1>递归去复制所有层级属性。
function deepClone(obj){
let objClone= Array.isArray(obj)?[]:{};
if(obj &&typeofobj==="object"){
for(keyinobj){
if(obj.hasOwnProperty(key)){
//判断ojb子元素是否为对象,如果是,递归复制
if(obj[key]&&typeofobj[key] ==="object"){
objClone[key]=deepClone(obj[key]);
}else{
//如果不是,简单复制
objClone[key] =obj[key];
}
}
}
}
returnobjClone;
}
<2>jQuery中$.extend()方法
$.extend(true,a4,a1);
<3>借用JSON对象的parse和stringify
JSON.stringify() 从一个对象中解析出字符串
JSON.stringify({"a":"1","b":"2"})
结果是:"{"a":"1","b":"2"}"
JSON.parse()从一个字符串中解析出JSON对象
var str = '{"a":"1","b":"2"}';
JSON.parse(str);
结果是:Object{a:"1",b:"2"}
function deepClone(obj){
let _obj=JSON.stringify(obj),
objClone=JSON.parse(_obj);
returnobjClone
}
let a=[0,1,[2,3],4],
b=deepClone(a);