js共有7种内置类型:数组
除对象外,其余统称为“基本类型”浏览器
咱们可用typeof来查看值的类型:安全
typeof undefined === "undefined"; // true
typeof true === "boolean"; // true
typeof 42 === "number"; // true
typeof "42" === "string"; // true
typeof { life: 42 } === "object"; // true
// ES6新增类型
typeof Symbol() === "symbol"; // true
复制代码
null比较特殊,typeof对它处理有问题:bash
typeof null === "object"; // true
复制代码
正确结果应该返回null,但这个bug由来已久,在js中已经存在了将近20年,因为牵涉到太多的Web系统,“修复”它会产生更多的bug,令许多系统没法修复。函数
咱们须要使用符合条件来检测null的类型:spa
var a = null;
(!a && typeof a === "object"); // true
复制代码
null是假值,也是惟一一个用typeof检测会返回“object”的基本类型code
还有一种状况:对象
typeof function a() { /*...*/ } === "function"; // true
复制代码
function也是js的一个内置函数。其实是object的一个“子类型”。具体来讲,函数是“可调用对象”,它有一个内部属性[[Call]],该属性使其能够被调用。索引
函数不只是对象,还能够拥有属性。如:作用域
function a(b, c) {
/*..*/
}
复制代码
函数对象的length属性是其声明的参数的个数:
a.length; // 2
复制代码
该函数声明了两个命名参数,b、c,因此其length值为2
typeof [1, 2, 3] === "object"; // true
复制代码
数组也是对象,确切的说是object的一个“子类型”,数组的元素按数字顺序来进行索引,其length属性是元素的个数
js中的变量是没有类型的,只有值才有。变量能够随时持有任何类型的值。js不作“类型强制”,语言引擎不要求变量老是持有与其初始值同类型的值。
在对变量执行操做时,获得的结果并非该变量的类型,而是该变量持有的值的类型,由于js中的变量没有类型
var a = 42;
typeof a; // "number"
a = true;
typeof a; // "boolean"
复制代码
typeof运算符老是会返回一个字符串:
typeof typeof 42; // "string"
复制代码
typeof 42 = "number", typeof "number" = "string"
变量在未持有值的时候为undefined,此时typeof返回“undefined”
var a;
typeof a;// "undefined"
var b = 42;
var c;
b = c;
typeof b; // "undefined"
typeof c; // "undefined"
复制代码
大多数开发者倾向于undefined等同于undeclared(未声明),但在js中他们彻底是两回事
var a;
a; // undefined
b; // ReferenceError: b is not defined
复制代码
undefined 和 is not defined是两码事。若此时浏览器报错成“b is not found” 或 “b is not declared”会更准确
var a;
typeof a; // "undefined"
typeof b; // "undefined"
复制代码
对于undeclared变量,typeof照样返回"undefined"
虽然b是一个undeclared变量,但typeof b没报错,这是由于typeof有一个特殊的安全防范机制
该安全防范机制对在浏览器中运行的js代码颇有帮助,由于多个脚本文件会在共享的全局命名空间中加载变量。
如何在程序中检查全局变量DEBUG才不会出现RefrenceError错误,这是typeof的安全防范机制就能作到:
// 这样会报错
if (DEBUG) {
console.log("Debugging is staring");
}
// 这样是安全的
if (typeof DEBUG !== "undefined") {
console.log("Debugging is staring");
}
复制代码
还有一种不经过typeof的安全防范机制的方法,就是检查全部全局变量是不是全局对象的属性,浏览器中的全局对象是window
if (window.DEBUG) {
// ..
}
if (!window.atob) {
// ..
}
复制代码
与undeclared变量不一样,访问不存在的对象属性(甚至是在全局对象window上)不会产生RefrenceError错误。