前端八股(自用)

1.js的数据类型

原始类型(值类型) 7 种栈存储:

String、Number、Boolean、Bigint、Undefined、Null、Symbol

引用类型堆存储:Object ( Array、Function、Date、RegExp等)

引用值特点:变量只存堆内存地址,多个变量共用同一个堆数据时,改一个全变

2.判断数据类型的方式

1. typeof

适合判断原始类型,判断对象只能分出object / function,数组、null 都识别不出来,null、数组都会判断为object

eg:

typeof "123456" => "string" typeof null => "object" typeof {a:1} => "object" typeof [1,2,3,4] => "object"
判断数组优先使用 Array.isArray()
2. instanceof

判断引用类型是谁的实例,不能直接判断原始值,返回布尔值true / false

注意:基本类型直接用 instanceof 是 false

const arr = [] console.log(arr instanceof Array) // true const obj = {} console.log(obj instanceof Object) // true function Person() {} const p = new Person() console.log(p instanceof Person) // true
3. Object.prototype.toString.call()

精准判断所有类型

面试题
问:堆和栈的区别?

答:

问:null 是放堆还是栈?

答:null是基本类型,值存在栈, typeof null === ‘object' 是历史bug,不是说它是对象

3.浅拷贝和深拷贝

1.浅拷贝

只复制栈里的地址,共用堆里对象

常见方法:

1.展开运算符 ...(常用)
const obj={a:1,b:{c:2}} const newObj={...obj}
2.Object.assign()
const newObj=Object.assign({},obj)

注意:只能复制自身可枚举属性,不拷贝原型、symbol 以外的不可枚举属性

3.数组浅拷贝
const arr=[1,2,3] const arr1=[...arr] const arr2=arr.slice() const arr3=Array.from(arr) const arr4=arr.concat()
2.深拷贝

在堆中开辟一块内存,生成全新对象

常用方法:

1.Json.parse(Jsom.stringify()) 最简单,有坑
const newObj = JSON.parse(JSON.stringify(obj))
  1. 不能拷贝undefined、function、symbol→ 直接丢掉
  2. 不能拷贝循环引用(会报错)
  3. 不能拷贝Date→ 变成字符串;RegExp、Error对象拷贝异常
  4. 无法拷贝原型链上的属性
2.手写递归深拷贝
function deepClone(obj,hush=new WeakMap()){ if(obj===null || typeof obj !== 'object') return obj if(hush.has(obj)) return hush.get(obj) let clone=Array.isArray(obj) ? [] : {} for(let k in obj){ if(obj.hasOwnProperty(k){ clone[k] = deepClone(obj[k],hush) } } return clone }
3.第三方库

lodash 的 _.cloneDeep() 生产最稳,内置处理各种特殊对象、循环引用

import _ from 'lodash' const newObj = _.cloneDeep(obj)
4. structuredClone
const obj = { a: 1, date: new Date(), map: new Map([['x', 2]]), set: new Set([3,4]) } // 循环引用也可以!JSON直接报错 obj.self = obj const clone = structuredClone(obj) clone.a = 999 console.log(obj.a) // 1,互不影响 ✔

structuredClone是现在浏览器原生最好用的深拷贝,解决了 JSON 深拷贝绝大多数痛点;但是对象里面一旦有函数,就不能用它,会直接报错。

4.数组的常用方法 (分成3类记)

迭代方法:forEach、map、filter、reduce...

修改原数组:push、pop、splice ...

返回新数组:slice 、concat、map 、filter...