Skip to content

JS 基础:类型识别

类型系统

javascript 类型系统可以分为标准类型和对象类型,进一步标准类型又可以分为原始类型和引用类型,而对象类型又可以分为内置对象类型、普通对象类型、自定义对象类型。

类型系统

类型转化表

类型转化表

类型判断

  • typeof
  • instanceof
  • Object.prototype.toString
  • constructor

typeof

  • 可以识别标准类型(null 除外)
  • 不可识别具体的对象类型(Function 除外)
js
//1. 可以识别标准类型(`null`除外)
typeof 1; // "number"
typeof ''; //"string"
typeof undefined; //"undefined"
typeof true; //"boolean"
typeof null; //"object"

//2. 不可识别具体的对象类型(`Function`除外)
typeof []; //"object"
typeof {}; //"object"
typeof function () {}; //"function"

instanceof

instanceof 左侧为查询变量,右侧为标识对象的类

  • 能够判别内置对象类型
  • 不能判别原始类型
  • 能够判别自定义类型
js
//1. 能够判别内置对象类型
[] instanceof Array; //true
/\d/ instanceof RegExp; //true

//2. 不能判别原始类型
1 instanceof Number; //false
'xiaohong' instanceof String; //false

//3. 能够判别自定义类型
function Point(x, y) {
  this.x = x;
  this.y = y;
}
var c = new Point(2, 3);

c instanceof Point; //true

实现一个 instanceof

js
function instanceOf(left, right) {
  let proto = left.__proto__;
  let prototype = right.prototype;
  while (true) {
    if (proto === null) return false;
    if (proto === prototype) return true;
    proto = proto.__proto__;
  }
}

Object.prototype.toString.call()

  • 可以识别标准类型,及内置对象类型
  • 不能识别自定义类型
js
//1. 可以识别标准类型,及内置对象类型
Object.prototype.toString.call(21); //"[object Number]"
Object.prototype.toString.call([]); //"[object Array]"
Object.prototype.toString.call(/[A-Z]/); //"[object RegExp]"

//2. 不能识别自定义类型
function Point(x, y) {
  this.x = x;
  this.y = y;
}

var c = new Point(2, 3); //c instanceof Point;//true
Object.prototype.toString.call(c); //"[object Object]"

为了方便使用,使用函数封装如下:

js
function typeProto(obj) {
  return Object.prototype.toString.call(obj).slice(8, -1);
}

typeProto('guo'); //"String"
typeProto({}); //"Object"

constructor

constructor 指向构造这个对象的构造函数本身..

  • 可识别原始类型
  • 可识别内置对象类型
  • 可识别自定义类型
js
//1. 可识别原始类型
'guo'.constructor === String; //true
(1).constructor === Number; //true
true.constructor === Boolean; //true
({}).constructor === Object; //true

//2. 可识别内置对象类型
new Date().constructor === Date; //true
[].constructor === Array; //true

//3. 可识别自定义类型
function People(x, y) {
  this.x = x;
  this.y = y;
}
var c = new People(2, 3);
c.constructor === People; //true

为了方便使用,使用函数封装如下:

js
function getConstructorName(obj) {
  return obj && obj.constructor && obj.constructor.toString().match(/function\s*([^(]*)/)[1];
}

getConstructorName(new Date()); //"Date"
getConstructorName(null); //null
getConstructorName(12); //"Number"

类型判断对比表

其中红色的单元格表示该判断方式不支持的类型。

类型判断对比表