目录
1.typeof和instanceof检测数据类型的异同
JS中的基本数据类型:
Undefined
Number
String
Boolean
Null
JS中引用数据类型:
Object
typeof检测 返回的是对应的数据类型
console.log(typeof(123)); //number
console.log(typeof(true));//boolean
console.log(typeof('MOOC'));// string
console.log(typeof(undefined));//undefined
console.log(typeof(null));//object
在计算机中typeof返回的数据类型是根据机器码后3位来确定的,
null在计算机的机器码是000...0000,而object的机器码就是以000结尾,
所以null的数据类型是object。这是JS语言的bug
console.log(typeof([]));// object
console.log(typeof(new Date()));//object
console.log(typeof({}));//object
console.log(typeof(function(){}));//function
console.log(typeof Array);//function
为什么是function, 在js设计的时候在引用类型的内部定义了一个内部方法call,
当用typeof检测的时候,先判断引用类型上是否有call方法,如果有就返回一个function,
否则就是object
面试题:
Q1:
var str='MOOC'
console,log(str) //MOOC
console.log(typeof('MOOC'))//string
Q2:
var str1=new String('MOOC')//实例化后的对象
console.log(str1)// {} key:value 0:M,1:O,2:O,3:C
console.log(typeof(str1))// object
instanceof 检测的结果是true 或false. A instanceof B,A是否是B实例化出来的对象。而且insatnceof是根据原型链去查找的。
console.log([] instanceof Array); true
console.log({} instanceof Object); true
console.log(new Date() instanceof Date); true
function Person(){}
console.log(new Person() instanceof Person); true
console.log([] instanceof Object); true
console.log({} instanceof Object); true
console.log(new Date() instanceof Object); true
function Person(){}
console.log(new Person() instanceof Object); true
A instanceof B 是true,B instanceof C 也是true,那么 A instanceof C 也是true
输出我们想要检测的数据类型:console.log(Object.prototype.toString.call('1'))// string
console.log(Object.prototype.toString.call([]))// array
总结
2.理解数据的存储形式-堆栈
栈:计算机为原始数据类型开辟的一块内存空间
堆:计算机为引用类型开辟的一块内存空间 object
var a='Mooc'
var b=a
b='Mooc2'
console.log(a,b)// Mooc Mooc2
在堆中开辟两个内存空间,分别存放a,b的内容
var c={key:1}
var d=c
d.key=2
console.log(c,d)// 2,2
先开辟一个栈存放指向c的内容的地址(因为不知道这个对象到底存放多少内容),然后d=c,开辟另一个栈存放d,存放的地址和c一样,指向同一个堆,堆里存放的就是key:1.
总之栈里存放的是地址值,堆里存放的具体的内容
堆栈区别
1.栈(stack):栈会自动分配内存空间,会自动释放,存放基本类型,简单的数据段,占据固定大小的空间。(基本类型:String,Number,Boolean,Null,Undefined)
堆(heap):动态分配的内存,大小不定也不会自动释放,存放引用类型,2.栈:所有在方法中定义的变量都是放在栈内存中,随着方法的执行结束,这个方法的内存栈也自然销毁。
优点:存取速度比堆快,仅次于直接位于CPU中的寄存器,数据可以共享;
缺点:存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。
堆:堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(参数传递)。创建对象是为了反复利用,这个对象将被保存到运行时数据区
3.深拷贝和浅拷贝
B复制了A,当修改A时,看B是否发生变化,如果B也跟着变化(存在堆里的引用数据类型),那就是浅拷贝,如果B没变那就是深拷贝。
浅拷贝的方法:1.遍历赋值 2.Object.create()
深拷贝的方法:1. 递归2.JSON.parse,JSON.stringify
var objCopy=JSON.parse(JSON.stringify(obj))
修改objCopy的值并不会改变obj, 上面这个过程就相当于将object->string->object
【JS】深拷贝与浅拷贝的区别,实现深拷贝的几种方法 - 听风是风 - 博客园 (cnblogs.com)
4.开发中常见的数据类型有哪些坑
NaN,0,undefined,null," " 这些特殊类型的隐式转换成false
1、 三大数据转化成boolean类型都是false
2、undefined、NaN和数值型数据相加之和为“NaN”,而null与数值型数据计算会隐式转换为0
3.NaN并且还不能等于自己(NaN==NaN)得false
console.log(NaN == NaN); // f
console.log(NaN == undefined); // f
console.log(NaN == null); // f
console.log(undefined == undefined); // t
console.log(undefined == null); // t
console.log(undefined === null); // f
console.log(undefined + 1); // NaN
console.log(NaN + 1); // NaN
console.log(null + 1); // 1