类型----《你不知道的js》

1、内置类型

js共有7种内置类型:数组

  • 空值(null)
  • 未定义(undefined)
  • 布尔值(boolean)
  • 数字(number)
  • 字符串(string)
  • 对象(object)
  • 符号(symbol, ES6新增)

除对象外,其余统称为“基本类型”浏览器

咱们可用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属性是元素的个数

3、值和类型

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和undeclared

变量在未持有值的时候为undefined,此时typeof返回“undefined”

var a;
typeof a;// "undefined"
var b = 42;
var c;
b = c;
typeof b; // "undefined"
typeof c; // "undefined"
复制代码

大多数开发者倾向于undefined等同于undeclared(未声明),但在js中他们彻底是两回事

  • undefined:已在做用域中声明但尚未赋值的变量
  • undeclared:尚未在做用域中声明过的变量
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有一个特殊的安全防范机制

二、typeof Undeclared

该安全防范机制对在浏览器中运行的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错误。

相关文章
相关标签/搜索