1.typeof 和 instanceof检测数据类型有哪些异同
首先我们先要了解js有哪些数据类型?
原始类型(基本类型): undefined、null、boolean、number和string
引用类型(复杂类型): object
1.1 typeof检测是返回数据类型:
console.log(typeof(undefined)) // undefined
console.log(typeof(null)) // object
console.log(typeof(true)) // boolean
console.log(typeof(123)) // number
console.log(typeof('Zeo')) // string
为什么typeof(null) 返回的是object?
计算机检测typeof返回的是机器码后三位,后三位为000则返回object
null 在计算机中存储为 000000...000 => object
typeof检测引用类型返回的是object/function
1.2 instanceof检测是返回ture or false
console.log([] instanceof Array) // ture
console.log({} instanceof Object) // true
console.log(new Date() instanceof Date) // true
console.log(new Person() instanceof Person) true
console.log([] instanceof Object) // ture
instanceof 是顺着原型链去判断
区别: 输出类型不一样,typeof直接检测的当前值的数据类型; 而instanceof会顺着原型链去判断,并不能百分百确定当前值的数据类型; typeof返回值是一个字符串,该字符串说明运算数的类型,结果为number,boolean,string,function(函数),object(null, 数组,对像),undefined;instanceof是用来判断A是否为B的实例对象,检测的是原型。
补充,如下所示方案也可以检测运算值的数据类型:
console.log(Object.prototype.toString.call('1')) // string
console.log(Object.prototype.toString.call([])) // Array
2.深入理解数据的存储形式-堆栈
2.1 什么是栈?什么是堆?
栈: 计算机为原始类型开辟的一块内存空间 // undefined、null、boolean、number和string
堆: 计算机为引用类型开辟的一块内存空间 // object
堆在栈里存的是地址值
3.深浅拷贝方式
浅拷贝
1.遍历赋值
var obj = {
a: 'hello',
b: {
a: 'world',
b: 111
},
c: [11, 22, 33]
}
function simpleClone (objNew) {
var obj = {}
for(var i in objNew) {
obj[i] = objNew[i]
}
return obj
}
var objCopy = simpleClone(obj)
console.log(obj)
console.log(objCopy)
上述方法为浅拷贝,如果修改了obj中b的值,会导致objCopy的b的值也会修改,原因是obj中的b是一个对象属于引用类型,存储的是一个地址值,和objCopy中的b引用的同一个地址,地址指向的同一个堆,因此修改了obj中b的值也会导致objCopy中的b的值被修改。
2.Object.create()
var objCopy = Object.create(obj)
console.log(obj)
console.log(objCopy)
上述也是一个浅拷贝
深拷贝
1.遍历赋值
function deepClone(startObj, endObj) {
var obj = endObj || {}
for(var i in startObj) {
if (typeof startObj[i] === 'object') {
obj[i] = startObj[i].constructor === Array ? [] : {}
deepClone(startObj[i], obj[i])
} else {
obj[i] = startObj[i]
}
}
return obj
}
var objCopy = deepClone(obj)
console.log(obj)
console.log(objCopy)
上述方法为深拷贝,修改了obj中b的值不会影响objCopy的值
- JSON.parse()、JSON.stringfy()
var objCopy = JSON.parse(JSON.stringify(obj)) // object -> string -> object
console.log(obj)
console.log(objCopy)