基础数据类型,存放在栈(stack)中,存值
String
Number
Boolean
Null
Undefined
-
Symbol
代表创建后独一无二且不可变的数据类型,主要是为了解决可能出现的全局变量冲突的问题
-
BigInt
是一种数字类型的数据,它可以表示任意精度格式的整数,使用 BigInt 可以安全地存储和操作大整数,即使这个数已经超出了 Number
能够表示的安全整数范围
// Symbol
let num1 = Symbol(1);
let num2 = Symbol(1);
console.log(num1 === num2); // false
// BigInt
let num1 = Number(10000000000000000000000);
let num2 = Number(10000000000000000000000);
console.log(num1 + num2); // 2e+22
let num3 = BigInt(10000000000000000000000);
let num4 = BigInt(10000000000000000000000);
console.log(num3 + num4); // 20000000000000000000000n
堆和栈
- 堆和栈的概念存在于数据结构中和操作系统内存中
- 在数据结构中,栈中数据的存取方式为先进后出。而堆是一个优先队列,是按优先级来进行排序的,优先级可以按照大小来规定。完全二叉树是堆的一种实现方式
- 在操作系统中,内存被分为栈区和堆区
- 栈区内存由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈
- 堆区内存一般由程序员分配释放,若程序员不释放,程序结束时可能由垃圾回收机制回收
引用类型,存放在堆(heap)中,指向栈中的地址,存址
-
Object
(RegExp
、Math
、Map
、Set
)
Array
Function
类型转换
- 强制转换
parseInt()
、parseFloat()
、Number()
- 隐式转换
==
、!!
let str = '99';
let num = 99;
// 强制转换
console.log(parseInt(str)) // 99
console.log(parseFloat(str)) // 99
console.log(Number(str)) // 99
// 隐式转换
console.log(str == num) // true
console.log(!!num) // true
类型判断
1. typeof
- 基础数据类型中除了
null
,其它类型都可以通过 typeof
来判断。
- 不同的对象在底层都表示为二进制,在 javascript 中要是二进制前三位都是 0 的话就表示对象,而
null
的二进制都是 0,那么前三位自然也是 0,就被认为是 object,所以 typeof null
返回的是 object。
console.log(typeof 1) // number
console.log(typeof undefined) // undefined
console.log(typeof null) // object
console.log(typeof true) // boolean
console.log(typeof '字符串') // string
console.log(typeof Symbol('1')) // symbol
console.log(typeof BigInt(10000)) // bigint
console.log( typeof function fun (){}) // function
console.log(typeof NaN); // number
// 判断当前脚本运行在浏览器还是node环境中
if (typeof process !== 'undefined') {
console.log("node");
} else {
console.log("浏览器");
}
2. instanceof
- 内部通过原型链的方式来判断是否为构建函数的实例,常用于判断具体的对象类型。
console.log([] instanceof Array) // true
3. constructor
console.log([].constructor === Array) // true
4. Object.prototype.toString(推荐)
console.log( Object.prototype.toString.call(null) ) // [object Null]
console.log( Object.prototype.toString.call(true) ) // [object Boolean]
console.log( Object.prototype.toString.call(1) ) // [object Number]
console.log( Object.prototype.toString.call('字符串') ) // [object String]
console.log( Object.prototype.toString.call(1n) ) // [object BigInt]
console.log( Object.prototype.toString.call([]) ) // [object Array]
console.log( Object.prototype.toString.call({}) ) // [object Object]
console.log( Object.prototype.toString.call(function fun(){}) ) // [object Function]
5. 判断特定类型的 API
console.log( isNaN(1) ) // false
console.log( Array.isArray([]) ) // true
数值格式化(每三位增加一个逗号)
// 方法一
function formatString(str) {
return str && str.replace(/(?!^)(?=(\d{3})+\.)/g, ",");
}
// 方法二
function formatNumber1(number) {
return Intl.NumberFormat().format(number)
}
// 方法三
function formatNumber2(number) {
return number.toLocaleString('en')
}
console.log(formatString('1002300.102')); // 1,002,300.102
console.log(formatNumber1(1002300.102)); // 1,002,300.102
console.log(formatNumber2(1002300.102)); // 1,002,300.102
0.1 + 0.2 != 0.3
- 当计算机计算 0.1+0.2 的时候,实际上计算的是这两个数字在计算机里所存储的二进制,0.1 和 0.2 在转换为二进制表示的时候会出现位数无限循环的情况。js 中是以 64 位双精度格式来存储数字的,只有 53 位的有效数字,超过这个长度的位数会被截取掉,这样会造成了精度丢失的问题
- 在对两个以 64 位双精度格式的数据进行计算的时候,首先会进行对阶的处理,对阶指的是将阶码对齐,也就是将小数点的位置对齐后,再进行计算,一般是小阶向大阶对齐,因此小阶的数在对齐的过程中,有效数字会向右移动,移动后超过有效位数的位会被截取掉,这样也会造成了精度丢失的问题
- 当两个数据阶码对齐后,进行相加运算后,得到的结果可能会超过 53 位有效数字,因此超过的位数也会被截取掉,这样也会造成了精度丢失的问题
console.log((0.1 * 10 + 0.2 * 10) / 10 === 0.3)
推荐 Number-Precision
面试题
let obj1 = {};
let a1 = '0';
let b1 = 0;
obj1[a1] = '好好';
obj1[b1] = '学习';
console.log(obj1[a1]); // 学习
// 引用类型,存址
// 属性名不能重复
// 数字属性名和字符串属性名隐式转换('0' == 0),obj[b] 覆盖 obj[a]
let obj2 = {};
let a2 = Symbol(1);
let b2 = Symbol(1);
obj2[a2] = '天天';
obj2[b2] = '向上';
console.log(obj2[a2]); // 天天
// Symbol 创建唯一的值
let obj3 = {};
let a3 = {
n: '1'
};
let b3 = {
m: '2'
};;
obj3[a3] = '我爱';
obj3[b3] = '我家';
console.log(Object.prototype.toString.call(a3)); // [objec Obje]
console.log(Object.prototype.toString.call(b3)); // [objec Obje]
console.log(obj3[a3]); // 我家
// Object.prototype.toString.call()
// a3 b3 都转换为[objec Obje],obj[b] 覆盖 obj[a]
网友评论