内置类型
JavaScript
目前有八种内置类型(包含ES6
的symbol
):
null
undefined
string
number
boolean
object
symbol
BigInt
检测类型
目前我们常见的数据类型的检测方式有typeof
、Object.prototype.toString
、instanceof
、constructor
,它们之间在实际场景的使用中各有优劣,下面我们就来介绍一下它们吧。
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
(这里依然抛开null
和undefined
)乍一看,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有八种内置类型:
null
、undefined
、boolean
、string
、number
、object
、symbol
、BigInt
。
通过typeof
检测null
、array
,返回的是object
,typeof
检测function
返回的是function
。
了解Object.prototype.toString
的使用
已声明未赋值(undefined
)和未声明未赋值(undeclared
)