知道一段数据的类型是什么,往往对代码能否顺利运行、不出错非常重要。
JavaScript 有几种方法可以检查一个值或对象的类型。
JavaScript 的类型检查机制有时并不太可靠。
如果想要更好的类型安全性和更强的类型,你或许应该使用 TypeScript。它构建在 JavaScript 之上,但采用静态类型语言的类型语法。
typeof运算符typeof运算符会返回其操作数的类型。
输出是一个字符串,与某个原始数据类型的名称相同,"null"除外。
它也可能是"function"或"object"。
typeof undefined;
// => "undefined"
typeof true;
// => "boolean"
typeof 42;
// => "number"
typeof 'Hello, World!';
// => "string"
typeof function () {
return 'Hello, World';
};
// => "function"
typeof [1, 2, 3, 4];
// => "object"
typeof { city: 'Stockholm', country: 'Sweden' };
// => "object"
这是出于[历史原因][typeof null is "object"]。
instanceof运算符要检查一个对象的类型,可以使用instanceof运算符。
它会根据第二个操作数是否位于第一个操作数的原型链中,求值为一个boolean。
具体来说,instanceof会返回第一个操作数是否为第二个操作数或其某个子类的实例。
instanceof只对对象有效。
class Beverage {
// ...
}
// The Coffee class is a child of the Beverage class.
class Coffee extends Beverage {
// ...
}
const java = new Coffee();
java instanceof Coffee;
// => true
java instanceof Beverage;
// => true
Array类有一个名为Array.isArray()的方法,用来检查它的实参是不是数组。
对于在别的 realm 中创建的数组,比如网页里的一个iframe,instanceof Array不起作用,而Array.isArray()可以。
这是因为Array类在每个 realm 中都有不同的构造函数,而每个iframe都有自己独立的 realm,也就是说原型链中的函数会不一样,从而导致instanceof Array判断失败。
Array.isArray()能够忽略这一点,因此只要可能就应该使用它。
它还能避开这类误报:某个对象其实并不是Array,只是它的原型链里有Array。
({ __proto__: Array.prototype }) instanceof Array
// => true
Array.isArray({ __proto__: Array.prototype })
// => false
in运算符in运算符会返回第一个操作数是不是第二个操作数的属性。
它不会检查该属性是否有定义的值。
即使某个属性被设为undefined,in依然能检测到它。
class Coffee {
constructor() {
this.temperature = 'hot';
this.isDarkMatter = undefined;
}
coolDown() {
this.temperature = 'warm';
}
}
const espresso = new Coffee();
'temperature' in espresso;
// => true
'color' in espresso;
// => false
'isDarkMatter' in espresso;
// => true
in对继承来的属性和方法也会返回true。
"coolDown" in espresso
// => true
"constructor" in espresso
// => true
想避免这种情况,请改用Object.hasOwn()。
Object.hasOwn()函数Object.hasOwn()方法会返回指定的对象是否_自身拥有给定的属性_(该属性不是继承来的,也不是方法)。
class Coffee {
constructor() {
this.temperature = 'hot';
}
coolDown() {
this.temperature = 'warm';
}
}
const cappuccino = new Coffee();
Object.hasOwn(cappucino, 'temperature');
// => true
Object.hasOwn(cappucino, 'constructor');
// => false
Object.hasOwn(cappucino, 'coolDown');
// => false