JS中有八种数据类型:
- 空值(null)
- 未定义(undefined)
- 布尔值(boolean)
- 数字(number)
- 字符串(string)
- 对象 (object)
- 符号(symbol, ES6中新增)
- 大整数(BigInt, ES2020 引入)
其中七种基础数据类型,又叫简单数据类型。
一种复杂数据类型,又叫引用数据类型:object 它包括普通对象,数组,正则,日期,Math数学函数
这两类的本质区别:存储方式不同,
基础数据类型存储在栈内存中,占据空间小。
复杂数据类型存储在堆内存中,占据空间大,在栈内存中存在一个指针指向堆内存中的起始地址。
null和undefined
undefined是全局对象的一个属性,当一个变量声明没有赋值,函数形参没有传实参,函数没有return或者return空值,访问某个对象的不存在属性,这些情况都是undefined。
let one;
let obj = {};
function fn(a, b) {
console.log(b); //undefined
return //换行默认会添加分号; 输出题
a + b;
}
console.log(fn(1));//undefined
console.log(obj.age);//undefined
null代表对象的值未设置,表示空对象指针,可以用于释放内存空间。
console.log(undefined == undefined);//true
console.log(undefined === undefined);//true
console.log(undefined == null);//true
console.log(undefined !== null);//true
undefined表示一个变量初始状态值,而null则表示一个变量被人为设置为空对象。
关于symbol和bigint两种新加入的数据类型
symbol(符号)是es6新加入的,符号是原始值,并且符号实例是唯一的不可变的。
符号实例:(不需要new来创建)
let sy = Symbol("2");
let sy1 = Symbol("2");
console.log(sy == sy1);//false
可以作为对象键,但是不可枚举。
let sy = Symbol("2");
const obj = { name: "object" };
obj[sy] = 100;
console.log(obj);//{name: 'object', Symbol(2): 100}
for (let key in obj) {
console.log(key);//name for in 遍历对象的可枚举属性 访问不到symbol
}
bigint表示大于 2^53 - 1 的整数,
可以用在一个整数字面量后面加 n 的方式定义一个 BigInt ,如:10n,或者调用函数 BigInt()(但不包含 new 运算符)并传递一个整数值或字符串值。
const a= = 9007199291n;
const b = BigInt(90);
// ↪ 90n
typeof
const number = 1;
const string = "ww";
const boolean = true;
const symbol = Symbol("y");
const bigInt = 1n;
const undefine = undefined;
const nul = null;
const arr = [2, "32"];
function fn() {}
console.log(typeof number);//number
console.log(typeof string);//string
console.log(typeof boolean);//boolean
console.log(typeof symbol);//symbol
console.log(typeof bigInt);//bigint
console.log(typeof undefine);//undefined
console.log(typeof null);//object
console.log(typeof arr);//object
console.log(typeof fn);//function
console.log(typeof NaN);//number
console.log(typeof NaN === "number"); //true 特殊的点
可以看到特殊的情况有:对于null返回object,函数返回function 数组返回object
typeof原理:不同的对象在底层都表示为二进制,在Javascript中二进制前(低)三位存储其类型信息
- 000: 对象
- 010: 浮点数
- 100:字符串
- 110: 布尔
- 1: 整数
因为null的二进制位前三位恰好都是0,所以解释typeof null返回object
typeof 函数返回function
****function实际上是object的一个"子类型",具体来说,函数是"可调用对象",它有一个内部属性[[Call]],该属性使其可以被调用。
typeof 数组返回object
数组也是object的"子类型"
可以看到上面代码底部有一个很特殊的点:typeof NaN 是number类型,这个记住就行。
undeclared和typeof防范机制
undeclared与undefined
let a
a;//undefined
b;//ReferenceError:b is not defined
在Javascript中,"undefined"和"is not defined"是两码事。
typeof安全防范机制
对于已经声明和未声明的变量typeof一视同仁,这是一种特殊的安全防范机制
let a;
console.log(typeof a);//undefined
console.log(typeof b);//undefined
可以看到下面这种情况:
let a
if (!a) {
console.log("sucess1");//success1
}
if (!b) {
console.log("sucess2");
} //这部分会报错ReferenceError: b is not defined
解决方法:
if (typeof b === "undefined") {
console.log("sucess2");//这样就可以正常输出
}
上面代码中变量b没有声明在我们的项目中可能会遇到:比如复制他人的代码,就需要检查复制部分的变量是否在宿主程序中定义过。一些库的引入都会涉及这个问题。这就可以使用typeof。
例子:
function doSomething() {
var a = (typeof b !== "undefined") ? b : function () {};
// 这里不知道宿主程序中是否有变量b,如果没有就自己定义
}
参考:《你不知道的JS》 《JS高级程序设计》 [ MDN ](MDN Web Docs (mozilla.org)) [别人的文章](typeof和instanceof原理 - 掘金 (juejin.cn))