JavaScript数据类型
说起面试,做技术的人应该都有一种感觉,那就是工作的时候用到的东西都可以去查,但是当别人直接问一个问题时,让你在不去查询的情况下,当即做回答,还是有一定难度的。尤其是面试的时候,很多程序员能力不缺,但是让你当即说出来或者当场手写代码的时候,往往容易卡壳。笔者也有类似的经历,遂决定从今天起,写一些面试题总结以及对面试的思考。欢迎对面试有兴趣的同行一起来探讨,共同进步。
1. JavaScript中的数据类型
JavaScript中的数据类型一共有两类:一类是基本数据类型,一类是引用数据类型。
- 基本数据类型有:
Undefined
,Null
,String
,Number
,Boolean
,Symbol
- 引用数据类型有:
Object
2. 数据类型的存放位置
-
基本数据类型的数据存放在 栈(Stack) 上,引用数据类型的数据存放在 堆(Heap) 上。
-
基本数据类型(也叫原始数据类型)直接存储在栈中的简单数据段,占用空间小、大小固定,属于被频繁使用的数据,所以放入栈中存储;
-
引用数据类型占用空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值的时候,会首先检索栈中的地址,取得地址后再从堆中获得实体。
3. 如何判断数据类型?
判断数据类型的方法常见的有以下几个,下面一一来说:
// typeof xxx;
- 使用
typeof
方法判断数据类型的时候,常见于判断上面提到的基本数据类型。而当使用typeof
判断引用数据类型的时候,typeof
只会返回function
和object
两种数据类型,这显然不是我们想要的更加精准的类型判断。所以,判断基本数据类型时,typeof
可以用;判断引用数据类型时,typeof
不建议使用; typeof
对于基本类型,除了null
都可以显示正确的类型 (typeof
判断null
时,返回的是object
);typeof
对于对象,除了函数都会显示object
;- 对于
null
来说,type
会返回object
,这是一个存在了很久的Bug。
// A instanceof B;
instanceof
通常用来判断 A
是否是 B
的实例,如果 A
是 B
的实例,那么 A instanceof B
返回 true
; 否则,返回 false
。
instanceof
的原理或者说内部机制是:通过判断对象的原型链中是不是能找到类型的 prototype
。
例如:
var a = {};
a instanceof Object; // true
var b = [];
b instanceof Array; // true
到这里的时候,看似都是正常的,没有什么问题。那么如果发挥孔乙己”四个回字“的想法呢? 比如:
var c = {};
c instanceof Array; // false
var d = [];
d instanceof Object; // true
这个时候,发现数组在使用 instanceof
的时候,既有属于数组的情况,又有属于对象的情况。虽然,我们可以仅仅使用 A instanceof Array
来判断 A
到底是不是数组,但是当数组也可以被 instanceof Object
为 true
时,心理多多少少有些觉得不够干脆利索。那么继续看看有没有更高效的判断引用数据类型的方法呢?答案是肯定的。请看下面:
// Object.prototype.toString.call( xxx );
其中 "xxx" 就是我们想要判断的数据类型。
这里的toString()
是Object
的原型方法,调用该方法后,会返回当前对象的 [[class]]
属性,这是一个内部属性,其格式为 [object Xxx]
, 其中 "Xxx"
就是对象的类型。
对于 Object
对象而言,直接调用 toString()
方法即可返回 [object Object]
;而对于其他对象而言,需要通过调用
call() / apply()
方法才能返回正确的类型信息。比如:
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(Symbol()); //[object Symbol]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window 是全局对象global的引用
4. Null,Undefined 的区别?
-
Undefined
:表示不存在这个值,“缺少值”,就是此处应该有一个值,但是还没有定义,当尝试去读取的时候,返回undefined
。 -
Null
: 表示一个对象被定义了,值为“空值”,它是一个对象,但是是一个空对象,没有属性和方法。在验证Null
的时候,一定要使用===
,因为==
无法分辨null
和undefined
。
5. == 和 === 的区别?
-
==
1.对于==
来说,如果双方类型相同的话,直接比大小;如果双方的类型不一样的话,就会进行类型的转换。
2.它会先判断是否在对比null
和undefined
, 是的话返回true
;
3.判断两者是否为string
和number
,是的话将字符串转为Number
;
4.判断其中一方是否为Boolean
,是的话将boolean
转为数字再比较;
5.判断其中一方是否为object
, 且另一方为string
,number
, 或者symbol
,是的话将object
转为原始类型再进行判断。 -
===
直接判断两者类型和值是否相同。
6. 类型转换
- 转
Boolean
在条件判断时,除了undefined
,null
,false
,NaN
,""
,0
,-0
,其他所有的值都会转为true
,包括所有对象。 - 对象转基本类型
对象在转换为基本类型时,首先会调用valueOf
,然后调用toString
,并且这两个方法也是可以重写的。 - 四则运算符
1.只有当使用加法运算时,其中一方是字符串类型,就会把另一方也转为字符串类型;
2.其他运算,只要有一方是数字,那么另一方就转化为数字;
3.加法运算会出发三种类型转换:将值转换为原始值、转换为数字、转换为字符串。
(本节完)
参考链接:
https://www.cnblogs.com/yan-yubo/p/Javascript-built_in_objects.html
https://www.cnblogs.com/M-right/p/9474307.html
https://blog.csdn.net/m0_37686205/article/details/89194248
https://www.cnblogs.com/echolun/p/7889848.html