前端高频面试题 Day01

2023-11-04

1. Map 和 Object 的不同

API 不同

// 初始化
const m = new Map([
    ['key1', 'hello'],
    ['key2', 100],
    ['key3', { x: 10 }]
])

// 新增
m.set('name', '双越')

// 删除
m.delete('key1')

// 判断
m.has('key2')

// 遍历
m.forEach((value, key) => console.log(key, value))

// 长度(Map 是有序的,下文会讲,所有有长度概念)
m.size

以任意类型为 key

const m = new Map()
const o = { p: 'Hello World' }

m.set(o, 'content')
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false

Map 是有序结构

Object key 不能按照既定顺序输出

// Object keys 是无序的
const data1 = {'1':'aaa','2':'bbb','3':'ccc','测试':'000'}
Object.keys(data1) // ["1", "2", "3", "测试"]

const data2 = {'测试':'000','1':'aaa','3':'ccc','2':'bbb'};
Object.keys(data2); // ["1", "2", "3", "测试"]

Map key 可以按照既定顺序输出

const m1 = new Map([
    ['1', 'aaa'],
    ['2', 'bbb'],
    ['3', 'ccc'],
    ['测试', '000']
])
m1.forEach((val, key) => { console.log(key, val) })
const m2 = new Map([
    ['测试', '000'],
    ['1', 'aaa'],
    ['3', 'ccc'],
    ['2', 'bbb']
])
m2.forEach((val, key) => { console.log(key, val) })

Map 很快

Map 作为纯净的 key-value 数据结构,它比 Object 承载了更少的功能。

Map 虽然有序,但操作很快,和 Object 效率相当。

// Map
const m = new Map()
for (let i = 0; i < 1000 * 10000; i++) {
    m.set(i + '', i)
}
console.time('map find')
m.has('2000000')
console.timeEnd('map find')
console.time('map delete')
m.delete('2000000')
console.timeEnd('map delete')
// Object
const obj = {}
for (let i = 0; i < 1000 * 10000; i++) {
    obj[i + ''] = i
}
console.time('obj find')
obj['200000']
console.timeEnd('obj find')
console.time('obj delete')
delete obj['200000']
console.timeEnd('obj delete')

另外,Map 有序,指的是 key 能按照构架顺序输出,并不是说它像数组一样是一个有序结构 —— 否则就不会这么快了

但这就足够满足我们的需求了。

WeakMap

WeakMap 也是弱引用。但是,WeakMap 弱引用的只是键名 key ,而不是键值 value

// 函数执行完,obj 会被销毁,因为外面的 WeakMap 是“弱引用”,不算在内
const wMap = new WeakMap()
function fn() {
    const obj = {
        name: 'zhangsan'
    }
    // 注意,WeakMap 专门做弱引用的,因此 WeakMap 只接受对象作为键名(`null`除外),不接受其他类型的值作为键名。其他的无意义
    wMap.set(obj, 100) 
}
fn()
// 代码执行完毕之后,obj 会被销毁,wMap 中也不再存在。但我们无法第一时间看到效果。因为:
// 内存的垃圾回收机制,不是实时的,而且是 JS 代码控制不了的,因此这里不一定能直接看到效果。

另外,WeakMap 没有 forEachsize ,只能 add delete has 。因为弱引用,其中的 key 说不定啥时候就被销毁了,不能遍历。

WeakMap 可以做两个对象的关联关系,而不至于循环引用,例如:

const userInfo = { name: '双越' }
const cityInfo = { city: '北京' }

// // 常规关联,可能会造成循环引用
// userInfo.city = cityInfo
// cityInfo.user = userInfo

// 使用 WeakMap 做关联,则无任何副作用
const user_to_city = new WeakMap()
user_to_city.set(userInfo, cityInfo)

总结

  • key 可以是任意数据类型
  • key 会按照构建顺序输出
  • 很快
  • WeakMap 弱引用

