JavaSctipt 语言类型和类型检测

内置类型

JavaScript目前有八种内置类型(包含ES6symbol):

  • null
  • undefined
  • string
  • number
  • boolean
  • object
  • symbol
  • BigInt

检测类型

目前我们常见的数据类型的检测方式有typeofObject.prototype.toStringinstanceofconstructor,它们之间在实际场景的使用中各有优劣,下面我们就来介绍一下它们吧。

typeof

typeof运算符可以用来检测数据的类型,它始终返回值类型的字符串。比较有意思的是,这些类型和它们的字符串值并不是一一对应的:

console.log(typeof undefined)  // 打印 "undefined"
console.log(typeof ' ')        // 打印 "string"  
console.log(typeof 123)        // 打印"number"
console.log(typeof true)       // 打印"boolean"
console.log(typeof {})         // 打印"object"
console.log(typeof Symbol())   // 打印"symbol"
// BigInt
console.log(typeof 9007199254740995n) // 打印"bigint"

以上六种类型均与其字符串值相同,只有null类型不在此列,null的字符串值是object,这也是语言建立初期存在的一个bug。

typeof null === 'object'; // true

还有一种情况,function函数是属于object的一个子类型,但是其字符串值确实function

typeof function () {} === 'function'; // true

以及还有Array也是输入引用类型,返回也是object.

typeof [] === 'object'

Object.prototype.toString

Object.prototype.toString用来返回一个表示该对象的字符串,这也是开发中比较常用的,也比较全面的检测数据类型的方式,下面我们就来看看。

var toString = Object.prototype.toString
console.log(toString.call(null))  // [object Null]
console.log(toString.call(undefined))  // [object Undefined]
console.log(toString.call(''))  // [object String]
console.log(toString.call(123))  // [object Number]
console.log(toString.call(true))  // [object Boolean]
console.log(toString.call([]))  // [object Array]
console.log(toString.call({}))  // [object Object]
console.log(toString.call(function(){}))  // [object Function]
console.log(toString.call(Symbol()))  // [object Symbol]
console.log(toString.call(9007199254740995n))  //[object BigInt]

instanceof

instanceof 运算符用于测试构造函数的 prototype 属性是否出现在对象的原型链中的任何位置。

[1] instanceof Array; // true
[1] instanceof Object; // true
"tom" instanceof String; //false
11 instanceof Number; //false

instanceof运算符直接访问的变量的原始值,不会自动建立包装类。因此不能用来判断基本类型值。

instanceof只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪种类型。

instanceof假定只有一个全局执行环境。如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的构造函数。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个框架中原生创建的数组分别具有各自不同的构造函数

constructor

console.log(("1").constructor === String);
console.log((1).constructor === Number);
console.log((true).constructor === Boolean);
//console.log((null).constructor === Null);
//console.log((undefined).constructor === Undefined);
console.log(([]).constructor === Array);
console.log((function() {}).constructor === Function);
console.log(({}).constructor === Object);
// 打印
都是 true

(这里依然抛开nullundefined)乍一看,constructor似乎完全可以应对基本数据类型和引用数据类型,都能检测出数据类型,事实上并不是如此,来看看为什么:

function Fn(){};

Fn.prototype=new Array();

var f=new Fn();

console.log(f.constructor===Fn);  // false
console.log(f.constructor===Array); // true

我声明了一个构造函数,并且把他的原型指向了Array的原型,所以这种情况下,constructor也显得力不从心了。
所以数据类型检测中还是Object.prototype.toString表现最优秀

其他

undefined 和 undeclared

变量在声明后并没有初始化值时,默认值为undefined

var a;
typeof a; // 'undefined'

没有在作用域中声明过的变量,是undeclared,但是typeof一个未声明的值却是'undefined',这也是typeof的一个安全机制

var a;
a; // undefined
b; // b is not defined

typeof a; // 'undefined'
typeof b; // 'undefined'

小结

JavaScript有八种内置类型:
nullundefinedbooleanstringnumberobjectsymbolBigInt
通过typeof检测nullarray,返回的是object,typeof检测function返回的是function
了解Object.prototype.toString的使用
已声明未赋值(undefined)和未声明未赋值(undeclared)

你可能感兴趣的:(JavaSctipt 语言类型和类型检测)