JavaScript 中有八种基本的数据类型(前七种为基本数据类型,后一种 Object
为复杂数据类型)
基本数据类型:
- number 用于任何类型的数字:整数或浮点数,在 ±(2(^53)-1) 范围内的整数。
- string 用于字符串:一个字符串可以包含 0 个或多个字符,所以没有单独的字符类型。
- boolean 用于 true 和 false。
- null 用于未知的值 —— 只有一个 null 值的独立类型。
- undefined 用于未定义的值 —— 只有一个 undefined 值的独立类型。
- symbol 用于唯一的标识符。
- bigint 用于任意长度的整数。
复杂数据类型:
- object
- Array
- Function
栈内存和堆内存
当定义一个变量的时候,JavaScript 引擎会为变量分配两种内存:栈内存和堆内存。
静态值在编译阶段有固定的大小,静态值有: 原始值:Null、Undefined、Boolean、Number、String、Symbol、BigInt 引用值:是对象的引用。 静态值有固定的大小,不能改变。JavaScript 引擎为它们分配一片固定的内存,并存储在栈上。例如:
为什么 0.1 + 0.2 !== 0.3 ?
0.1 和 0.2 的二进制表示形式是不准确的,所以它们相加时,结果不是精确的 0.3, 而是非常接近的值:0.30000000000000004。
当 0.1 存下来的时候,就发生了精度丢失,当我们用浮点数进行运算的时候,使用的其实是精度丢失后的数。当我们对两个数字求和时,它们的“精度损失”会叠加起来。这就是为什么 0.1 + 0.2 不等于 0.3。
空值合并运算符(??
)
空值合并运算符(??)是一个逻辑运算符,判断左边的值是否是 null 或 undefined。如代码 a ?? b,如果 a 是 null 或 undefined,返回 b, 反之,返回 a。
??
和 ||
的相同点:都可以为值为 null
或 undefined
的变量赋默认值。如下面代码:
let firstName = null, lastName = 'Sun';
let fullName = firstName ?? lastName
console.log(fullName); // Sun
fullName = firstName || lastName;
console.log(fullName); // Sun
不同点在于: ?? 只判断值 null 和 undefined。 || 是任何假值(0, '', NaN, null, undefined)都不会被返回。这导致如果你使用 0,'' 或 NaN 作为有效值,就会出现不可预料的后果。
typeof null 的结果是什么?
JavaScript 中,typeof null 是 object,这是不对的,因为 null 是基本数据类型,不是对象。这是个 bug,但是因为修复这个 bug 会影响现存的代码,所以就一直没改。
typeof NaN
返回 'number'
。NaN
表示不是一个数字,它是 Number
的特殊值。
==、 === 和 Object.is() 的区别是什么?
==
:等同,比较运算符,两边值类型不同的时候,先进行类型转换,再比较;
===
:恒等,严格比较运算符,不做类型转换,类型不同就是不等;
Object.is 除下面三个值外,表现与 ===
相同
-0
和+0
不相等Object.is(NaN,NaN)
为true
JavaScript 判断数据类型有哪些方法?
type
返回一个字符串,表示操作数的类型
- typeof 的返回类型为字符串,值有:number、boolean、string、object、function、undefined、symbol、bigint
- typeof 一般用来判断基本数据类型,除了判断null会输出"object",其它都是正确的
- typeof 判断引用数据类型时,除了判断函数会输出"function",其它都是输出"object"
instanceof
可以正确判断对象的类型
console.log(2 instanceof Number)//false
console.log(true instanceof Boolean)//false
console.log('str' instanceof String)//false
console.log([] instanceof Array)//true
console.log(function () {
} instanceof Function)//true
console.log({} instanceof Object)//true
- instanceof 只能正确判断引用数据类型,而不能判断基本数据类型。
- instanceof 返回值为布尔值
Object.prototype.toString.call()
Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
判断数组的方式有哪些
- Object.prototype.toString.call(obj).slice(8,-1) === 'Array';
- obj.proto === Array.prototype;
- Array.isArrray(obj);
- obj instanceof Array