2. Set 和数组的区别

Set 元素不能重复

const arr = [10, 20, 30, 30, 40]
const set = new Set([10, 20, 30, 30, 40]) // 会去重
console.log(set) // Set(4) {10, 20, 30, 40}
// 数组去重
function unique(arr) {
    const set = new Set(arr)
    return [...set]
}
unique([10, 20, 30, 30, 40])

API 不一样

// 初始化
const set = new Set([10, 20, 30, 30, 40]) 

// 新增(没有 push unshift ,因为 Set 是无序的,下文会讲)
set.add(50)

// 删除
set.delete(10)

// 判断
set.has(20)

// 长度
set.size

// 遍历
set.forEach(val => console.log(val))

// set 没有 index ,因为是无序的

Set 是无序的,而数组是有序的 —— 这一点很少有人提到,却很关键!!!

先看几个测试

  • 数组:前面插入元素 vs 后面插入元素
  • 数组插入元素 vs Set 插入元素
  • 数组寻找元素 vs Set 寻找元素
// 构造一个大数组
const arr = []
for (let i = 0; i < 1000000; i++) {
    arr.push(i)
}

// 数组 前面插入一个元素
console.time('arr unshift')
arr.unshift('a')
console.timeEnd('arr unshift') // unshift 非常慢
// 数组 后面插入一个元素
console.time('arr push')
arr.push('a')
console.timeEnd('arr push') // push 很快

// 构造一个大 set
const set = new Set()
for (let i = 0; i < 1000000; i++) {
    set.add(i)
}

// set 插入一个元素
console.time('set test')
set.add('a')
console.timeEnd('set test') // add 很快

// 最后,同时在 set 和数组中,寻找一个元素
console.time('set find')
set.has(490000)
console.timeEnd('set find') // set 寻找非常快
console.time('arr find')
arr.includes(490000)
console.timeEnd('arr find') // arr 寻找较慢

什么是无序,什么是有序?参考 x1-有序和无序.md

  • 无序:插入、查找更快
  • 有序:插入、查找更慢

因此,如果没有强有序的需求,请用 Set ,会让你更快更爽!

WeakSet

WeekSet 和 Set 类似,区别在于 —— 它不会对元素进行引用计数,更不容易造成内存泄漏。

// 函数执行完,obj 就会被 gc 销毁
function fn() {
    const obj = {
        name: 'zhangsan'
    }
}
fn()
// 函数执行完,obj 不会被销毁,因为一直被外面的 arr 引用着
const arr = []
function fn() {
    const obj = {
        name: 'zhangsan'
    }
    arr.push(obj)
}
fn()
// 函数执行完,obj 会被销毁,因为外面的 WeakSet 是“弱引用”,不算在内
const wSet = new WeakSet()
function fn() {
    const obj = {
        name: 'zhangsan'
    }
    wSet.add(obj) // 注意,WeakSet 就是为了做弱引用的,因此不能 add 值类型!!!无意义
}
fn()

【注意】内存的垃圾回收机制,不是实时的,而且是 JS 代码控制不了的,因此这里不一定能直接看到效果。
WeekSet 没有 forEachsize,只能 add deletehas。因为垃圾回收机制不可控(js 引擎看时机做垃圾回收),那其中的成员也就不可控。

总结

  • Set 值不能重复
  • Set 是无序结构
  • WeakSet 对元素若引用

3. 数组求和

传统方式

function sum(arr) {
    let res = 0
    arr.forEach(n => res = res + n)
    return res
}
const arr = [10, 20, 30]
console.log( sum(arr) )

reduce 方法的使用

// 累加器
const arr1 = [10, 20, 30, 40, 50]
const arr1Sum = arr1.reduce((sum, curVal, index, arr) => {
    console.log('reduce function ......')
    console.log('sum', sum)
    console.log('curVal', curVal)
    console.log('index', index)
    console.log('arr', arr)

    return sum + curVal // 返回值,会作为下一次执行的 sum
}, 0)
console.log('arr1Sum', arr1Sum)

