1.使用typeof
console.log(typeof 7); //number
console.log(typeof 'JavaScript'); //string
console.log(typeof true); //boolean
console.log(typeof {}); //object
console.log(typeof undefined); //undefined
const bigIntValue = 1234567890123456789012345678901234567890n;
console.log(typeof bigIntValue); //bigint
const mySymbol = Symbol("description");
console.log(typeof mySymbol); // symbol
上面已经包含了八个类型中的number,string,boolean,object,undefined,bigint,symbol这七个,你可能会感到好奇,那为什么没有null呢?
这就不得不提及一个JavaScript的历史遗留问题了:
JavaScript 中的
null
值被错误地归类为"object"
类型,而不是自己的类型。这个问题源自 JavaScript 最早的实现,并为了保持向后兼容性而一直保留下来
由于这个历史遗留问题,当我们使用typeof时会产生如下效果
console.log(typeof null); //object
那么如果要检查一个变量是否为 null
,你可以直接比较它与 null
值,例如:
const myValue = null;
if (myValue === null) {
console.log("myValue is null");
} else {
console.log("myValue is not null");
}
除此之外,数组如果使用typeof
也会被判断为"object"
,这是因为JavaScript 最初设计时,数组实际上就是对象的一种形式,它们可以包含属性和方法。这使得数组在 JavaScript 中非常灵活,可以像对象一样扩展属性。然而,随着 JavaScript 的发展,数组的行为和优化逐渐发生了变化,但为了保持向后兼容性,typeof
运算符仍然返回 "object"
,因为数组被视为对象的一种特殊情况。
除了识别基础数据类型,typeof
还有一种用于识别函数类型的特殊情况,当其返回为"function"
时,表明检查的值是一个函数类型。
2.使用instanceof
instanceof 可以正确判断对象的类型,其内部运行机制是判断在其原型链中能否找到该类型的原型。
console.log(7 instanceof Number); //false
console.log(true instanceof Boolean); //false
console.log([] instanceof Array); //true
console.log({} instanceof Object); //true
由此可见,instanceof
运算符是用于检查对象的构造函数(constructor)是否在其原型链上的一部分的 JavaScript 运算符。它用于确定一个对象是否是某个特定类或构造函数的实例,而对于基本数据类型是无法判断的。
JavaScript中的基础类型
- 数字(Number)
- 字符串(String)
- 布尔值(Boolean)
- 未定义(Undefined)
- 空值(Null)
- 大整数(BigInt)(ECMAScript 11引入)
- 符号(Symbol)(ECMAScript 6引入)
需要注意的是,JavaScript 中的函数(function)和数组(array)都是是 Object
的实例,因此 function instanceof Object
和array instanceof Object
会返回 true
。这是因为函数在 JavaScript 中也是对象的一种特殊形式,具有属性和方法,因此它们继承了 Object
的特性。
3.使用constructor
constructor 有两个作用,一是判断数据的类型,二是对象实例通过constrcutor 对象访问它的构造函数。
console.log((7).constructor === Number); //true
console.log(([]).constructor === Array); //true
需要注意,如果创建一个对象来改变它的原型,constructor 就不能用来判断数据类型了:
function F(){};
F.prototype = new Array();
var f = new Fn();
console.log(f.constructor === F); //false
console.log(f.constructor === Array); //true
4.使用Object.prototype.toString.call()
Object.prototype.toString.call() 使用 Object 对象的原型方法toString 来判断数据类型:
var a = Object.prototype.toString;
console.log(a.call(2)); //[object Number]
console.log(a.call(true)); //[object Boolean]
Object.prototype.toString
方法通常用于获取对象的类型,它返回一个表示对象类型的字符串。
那么,同样是检测对象 obj 调用 toString
方法,为什么会有obj.toString()
的结果和
Object.prototype.toString.call(obj)
的结果不一样这种情况出现呢
这是因为 toString 是 Object 的原型方法,而 Array、function 等类型作为 Object 的实例,都重写了 toString 方法。不同的对象类型调用 toString 方法时,根据原型链的知识,调用的是对应的重写之后的 toString 方法(function 类型返回内容为函数体的字符串,Array
类型返回元素组成的字符串…),而不会去调用 Object 上原型toString 方法(返回对象的具体类型),所以采用 obj.toString()不能得到其对象类型,只能将 obj 转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用 Object 原型上的 toString 方法。