企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
[toc] #### 1.js数据类型,区别 1.基本数据类型 + string + number + null + undefined + boolean + Symbol ```javascript 唯一数 let sym = Symbol('描述') ``` + BigInt 大整数 ```js js最大支持53位数,为了表示最大精度以外的数,新增了BigInt类型 let num = 123n typeof num // bigint 可以进行加减乘除 如果除法有小数,会被舍弃小数部分 ``` 2.引用数据类型 + Object + Function + Array #### 2.Object.assign(target, source) 将后面的对象key以及内容覆盖到target对象上 #### 3.constructor #### 4.手写map ```js Array.prototype._map = function(callback) { let res = [] for (let i=0; i<this.length; i++) { res.push(callback(this[i], i, this)) } return res } ``` #### 5. for of 能遍历对象吗? 不能,只能遍历可迭代的对象,如 Array, Map, Set 等 #### 6.instanceOf 作用,手写一个 instanceOf 主要用于判断一个实例是否属于某种类型 `left instanceOf rightClass`,右边的prototype在左边的原型链上即可 ```js function instance_of(l, r) { let o = r.prototype // 获取 r 的原型 let pL = l.__proto__ // 获取 l 的原型 // 寻找 l 的原型链,看是否存在 o,直到原型指向 null while(true) { if (pL === null) { return false } if (o === pL) { // 找到 l 的原型链上存在 等于 l return true } pL = pL.__proto__ } } ``` #### 7.数组去重 1. new Set(arr) 方法 2. 遍历法,includes判断 3. Map方法,把值存在 Map对象的 key上,遍历arr,判断Map是否存在该item,如果不存在则push到新数组 ```js // set function uni(arr) { return [...new Set(arr)] } // Map 遍历法 function uni2(arr) { let map = new Map() let res = [] arr.forEach(item => { if (!map.has(item)) { map.set(item, true) res.push(item) } }) return res } // 双指针修改原数组 function uni3(arr) { let i = 0, // 非重复位置 j = 0; // 指针 // 指针j开始移动 for (0; j<arr.length; j++) { // 如果j和i项不一样,则i+1,将j的值赋给i, j继续+1 // 如果一样,i不动,j++ // 所以 i的位置就是非重复数组的最后一个位置 if (arr[i] !== arr[j]) { i++ arr[i] = arr[j] } } return arr.slice(0, i+1) } let arr = [1, 1, 2, 2, 3, 3] console.log(uni(arr)); console.log(uni2(arr)); console.log(uni3(arr)); ``` #### 8.类数组与数组区别,转换 1.类数组 + 通过class类名,或者标签名获取dom,得到的就是类数组 + 函数内arguments代替参数 + 手动实现 ```js let al1 = { length: 5, 0: 0, 1: 1, 3: 3, 4: 4, 5: 5, }; ``` 2.类数组转化为数组 + Array.from + Array.prototype.slice.call(objArr) ```js console.log(Array.from(objArr)); console.log(Array.prototype.slice.call(objArr)); ``` #### 9.手写发布订阅 原理:创建一个发布订阅 class,用event对象{}存储事件名,以及回调函数 on,订阅,指的是创建事件名对应的回调函数,或者往callbacks数组中push方法 off,解除订阅,指的是callbacks数组中删除某个方法,或者清空 emit, 触发订阅事件,指的是遍历执行callbacks数组中的方法,但是注意args传参,以及this指向 ```js class EventPubSub { constructor() { this.event = {} // 事件集合 } // 订阅 // type: 事件名, callback: 回调函数 on(type, callback) { // 如果订阅的事件不存在 if(!this.event[type]) { this.event[type] = [callback] // 发布订阅需要执行的callback是一个callback数组 } else { this.event[type].push(callback) } } // 解除订阅,解除的是callback一样的某一个 off(type, callback) { if(!this.event[type]) { return } if (callback) { this.event[type] = this.event[type].filter(item => { return item !== callback }) } else { this.event[type] = [] } } // 发布,执行 emit(type, ...args) { if (!this.event[type]) { return } this.event[type].forEach(callback => { callback.apply(this, args) }) } } let event = new EventPubSub event.on('click', (args) => { console.log('触发click方法', args); }) event.emit('click', 1) ``` #### 10.手写数组转成树 ```js // 例如将 input 转成output的形式 let input = [ { id: 1, val: '学校', parentId: null }, { id: 2, val: '班级1', parentId: 1 }, { id: 3, val: '班级2', parentId: 1 }, { id: 4, val: '学生1', parentId: 2 }, { id: 5, val: '学生2', parentId: 2 }, { id: 6, val: '学生3', parentId: 3 }, ] let output = { id: 1, val: '学校', children: [{ id: 2, val: '班级1', children: [ { id: 4, val: '学生1', children: [] }, { id: 5, val: '学生2', children: [] } ] }, { id: 3, val: '班级2', children: [{ id: 6, val: '学生3', children: [] }] }] } ``` ```js function arrToTree(arr) { // 1.先定义 id 的 hashMap, id -> item // 2.再遍历 arr,通过 parentId判断将当前 item 挂到 hashMap下哪一个item的children中 let idMap = {} arr.forEach(item => { idMap[item.id] = item }) arr.forEach(item => { if (idMap[item.parentId]) { let parentItem = idMap[item.parentId] if (parentItem.children && parentItem.children.length >= 0) { parentItem.children.push(item) } else { parentItem.children = [item] } } }) // 3.获取树的最外层,即没有parentId的那层 return arr.filter(item => !item.parentId) } ``` #### 11.Set, Map, WeakSet和WeakMap区别 + Set ```js 1.可以遍历, forEach 2.类似不能重复的数组 new Set([1, 2, 3]) 3.add, delete, has ``` + WeakSet ```js 1.不可以遍历 2.成员都是对象,引用类型 3.不能遍历,add, delete, has,没有size ``` + Map ```js 1.可以遍历,forEach((value, key)) 2.类似对象,但是key可以是多种类型 3.set, delete, has, clear, size ``` + WeakMap ```js 弱引用类型 1.不可以遍历,没有size, values, keys等,key必须为对象,目的是为了不会被垃圾回收考虑,当WeakMap没有被使用时会自动销毁 2.set, delete ``` #### 12.js存在哪几种内存泄露的情况 1. 意外的全局变量 2. 闭包 3. 未被清空的定时器 4. 未被销毁的事件监听 5. DOM引用 #### 13.js判断数组 ```js 1.Array.isArray(arr) // true 2.arr instanceof Array // true 3.arr.constructor === Array // true 4.Object.prototype.toString.call(arr) === '[Object Array]' ```