1

JavaScript数据类型

说起面试,做技术的人应该都有一种感觉,那就是工作的时候用到的东西都可以去查,但是当别人直接问一个问题时,让你在不去查询的情况下,当即做回答,还是有一定难度的。尤其是面试的时候,很多程序员能力不缺,但是让你当即说出来或者当场手写代码的时候,往往容易卡壳。笔者也有类似的经历,遂决定从今天起,写一些面试题总结以及对面试的思考。欢迎对面试有兴趣的同行一起来探讨,共同进步。

1. JavaScript中的数据类型

JavaScript中的数据类型一共有两类:一类是基本数据类型,一类是引用数据类型。

  • 基本数据类型有:Undefined, Null, String, Number, Boolean, Symbol
  • 引用数据类型有:Object

2. 数据类型的存放位置

  • 基本数据类型的数据存放在 栈(Stack) 上,引用数据类型的数据存放在 堆(Heap) 上。
  • 基本数据类型(也叫原始数据类型)直接存储在栈中的简单数据段,占用空间小、大小固定,属于被频繁使用的数据,所以放入栈中存储;
  • 引用数据类型占用空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值的时候,会首先检索栈中的地址,取得地址后再从堆中获得实体。

3. 如何判断数据类型?

判断数据类型的方法常见的有以下几个,下面一一来说:

// typeof xxx;

  • 使用 typeof 方法判断数据类型的时候,常见于判断上面提到的基本数据类型。而当使用 typeof 判断引用数据类型的时候,typeof 只会返回 functionobject 两种数据类型,这显然不是我们想要的更加精准的类型判断。所以,判断基本数据类型时,typeof 可以用;判断引用数据类型时,typeof 不建议使用;
  • typeof 对于基本类型,除了 null 都可以显示正确的类型 (typeof判断null时,返回的是 object );
  • typeof 对于对象,除了函数都会显示 object
  • 对于null来说,type会返回object,这是一个存在了很久的Bug。

// A instanceof B;
instanceof 通常用来判断 A 是否是 B 的实例,如果 AB 的实例,那么 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 Objecttrue 时,心理多多少少有些觉得不够干脆利索。那么继续看看有没有更高效的判断引用数据类型的方法呢?答案是肯定的。请看下面:

// 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的时候,一定要使用 ===,因为 == 无法分辨 nullundefined

5. == 和 === 的区别?

  • ==

1.对于 == 来说,如果双方类型相同的话,直接比大小;如果双方的类型不一样的话,就会进行类型的转换。
2.它会先判断是否在对比 nullundefined, 是的话返回true;
3.判断两者是否为 stringnumber,是的话将字符串转为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-y...
https://www.cnblogs.com/M-rig...
https://blog.csdn.net/m0_3768...
https://www.cnblogs.com/echol...

张子溪
146 声望9 粉丝

程序员