js基石之数据类型二:类型判断

110 阅读2分钟

相关文章

js基石之数据类型一:类型分类&区别
js基石之数据类型二:类型判断
js基石之数据类型三:类型转换
js基石之Number:本质
js基石之Number:应用(数字运算,数字&字符串转换,不同进制表示&相互转换)
js基石之字符: ASCII,GBK,Unicode,utf-32,utf-16,utf-8,encodeuri,encodeuricomponent,base64
js基石之Symbol值
js基石之Object,Map,WeakMap
js基石之Array,Stack,Queue,Set,WeakSet

类型判断

曾经的王者Object.prototype.toString

console.log(Object.prototype.toString.call('hello')); // 输出 "[object String]"
console.log(Object.prototype.toString.call([1, 2, 3])); // 输出 "[object Array]"
console.log(Object.prototype.toString.call({x: 1})); // 输出 "[object Object]"
console.log(Object.prototype.toString.call(null)); // 输出 "[object Null]"
console.log(Object.prototype.toString.call(undefined)); // 输出 "[object Undefined]"
console.log(Object.prototype.toString.call(function())); // 输出 "[object Function]"

Object.prototype.toString本质是使用 Symbol.toStringTag 来判断的

const obj = {
    get [Symbol.toStringTag](){
        return 'type' // 一个自定义类型
    }
};
Object.prototype.toString.call(obj)
// '[object type]'

所以现在Object.prototype.toString也是不准确的了 因为可以被改变

Array.prototype[Symbol.toStringTag] = 'string';
Object.prototype.toString.call([]) // '[object String]' 成功的将数组改变为字符串
Array.isArray([]) // true 依然可以判断出数组 所以数组优先使用官方的方法吧。
Number.prototype[Symbol.toStringTag] = 'String';
let a = 12;
Object.prototype.toString.call(a)  // '[object String]'成功的将数字改变为字符串
typeof a // number 准确的

typeof:检测基础数据类型和函数

console.log(typeof 'hello'); // 输出 "string"
console.log(typeof 123); // 输出 "number"
console.log(typeof true); // 输出 "boolean"
console.log(typeof Symbol('symbol')); // 输出 "symbol"
console.log(typeof BigInt(1)); //输出 bigint
console.log(typeof undefined); // 输出 "undefined"
console.log(typeof null); // 输出 "object"
console.log(typeof {x: 1}); // 输出 "object"
console.log(typeof [1, 2, 3]); // 输出 "object"
console.log(typeof function(){}); // 输出 "function"

严格等值比较:与固定值进行比较

console.log(null === null) // true
console.log(undefined === undefined) // true
console.log(null === undefined) // false

constructor:指向实例构造函数 可以被改变 一般不用

console.log([1, 2, 3].constructor === Array); // 输出 true
console.log({x: 1}.constructor === Object); // 输出 true
console.log('hello'.constructor === String); // 输出 true

class Person{}
class Student extends Person{}
const p = new Person();
const stu = new Student();
p.constructor === Person // true
stu.constructor === Student // true
stu.constructor === Person // false

instanceof:沿着原型链去找

class Person{}
class Student extends Person{}
const p = new Person();
const stu = new Student();
p instanceof Person // true
stu instanceof Student // true
stu instanceof Person // true

Array.isArray:检测数组的首选

Array.prototype[Symbol.toStringTag] = 'string';
Object.prototype.toString.call([]) // '[object String]' 成功的将数组改变为字符串
Array.isArray([]) // true 依然可以判断出数组 所以数组优先使用官方的方法吧。

Number.isNaN:

Number.isNaN(NaN) // true
Number.isNaN(12) // false

总结:没一个靠谱的

所以类型判断到底要如何做!我只是想判断个类型啊~

  1. 术业有专攻 有为了某个类型专门提供的api 优先使用该api 例如 Array.isArray Number.isNaN
  2. 能比较值的优先比较值 null === null,undefined === undefined
  3. 优先使用操作符 typeof

所以还是要根据场景自己实现一个函数来判断。

// 获取具体的类型
const getType = (p)=>{ 
    if(Array.isArray(p)){
       return 'array' 
    }
    if(Number.isNaN(p)){
        return 'NaN' 
    }
    if(p === null){
        return 'null'
    }
    if(p === undefined){
        return 'undefined'
    }
    return typeof p;
};

// 判断是否是原始类型 原始类型返回true 对象返回false
 function isPrimitive(value){
    return value !== Object(value);
  }

参考

  1. javaScript 数据类型和数据结构
  2. 细说 JavaScript 七种数据类型 
  3. 数据类型
  4. 引用类型转换原始类型