类型检测
typeof
因为 ECMAScript
的类型系统是松散的,所以需要一种手段来确定任意变量的数据类型。因此,ECMAScript提供了一个可以查看值类型的运算符:typeof
,它返回的是类型的字符串值。
JavaScript中的变量是没有类型的,只有值才有。变量可以随时持有任何类型的值。在对变量执行 typeof操作时,得到的结果并不是该变量的类型,而是该变量持有的值的类型,因为 JavaScript中变量是没有类型的。
变量在未持有值的时候为 undefined
1let a;
2typeof a; // undefined
对一个值使用 typeof
会返回下列字符串之一:
返回值 |
含义 |
undefined |
表示值未定义 |
boolean |
表示值为布尔值 |
string |
表示值为字符串 |
number |
表示值为数值 |
object |
表示值为对象 |
function |
表示值为函数 |
symbol |
表示值为符号 |
typeof
是一个操作符而不是函数,所以它的写法和函数有所不同。它直接跟在你想要检测的变量之前,而不是像函数那样使用括号。
1// 简单数据类型
2let num = 123;
3console.log(typeof num); // number
4
5let str = "Hello";
6console.log(typeof str); // string
7
8let bool = true;
9console.log(typeof bool); // boolean
10
11let nul = null;
12console.log(typeof nul); // object
13
14let und = undefined;
15console.log(typeof und); // undefined
16
17let sym = Symbol();
18console.log(typeof sym); // symbol
19
20// 复杂数据类型
21let obj = {};
22console.log(typeof obj); // object
23
24let arr = [];
25console.log(typeof arr); // object
26
27let fun = function () {};
28console.log(typeof fun); // function
需要注意的是,typeof
对于 null 和 数组的检测会返回 object
,这是 JavaScript 的一个历史遗留问题。如果你需要更加准确地检测这些类型,可能需要使用其他方法,例如 :
null 是 “假值”(falsy或者falsy-like),也是唯一一个用 typeof
检测会返回 object
的基本类型。
1// 使用 Array.isArray() 来检测数组
2let arr = [];
3console.log(Array.isArray(arr)); // true
4
5// 对于 null 的检测,你可以直接使用 === 来判断
6// 这里需要注意的是,如果你使用 == 来比较,那么 null 和 undefined 会被认为是相等的
7let nul = null;
8console.log(nul === null); // true
9console.log(!nul && typeof nul === 'object'); // true
function 实际上是 object 的一个子类型。函数是“可调用对象”,它有一个内部属性 [[Call]]
,该属性使其可以被调用。
数组也是 object 的一个子类型,数组的元素按数字顺序来进行索引(而非像普通对象那样通过字符串键值),其length属性是元素的个数。
然而,尽管 typeof
不是函数,但你仍然可以在它后面使用括号。这样并不影响结果,这些括号只是用于改变运算优先级或者提高代码可读性。例如:
1let num = 123;
2console.log(typeof(num)); // number
3
4let str = "Hello";
5console.log(typeof(str)); // string
instanceof
1function Foo() {}
2const a = new Foo();
3
4console.log(a instanceof Foo); // true
instanceof
操作符左操作数是一个普通对象,右操作数是一个函数。
instanceof
回答的问题是:在 a 的整条 [[prototype]]
链中是否有 Foo.prototype
指向的对象?
instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。
也可以理解为是否为某个对象的实例,typeof
不能区分数组,但 instanceof
则可以。
值类型与对象
下面是使用字面量与对象方法创建字符串,返回的是不同类型。
1let name1 = "xiaosutongxue";
2let name2 = new String("xstx");
3console.log(typeof name1, typeof name2); //string object
只有对象才有方法使用,但在JS
中也可以使用值类型调用方法,因为它会在执行时将值类型转为对象。
1let name1 = "xiaosutongxue";
2let name2 = new String("xstx");
3console.log(name1.length); //13
4console.log(name2.length); //4