面试总结之数据判断数据类型的几种方式

173 阅读2分钟

数据类型

数据类型分为原始类型和引用类型

判断数据类型的方法

typeof

用法:

typeof XXX 或者 typeof(XXX)

返回:

类型为字符串如: "string"

console.log(typeof 1) // 'number'
console.log(typeof '杨紫你好') // 'string'
console.log(typeof a);  // 'undefined'
console.log(typeof(true));  // 'boolean'
console.log(typeof NaN); // 'number'
console.log(typeof Symbol); // 'function'
console.log(typeof Symbol()); // 'symbol'

console.log(typeof null); // 'object'
var arr = new Array();
console.log(typeof(arr));  // 'object'
var  fun = function(){};
console.log(typeof(fun));  // 'function'
console.log(typeof(class Parant{}));  // 'function'

发现问题:

  • null、数组 检测出来都是"object "所以typeof只能检测基本类型以及部分引用类型,要想区分对象、数组、单纯使用typeof是不行的
  • 为什么typeof null 会返回 "object"呢?
  • 如何判断该实例是某个对象的实例呢?
  • 又有哪些方法可以判断数组?
  • 是否有一个方法可以检测所有类型呢?

第一个疑问 typeof null 为什么会返回 "object"呢?

所有的数据类型,在计算机存储都是[64]位的二进制来存储,前三位则表示数据类型,一般前三位都是0的就会认为是对象

前三位类型名称
000对象
1整数
010浮点数
100字符串
110布尔

而null和undefined有点“特殊”

undefined: -2^30

null: 64位都是0

null都是0导致判断前三位时候000就被认为是对象所以返回"object"

null instanceof null // TypeError: Right-hand side of 'instanceof' is not an object
null instanceof Object // false

第二个疑问如何判断该实例是某个对象的实例呢?

instanceof

用法:

object instanceof constructor

返回:

true或者false

function Car(){};
var auto = new Car();
console.log(auto instanceof Car); // true
console.log(auto instanceof Object); // true

instanceof 操作符的实现原理

x instanceof y 通过判断 y.prototype 是否在x. proto 原型链上,如果在则返回true,否则返回false

function Car(){};
var auto = new Car();
function MyInstanceof(x,y){
   var _prototype = y.prototype,_proto = x.__proto__;
   while(true){
     if(_proto === null){
        return false;
     }
     if(_proto === _prototype){
       return true;
     }
   		_proto =_proto.__proto__;
   };
};
console.log(MyInstanceof(auto,Car))

第三个疑问哪些方法可以判断数组?

1instanceof
let arr = [];
console.log(arr instanceof Array);
2、__proto__
console.log(arr.__proto__ == Array.prototype);
3、constructor
console.log(arr.constructor == Array);
4Array.isArray
console.log(Array.isArray(arr))
5Object.prototype.toString.call(arr) //'[object Array]'

第四个疑问是否有一个方法可以检测所有类型呢? 答案是肯定的

Object.prototype.toString.call

每个对象都有一个 toString() 方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中 type 是对象的类型,可以通过 toString() 来获取每个对象的类型。为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg (来至于MDN)

var toString = Object.prototype.toString;
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]
toString.call(undefined); // '[object Undefined]'
toString.call(Symbol()); // '[object Symbol]'
toString.call([]); // '[object Array]'