原文: JavaScript Type Checking – How to Check Type in JS with typeof()
JavaScript 是一种动态类型(或松散类型)的编程语言。它允许你声明变量而不指定或定义变量类型。
你可以在 JavaScript 中创建一个变量,而不定义你可以存储在该变量中的值的类型。这可能会影响你的程序,并在运行时造成错误,因为类型可以改变。
例如,一个变量可以被声明并分配一个数字。但随着你写的代码越来越多,各个值可能会被放错位置,你可能会给同一个变量分配一个字符串或布尔值。这将在你的代码运行时造成影响:
let myVariable = 45; // => number
myVariable = 'John Doe'; // => string
myVariable = false; // => boolean
从上面的例子可以看出,JavaScript 中的变量可以在程序的整个执行过程中改变类型。作为一个程序员,这可能是很难掌握的。这就是为什么 TypeScript 被认为是 JavaScript 的超集的原因之一。
为了在 JavaScript 中通过检查变量的类型来验证变量,你可以使用 typeof
操作符。在 JavaScript 中,对于非基本数据类型和特定的值,类型检查是不直接的。这就是为什么类型检查会变得很烦人,特别是对于没有经验的 JS 开发者来说。
在这篇文章中,你将学习如何使用 typeof
操作符,在什么情况下你不应该使用 typeof
,以及在 JavaScript 中对这种情况进行类型检查的最佳方法。
JavaScript 数据类型
在 JavaScript 中,数据类型被分为两组:基本数据类型和非基本数据类型。除了对象是一个非基本数据类型外,其他都是基本数据类型。
这些数据类型包括:
- String 字符串
- Number 数值
- Boolean 布尔值(true and false 真和假)
- null
- undefined
- Symbol
你可能认为我省略了数组和函数。不是的,这是因为它们都是对象。
如何在 JavaScript 中用 typeof 运算符检查类型
typeof
运算符接受一个操作数(一个单数运算符),并确定操作数的类型。
有两种方法可以使用 typeof
运算符。你可以评估一个单一的值或一个表达式:
typeof(expression);
// 或者
typeof value;
typeof
操作符将返回类型为一个字符串,即 “number”、“string”、"boolean” 等等。
let myVariable = 45;
console.log(typeof myVariable); // 返回 "number"
console.log(typeof(myVariable)); // 返回 "number"
console.log(typeof 45); // 返回 "number"
console.log(typeof(45)); // 返回 "number"
重要的是要知道,在评估一个表达式而不是一个单一的值时,你应该总是使用表达式方法(以函数的形式),比如说:
console.log(typeof(typeof 45)); // 返回 "string"
上面返回的是一个字符串,因为 typeof 45
的输出为 “number”(它被返回为字符串),然后 typeof("number")
的输出为 “string”。
另一个例子是,如果你的数字里有一个连字符:
// 使用表达式
console.log(typeof(123-4567-890)); // 返回 "number"
// 使用一个值
console.log(typeof 123-4567-890); // 返回 NaN
一个值的方法将返回 NaN
(不是一个数字),因为它首先会评估 typeof 123
,这将返回一个字符串,“number”。这意味着你现在只剩下 "number" - 4567-890
,它不能被减去,将返回 NaN
。
如何检查数值数据类型
现在让我们来探讨一下将返回数值数据类型的可能实例。
在 JavaScript 中,数值可能有不同的值,比如正负整数、零、浮点数和无穷大:
console.log(typeof 33); // 返回 "number"
console.log(typeof -23); // 返回 "number"
console.log(typeof 0); // 返回 "number"
console.log(typeof 1.2345); // 返回 "number"
console.log(typeof Infinity); // 返回 "number"
另一点也很重要,像 NaN 这样的值,尽管它意味着 Not-a-Number(不是一个数字),但总是会返回一个 “number” 的类型。此外,数学函数的数据类型也是数字:
console.log(typeof NaN); // 返回 "number"
console.log(typeof Math.LOG2E); // 返回 "number"
最后,当你使用 Number()
构造函数将一个含有数字的字符串显式地类型转换为一个数字,甚至是一个不能类型转换为整数的字符串这样的值,它将总是返回一个数字作为其数据类型:
// 类型转换一个值为数值
console.log(typeof Number(`123`)); // 返回 "number"
// 不能类型转换为整数的值
console.log(typeof Number(`freeCodeCamp`)); // 返回 "number"
最后,当你使用 parseInt()
和 parseFloat()
等方法将字符串转换为数字,并将数字四舍五入时,其数据类型将是 number:
console.log(typeof parseInt(`123`)); // 返回 "number"
console.log(typeof parseFloat(`123.456`)); // 返回 "number"
如何检查字符串数据类型
只有少数情况下会返回 “string”。这些实例是空字符串、一串字符(这也可以是一个数字)和多个单词:
console.log(typeof ''); // 返回 "string"
console.log(typeof 'freeCodeCamp'); // 返回 "string"
console.log(typeof 'freeCodeCamp offers the best free resources'); // 返回 "string"
console.log(typeof '123'); // 返回 "string"
另外,当你对任何值使用 String()
构造函数时:
console.log(typeof String(123)); // 返回 "string"
如何检查布尔值数据类型
当你检查 true
和 false
值时,它总是返回布尔值类型。另外,当你检查任何使用 Boolean()
构造函数的数据时:
console.log(typeof true); // 返回 "boolean"
console.log(typeof false); // 返回 "boolean"
console.log(typeof Boolean(0)); // 返回 "boolean"
此外,当你使用双非运算符(!!
)时,它的作用与 Boolean()
构造函数一样,将返回 “boolean”。
console.log(typeof !!(0)); // 返回 "boolean"
如何检查 Symbol 数据类型
当你使用 Symbol()
构造函数时,即使没有传递值,也会返回 “symbol” 数据类型。另外,当你传入一个参数或使用 Symbol.iterator
时,它指定了一个对象的默认迭代器。
console.log(typeof Symbol()); // 返回 "symbol"
console.log(typeof Symbol('parameter')); // 返回 "symbol"
console.log(typeof Symbol.iterator); // 返回 "symbol"
如何检查 Undefined 数据类型
当你声明一个变量而没有给它赋一个值时,就表明它是 undefined
。当你检查 undefined、没有值的变量(未定义)和未定义的变量时,它们总是会返回 “undefined”。
// 使用 undefined 关键字
console.log(typeof undefined); // 返回 "undefined"
//声明了一个变量,但是未定义(故意不给它赋值)
let a;
console.log(typeof a); // 返回 "undefined"
// 使用 undefined 变量
console.log(typeof v); // 返回 "undefined"
到目前为止,你已经学会了如何检查除 null 以外的所有基本数据类型的类型。这有点复杂,我在《JavaScript 中的空值检查详解》一文中详细介绍过。
但我将在这篇文章中简要地介绍一下如何检查 null
,以便你能理解基础知识。
如何检查 Object 数据类型
某些实例将总是返回 “object”,尽管 null
的情况是一个无法修复的历史 bug,而函数有其技术原因。
console.log(typeof null);
console.log(typeof [1, 2, 3, "freeCodeCamp"]);
console.log(typeof { age: 12, name: "John Doe" });
console.log(typeof [1, 2, 3, 4, 5, 6]);
正如你在上面的例子中所看到的,当你使用 typeof
操作时,数组将总是返回 “object”。这可能不是很令人愉快,但从技术上讲,数组是一种特殊的对象类型:
console.log(typeof [1, 2, 3, 'freeCodeCamp']);
在 ES6 中,Array.isArray
方法被引入,这使得你有可能轻松地检测到一个数组:
console.log(Array.isArray([1, 2, 3, "freeCodeCamp"])); // 返回 true
console.log(Array.isArray({ age: 12, name: "John Doe" })); // 返回 false
另外,在引入 ES6 之前,instanceof
操作符被用来检测一个数组:
const isArray = (input) => {
return input instanceof Array;
};
console.log(isArray([1, 2, 3, 'freeCodeCamp'])); // 返回 true
如何检查 Null 数据类型
当你使用 typeof
操作符检查 null
值时,由于一个无法修复的历史 bug,它返回 “object”。
注意:不要将 null 与 undefined 混淆。如果一个变量有意包含 null
的值,它就被称为 null
。相反,当你声明一个变量而没有赋给它一个值时,它就是 undefined
。
检测 null
的一个非常直接的方法是使用严格比较法:
const isNull = (input) => {
return input === null;
}
let myVar = null;
console.log(isNull(myVar)); // 返回 true
你可以阅读这篇文章《检查 JavaScript 中的 null 值》,了解更多的选项和详细的解释。
JavaScript 中类型检查的通用解决方案
在 Tapas Adhikary 之前的一篇文章《如何在 JS 中检查变量或对象的类型》中,他补充并解释了一个通用的解决方案,你可以用它来更准确地检查类型:
const typeCheck = (value) => {
const return_value = Object.prototype.toString.call(value);
const type = return_value.substring(
return_value.indexOf(" ") + 1,
return_value.indexOf("]")
);
return type.toLowerCase();
};
让我们来测试一下:
console.log(typeCheck([])); // 返回 'array'
console.log(typeCheck(new Date())); // 返回 'date'
console.log(typeCheck(new String("freeCodeCamp"))); // 返回 'string'
console.log(typeCheck(new Boolean(true))); // 返回 'boolean'
console.log(typeCheck(null)); // 返回 'null'
总结
在这篇文章中,你已经学会了如何用 typeof
操作符检查 JavaScript 中的类型。
你还了解了一些限制,以及如何使用其他方法来克服这些限制。请记住,对于大多数基本数据类型,你总是可以使用 typeof
操作符。
Have fun coding!