关于javascript的数据类型判断

一. jsvascript中的数据类型

  1. 原始类型:Boolean,string,number,null,undefined,symbol,BigInt(可以用任 精度表示整数)

特殊:

  • symbol:

ES6新增,表示独一无二的值,数据类型 “symbol” 是一种原始数据类型,该类型的性质在于这个类型的值可以用来创建匿名的对象属性。该数据类型通常被用作一个对象属性的键值——当你想让它是私有的时候。一个具有数据类型 “symbol” 的值可以被称为 “符号类型值”。在 JavaScript 运行时环境中,一个符号类型值可以通过调用函数 Symbol() 创建,这个函数动态地生成了一个匿名,唯一的值。Symbol类型唯一合理的用法是用变量存储 symbol的值,然后使用存储的值创建对象属性。

  • BigInt:

可以用任意精度表示整数。使用 BigInt,您可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。BigInt是通过在整数末尾附加 n 或调用构造函数来创建的。

  1. 引用类型(对象类型):对象类型包括:数组(Array)、函数(Function)、还有两个特殊的对象:正则(RegExp)和日期(Date)。

二.判断数据类型

1. typeof

console.log(typeof 2)//number
console.log(typeof true)//boolean
console.log(typeof 'str')//string
console.log(typeof [])   //object
console.log(typeof function(){
    
    })//function
console.log(typeof {
    
    })    //object
console.log(typeof undefined)//undefined
console.log(typeof null)//object
const bar = Symbol()
console.log(typeof bar )//symbol
const x = 2n ** 53n//BigInt类型
console.log(typeof x)//bigint
const y = typeof x
console.log(typeof y)//string

总结:

  • typeof可以返回的值有:number,string,undefined,Boolean,object,function,symbol,bigint
  • typeof返回的结果都是string类型

2. instanceof

上面的typeof检测数组和对象都是返回"object",因此我们不能做精确的判断引用类型的数据类型,对null也是不能准确判断

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

模拟instanceof的内部执行:当 A 的 proto 指向 B 的 prototype 时,就认为A就是B的实例

instanceof (A,B) = {
    
    
    var L = A.__proto__;
    var R = B.prototype;
    if(L === R) {
    
    
        //A的内部属性__proto__指向B的原型对象
        return true;
    }
    return false;
}


例如

function Car(make, model, year) {
    
    
  this.make = make;
  this.model = model;
  this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);

console.log(auto instanceof Car);
// expected output: true

console.log(auto instanceof Object);
// expected output: true

用来检测数据类型

console.log(2 instanceof Number);      //false
console.log(true instanceof Boolean);   //false
console.log("str" instanceof String);   //false
console.log([] instanceof Array);       //true
console.log([] instanceof Object)    //true
console.log(function(){
    
    } instanceof Function);//true
console.log({
    
    } instanceof Object)    //true
console.log(null instanceof Object) //false
//通过实例构造函数得到的值是原始类型也是可以使用instanceof判断数据类型
var bool2 = new Boolean()
console.log(bool2 instanceof Boolean);// true
var num2 = new Number()
console.log(num2 instanceof Number);// true
var str2 = new String()
console.log(str2 instanceof String);//  true

总结:

  • instanceof不能区别undefined和null
  • 而且对于基本类型如果不是用new声明的则也测试不出来,通过实例构造函数得到的值是原始类型也是可以使用instanceof判断数据类型
  • 对于是使用new声明的类型,它还可以检测出多层继承关系,如检测数组时:虽然 instanceof 能够判断出 [] 是Array的实例,但它认为 [] 也是Object的实例,这是由于原型链的特点

在这里插入图片描述

3. constructor

constructor属性的作用是,可以得知某个实例对象,到底是哪一个构造函数产生的。

console.log((2).constructor === Number);      //true
console.log((true).constructor === Boolean);   //true
console.log(("str").constructor === String);   //true
console.log(([]).constructor === Array);       //true
console.log(([]).constructor===Object );       //false
console.log((function(){
    
    }).constructor === Function);//true
console.log(({
    
    }).constructor === Object)    //true

但是,在开发当中constructor是可以被重写的

function Fn(){
    
    }
Fn.prototype = new Array(); //prototype==原型
var f = new Fn();
console.log(f.constructor === Fn)//false
console.log(f.constructor === Array)//true

总结:

  • constructor是可以被重写的,重写后判断不准确
  • undefined和null没有contructor属性,constructor不能判断undefined和null

4. Object.prototype.toString.call ***

toString是Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,更严格的讲,是 toString运行时this指向的对象类型, 返回的类型格式为[object,xxx],xxx是具体的数据类型

console.log(Object.prototype.toString.call('')) ;   // [object String]
console.log(Object.prototype.toString.call(2)) ;    // [object Number]
console.log(Object.prototype.toString.call(true)) ; // [object Boolean]
console.log(Object.prototype.toString.call(undefined)) ; // [object Undefined]
console.log(Object.prototype.toString.call(null)) ; // [object Null]
console.log(Object.prototype.toString.call(new Function())) ; // [object Function]
console.log(Object.prototype.toString.call(new Date())) ; // [object Date]
console.log(Object.prototype.toString.call([])) ; // [object Array]
console.log(Object.prototype.toString.call(new RegExp()) ); // [object RegExp]
console.log(Object.prototype.toString.call(new Error())) ; // [object Error]
console.log(Object.prototype.toString.call(window) ); //[object Window]
console.log(Object.prototype.toString.call( Symbol()))//[object Symbol]
console.log(Object.prototype.toString.call( 3n))//[object BigInt]

总结:

  • String,Number,Boolean,Undefined,Symbol,Null,Function,BigInt,Date,Array,RegExp,Error,HTMLDocument,… 基本上所有对象的类型都可以通过这个方法获取到。
  • 必须通过Object.prototype.toString.call来获取,而不能直接 new Date().toString(), 从原型链的角度讲,所有对象的原型链最终都指向了Object, 按照JS变量查找规则,其他对象应该也可以直接访问到Object的toString方法,而事实上,大部分的对象都实现了自身的toString方法,这样就可能会导致Object的toString被终止查找,因此要用call来强制执行Object的toString方法。

猜你喜欢

转载自blog.csdn.net/pz1021/article/details/105177939