JavaScript:类型判断与类型转换

157 阅读2分钟

JS中数据类型

  • 原始类型:(六种)boolean、number、string、null、undefined以及ES6提出的symbol。(注意首字母都是小写的)
  • 引用类型:普通对象、数组、函数(数组和函数其实也是对象)

类型判断

typeof运算符

返回七种类型的字符串(undefined/number/string/boolean/symbol/object/function),可以区别函数和普通对象,但是没有办法区分null和普通对象

  1. 经常会用if(typeof window === 'undefined')判断是否在浏览器环境下
  2. typeof null 返回object,这是javascript的一个远旧的问题,null并不是引用类型,依旧是原始类型
  3. typeof func 返回function,不是object
  4. typeof Symbol(1)返回symbol,Symbol不是一个完整构造函数,不支持new Symbol(11)的语法。Symbol(1)是一个原始类型,但在调用它的proto时会有一个如下的自动装箱
const a = new String('a')
const b = Symbol('a')
a.__proto__.__proto__===b.__proto__.__proto__ // true
const [a1, b1, c1, d1, e1, f1, g1] = [undefined, null, false, NaN, "abc", {}, Symbol()];
console.log(typeof a1); // undefined
console.log(typeof b1); // object
console.log(typeof c1); // boolean
console.log(typeof d1); // number
console.log(typeof e1); // string
console.log(typeof f1); // object
console.log(typeof g1); // symbol

const h1 = function () {};
console.log(typeof h1); // function

const [i1, j1, l1, m1, n1] = [new Date(), /\s/, Math.sign, Math.PI, []];
console.log(typeof i1); // object
console.log(typeof j1); // object
console.log(typeof l1); // function
console.log(typeof m1); // number
console.log(typeof n1); // object
  1. 当实例化一个原始类型的包装类型,返回值时object
const a2 = new Boolean(false);
const b2 = new Number(25);
const c2 = new String('abc');
console.log(typeof a2); // object
console.log(typeof b2); // object
console.log(typeof c2); // object

const d2 = new Function('a', 'b', 'return a + b');
console.log(typeof d2); // function

Object.prototype.toString

toString这个方法是Object.prototype上的一个属性,任何对象的原型链的底部都是Object.prototype,应该可以直接调用(原始类型去调用时会自动装箱成对应的对象),但由于不同的对象构造函数对toString方法进行了重写,所以使用Object.prototype.toString.call(target)去判断。 原始类型:

Object.prototype.toString.call(999) // "[object Number]"
Object.prototype.toString.call('') // "[object String]"
Object.prototype.toString.call(Symbol()) // "[object Symbol]"
Object.prototype.toString.call(42n) // "[object BigInt]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(true) // "[object Boolean]

引用类型(只能返回内置的类型)

Object.prototype.toString.call({a:1}) // "[object Object]"
Object.prototype.toString.call([1,2]) // "[object Array]"
Object.prototype.toString.call(new Date) // "[object Date]"
Object.prototype.toString.call(function(){}) // "[object Function]"
function Person(){}
const p = new Perosn()
Object.prototype.toString.call(p) // "[object Object]"

instanceof

targetObj instanceof Function 目标对象是否是构造函数的一个实例,不仅可以用于判断内置的类型,还可以判断自定义的构造函数。

只能用于判断引用类型,原始类型会返回false。

[1,2] instanceof Array  // true
(function(){}) instanceof Function // true
({a:1}) instanceof Object // true
(new Date()) instanceof Date // true

function Person(){};
const k = new Person();
k instanceof Person; // true

1 instanceof Number // false

实现一个instance函数

const Instance = (target, fun) => {
  const p = fun.prototype
  const t = target.__proto__
  while (t) {
    if (t === p) {
      return true
    }
    t = t.__proto__
  }
  return false
}

类型转换