reduce 的其他用法

// 计数
function count(arr, value) {
    // 计算 arr 中有几个和 value 相等的数
    return arr.reduce((c, item) => {
        return item === value ? c + 1 : c
    }, 0)
}
const arr2 = [10, 20, 30, 40, 50, 10, 20, 10]
console.log( count(arr2, 20) )
// 数组输出字符串
const arr3 = [
    { name: 'xialuo', number: '100' },
    { name: 'madongmei', number: '101' },
    { name: 'zhangyang', number: '102' }
]
// // 普通做法 1(需要声明变量,不好)
// let arr3Str = ''
// arr3.forEach(item => {
//     arr3Str += `${item.name} - ${item.number}\n`
// })
// console.log(arr3Str)
// // 普通做法 2(map 生成数组,再进行 join 计算)
// console.log(
//     arr3.map(item => {
//         return `${item.name} - ${item.number}`
//     }).join('\n')
// )
// reduce 做法(只遍历一次,即可返回结果)
console.log(
    arr3.reduce((str, item) => {
        return `${str}${item.name} - ${item.number}\n`
    }, '')
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

前端高频面试题 Day01 的相关文章

随机推荐

  • Arduino基础入门篇31—LCD1602液晶显示

    LCD1602也叫1602字符型液晶 是一种专门用来显示字母 数字 符号的点阵型液晶模块 能同时显示16X2即32个字符 本篇我们来认识LCD1602 驱动它显示 Hello World 1 LCD1602介绍 对于单片机爱好者和电子爱好者
  • php-cgi.exe - FastCGI 进程超过了配置的请求超时时限

    解决方案一 处理 php cgi exe FastCGI 进程超过了配置的请求超时时限 的问题 内容转载 处理 php cgi exe FastCGI 进程超过了配置的请求超时时限 的问题 php技巧 脚本之家 详细错误 HTTP 错误 5
  • 【华为OD机试真题 JAVA】出错的或电路

    JS版 华为OD机试真题 JS 出错的或电路 标题 出错的或电路 时间限制 1秒 内存限制 262144K 语言限制 不限 某生产门电路的厂商发现某一批次的或门电路不稳定 具体现象为计算两个二进制数的或操作时 第一个二进制数中某两个比特位会
  • 利用Java对后端数据进行分页处理(Java假分页)

    代码如下 import java util Collections import java util List java分页 辅助器 public class PageHelper
  • HttpClient远程调用工具类

    文章目录 前言 一 HttpClient工具类 二 使用步骤 1 引入库 前言 提示 当前工具类get方式无法传分页数据 可自行篡改 不行就用post方式哈哈 提示 以下是本篇文章正文内容 下面案例可供参考 一 HttpClient工具类
  • Qt中显示摄像头数据(V4L2三)

    目录 一 通过V4l2来采集用qt显示 1 将V4L2获取摄像头数据封装成一个类 2 设置开始按钮开始采集数据 3 设置停止按钮停止采集数据 4 设置定时器不断采集数据 二 直接用qt多媒体模块来实现采集并且显示 1 在qt工程文件中添加
  • 【网络结构设计】7、RepVGG

    文章目录 一 背景 二 方法 2 1 使用简单结构的卷积神经网络的三个原因 2 2 使用多分支结构的训练时长 2 3 边端设备推理的重参数化 2 4 结构细节 三 效果 论文 RepVGG Making VGG style ConvNets
  • 解决野鸡大学水硕、水博?中国首次发布海外大学排名!

    本文分享中国首次发布的海外大学排名 来源 全国高校信息资料研究会与中国人民大学评价研究中心 新东方在线托福 青塔等平台 编辑 学妹 不久前 我国一科研机构首次发布了对海外学校的评估 网传 这或许会成为以后中国看待海归大学的背景考核依据之一
  • 深度学习:循环神经网络RNN及LSTM

    深度学习 循环神经网络RNN及LSTM 循环神经网络RNN 原理 代码 长短期记忆网络LSTM 原理 遗忘门 记忆门 输出门 代码 循环神经网络RNN 原理 对于传统的神经网络 它的信号流从输入层到输出层依次流过 同一层级的神经元之间 信号
  • 两行css代码实现瀑布流,html,css最简单的瀑布流实现方式且没有缺点!

    两行css代码实现瀑布流 html css最简单的瀑布流实现方式且没有缺点 之前一直使用css position定位 js原生的方法实现 代码如下 html代码段
  • 因果推断理论框架 Potenial Outcomes Framework

    1 Potenial Outcomes Framework 因果效应通常无法直接计算 无法同时观测一个样本施加和不施加干预的结果 所以通常是通过观测数据推断 由于相关性 neq 因果性 观测结果不直接等于ATE Potenial Outco
  • SpringBoot 基本使用

    目录 热部署 方式一 Spring Boot DevTools 方式二 使用JRebel插件 web静态资源的存放 json日期时间设置 组件扫描 资源导入 运行项目的多个实例 资源文件的拷贝问题 读取resources下的文件 SpEL的
  • python三本经典书籍-关于 Python 的经典入门书籍有哪些?

    先说明 这些书是我整理来准备以后慢慢看的 并没有全部购买 更没有全部阅读 排名不分先后 Learn Python the Hard Way 本书是一本Python入门书籍 适合对计算机了解不多 没有学过编程 但对编程感兴趣的读者学习使用 这
  • GPU版本PyTorch详细安装教程

    目录 一 安装显卡驱动 1 查看显卡驱动型号 2 下载显卡驱动 3 查看GPU状态 二 安装Visual Studio 2019 三 安装CUDA 1 下载对应版本的CUDA 2 安装下载好的CUDA 3 设置环境变量 四 安装cudnn
  • ImportError: cannot import name ‘Bar‘ from ‘pyecharts‘ (D:\Anaconda3-2019.03\Anaconda3\lib\site-pack

    如题所示错误 无法从pyecharts中导入Bar 这里我安装的是最新版的pyecharts 新版Bar的导入方式有所改变 之前的导入方式 from pyecharts import Bar 已经不适用在新版本中了 现在的导入方式为 fro
  • redux详细介绍

    redux详细介绍 1 redux 1 redux是什么 redux是一个专门做状态管理的js库 不是react插件库 它可以用在react angular vue等项目中 但基本与react配合使用 作用 集中式管理react应用中多个组
  • python中sort的使用

    描述 sort 函数用于对原列表进行排序 如果指定参数 则使用比较函数指定的比较函数 语法 sort 方法语法 list sort key None reverse False 参数 参数 key 主要是用来进行比较的元素 只有一个参数 具
  • Day10_Git版本控制、项目总结,preview_220627,

    Day10 Git版本控制 手动的管理和记录每个版本之间的变化 项目开发会存在同样的问题 整个项目由多个人共同开发 每个人开发的模块可能一样也可能不一样 不一样 每个人负责不同的 功能模块 一样 多个人共同负责一个模块 代码会产生多个版本
  • mysql8.0及以上版本JDBC(带mysql8.0版本之前jdbc)

    关于Mysql 8 0及以上jdbc MYSQL8 0以前的jdbc格式 注册驱动 Class forName com mysq1 jdbc Driver 获取数据库连接对象 Connection conn Drive rManager g
  • 前端高频面试题 Day01

    文章目录 1 Map 和 Object 的不同 API 不同 以任意类型为 key Map 是有序结构 Map 很快 WeakMap 总结 2 Set 和数组的区别 Set 元素不能重复 API 不一样 Set 是无序的 而数组是有序的 这