0


web前端面试宝典——带你直击面试重难点(40个经典题目,涵盖近90%的考点,码字2w,干货满满!)

系列文章目录

JavaScript 知识梳理,收录了web前端面试 95%以上 的高频考点,满满的干货。给你做一个高效的知识梳理,为你的面试保驾护航!

内容参考链接HTML & CSS 篇HTML & CSS 篇JavaScript 篇(一)JavaScript 篇(一)【JS的三座大山 】原型和原型链、作用域和闭包、异步JavaScript 篇(二)JavaScript 篇(二)【JS 异步进阶】JavaScript-Web-API 篇(一)JavaScript-Web-API 篇(一)DOM、BOM、事件JavaScript-Web-API 篇(二)JavaScript-Web-API 篇(二)AJAX、存储HTTP 篇HTTP 篇性能优化篇性能优化篇(手写防抖、手写节流、XXS攻击、XSRF攻击)经典面试题-JS篇经典面试题 HTML、CSS、JavaScript篇

文章目录


声明:全篇近两万字,耗时五天完成。涵盖了JavaScript 面试高频考点,码字不易,如果对你有帮助,还请多多支持!(先点赞,后观看,期待你的一键三连!)

var 和 let const 的区别

  • var 是 ES5 语法,let const 是 ES6 语法;var 有变量提升
  • var 和 let 是变量,可修改;const 是常量,不可修改
  • let const 有块级作用域,var 没有

示例:变量提升

    console.log(a)// undefinedvar a =100// 相当于var a
    console.log(a)// undefined
    a =100

示例:块级作用域

for(let i =0; i <5; i++){let j = i +1}
    console.log(i)

在这里插入图片描述

typeof 能判断哪些类型

  • undefined string number boolean symbol
  • object(注意:typeof null === ‘object’)
  • function

列举强制类型转换和隐式类型转换

  • 强制:parseInt parseFloat toString
  • 隐式:if、逻辑运算、==、+ 拼接字符串

手写深度比较 lodash.isEqual

  • isObject 来判断传入的参数是否为对象
  • 如果不是对象直接返回它们的全等
  • 如果传入的是同一个对象或数组,直接返回 true
  • 如果传入的是两个不相等的对象或数组
  • 则先判断长度,不一样直接返回 false
  • 一样的话,以 obj1 为基准,和 obj2 依次递归比较
  • 不相等返回 false,全满足了返回 true
// 判断是否是对象或数组functionisObject(obj){returntypeof obj ==='object'&& obj !==null}functionisEqual(obj1, obj2){if(!isObject(obj1)||!isObject(obj2)){// 值类型(参与 equal 的一般不会是函数)return obj1 === obj2
        }if(obj1 === obj2){returntrue}// 两个都是对象或数组,而且不相等// 1.先取出 obj1 和 obj2 的 keys,比较个数const obj1Keys = Object.keys(obj1)const obj2Keys = Object.keys(obj2)if(obj1Keys.length !== obj2Keys.length){returnfalse}// 2.以 obj1 为基准,和 obj2 依次递归比较for(let key in obj1){// 比较当前 key 的 val —— 递归const res =isEqual(obj1[key], obj2[key])if(!res){returnfalse}}// 3.全相等returntrue}// 测试const obj1 ={a:10,b:{x:100,y:200}}const obj2 ={a:10,b:{x:100,y:200}}
    console.log(isEqual(obj1, obj2))// true

split() 和 join() 的区别

  • Array.join() 方法是 String.split() 方法的反向操作
  • split('-') 把字符串去掉 - 转为数组
  • join('-') 把数组加上 - 转为字符串
'1-2-3'.split('-')[1,2,3].join('-')

在这里插入图片描述

pop、shift、push、unshift

以 arr 为例

const arr =[10,20,30]

pop:

  • 功能:删除数组的最后一个元素
  • 返回值:被删除的元素
  • 是否对原数组造成影响:是
// popconst popRes = arr.pop()
    console.log(popRes, arr)

在这里插入图片描述

shift:

  • 功能:删除数组的第一个元素
  • 返回值:被删除的元素
  • 是否对原数组造成影响:是
const shiftRes = arr.shift()
    console.log(shiftRes, arr)

在这里插入图片描述

push:

  • 功能:从尾部添加元素
  • 返回值:数组的长度
  • 是否对原数组造成影响:是
const pushRes = arr.push(40)
    console.log(pushRes, arr)

在这里插入图片描述
unshift:

  • 功能:从头部添加元素
  • 返回值:数组的长度
  • 是否对原数组造成影响:是
const unshiftRes = arr.unshift(5)
    console.log(unshiftRes, arr)

在这里插入图片描述

数组的API,有哪些是纯函数

纯函数:

  • 不改变源数组(没有副作用)
  • 返回一个数组
const arr =[10,20,30]

concat:

// concatconst arr1 = arr.concat([40,50]) 
    console.log(arr, arr1)

在这里插入图片描述

map:

// mapconst arr2 = arr.map(num=> num *2)
    console.log(arr, arr2)

在这里插入图片描述

filter:

// filterconst arr3 = arr.filter(num=> num >15)
    console.log(arr, arr3)

在这里插入图片描述

slice:

// sliceconst arr4 = arr.slice(2)
    console.log(arr, arr4)

在这里插入图片描述

数组 slice 和 splice 的区别

  • 功能区别:slice 切片,splice 剪接
  • 参数和返回值
  • 是否纯函数

slice:

  • slice 切片
  • 参数可传可不传,返回值是切片后的数组
  • 是纯函数(不改变原始数组)
const arr  =[10,20,30,40,50]// slice 纯函数const arr1 = arr.slice()const arr2 = arr.slice(1,4)const arr3 = arr.slice(2)const arr4 = arr.slice(-2)
    console.log(arr)// [10, 20, 30, 40, 50]
    console.log(arr1)// [10, 20, 30, 40, 50]
    console.log(arr2)// [20, 30, 40]
    console.log(arr3)// [30, 40, 50]
    console.log(arr4)// [40, 50]

在这里插入图片描述

splice:

  • splice 剪接
  • 参数可传可不传,返回值是剪接掉的元素的数组
  • 非纯函数(改变原始数组)
  • 解读:开始剪接的元素索引(1),剪接的元素个数(2),要添加的元素('a', 'b', 'c'
const arr  =[10,20,30,40,50]// splice 非纯函数const spliceRes = arr.splice(1,2,'a','b','c')
    console.log(spliceRes)// [20, 30]
    console.log(arr)// [10, 'a', 'b', 'c', 40, 50]

在这里插入图片描述

const arr  =[10,20,30,40,50]// splice 非纯函数const spliceRes1 = arr.splice(1,0,'a','b','c') 
    console.log(spliceRes1)// []
    console.log(arr)// [10, 'a', 'b', 'c', 20, 30, 40, 50]

在这里插入图片描述

const arr  =[10,20,30,40,50]// splice 非纯函数const spliceRes2 = arr.splice(1,2) 
    console.log(spliceRes2)// [20, 30]
    console.log(arr)// [10, 40, 50]

在这里插入图片描述

[10, 20, 30].map(parseInt) 输出结果

map:

  • 第一个参数是当前元素
  • 第二个参数是当前索引值

parseInt:

  • 第一个参数是要被解析的字符串
  • 第二个参数是要解析的数字的基数(进制数 2~36)
const res =[10,20,30].map(parseInt)
    console.log(res)// 拆解const res2 =[10,20,30].map((num, index)=>{returnparseInt(num, index)})
    console.log(res2)

在这里插入图片描述

ajax 请求 get 和 post 的区别

  • get 一般用于查询操作,post 一般用于提交操作
  • get 参数拼接在 url 上,post 放在请求体内(数据体积可更大)
  • 安全性:post 易于防止 CSRF 攻击

函数 call 、apply 和 bind 的区别

  • call 传入的参数直接放进去
  • apply 传入的参数是一个数组或类数组
  • bind 返回的是一个新的函数,必须调用它才会被执行
fn.call(this, p1, p2, p3)fn.apply(this, arguments)fn.bind(this, p1, p2, p3)()

示例:

let zhangsan ={name:'张三',age:20,myFun(from, to){
            console.log(this.name +this.age,'来自'+ from +'去往'+ to)}}let lisi ={name:'李四',age:22}
    
    zhangsan.myFun.call(lisi,'济南','青岛')
    zhangsan.myFun.apply(lisi,['济南','青岛'])
    zhangsan.myFun.bind(lisi,'济南','青岛')()

在这里插入图片描述

事件代理(委托)

  • 把 每个 li 的点击事件委托给 ul
  • 可以减少内存的消耗
  • 可以减少重复性操作
<ul id="list"><li>item 1</li><li>item 2</li><li>item 3</li>...<li>item n</li></ul>//获取目标元素const lis = document.getElementsByTagName('li')//循环遍历绑定元素for(let i =0; i < lis.length; i++){
        lis[i].onclick=function(event){
            console.log(event.target.innerHTML)}}

在这里插入图片描述

闭包

闭包的影响:变量会常驻内存,得不到释放。闭包不要乱用

阻止事件冒泡和默认行为

  • 阻止冒泡:event.stopPropagation() 点击激活,不会弹出取消
  • 阻止默认行为:event.preventDefault() 点击超链接,不会跳转
<p id="p1">激活</p><a id="a1" href="https://baidu.com">取消</a>const p1 = document.getElementById('p1')const a1 = document.getElementById('a1')const body = document.body

    p1.addEventListener('click',function(event){
        event.stopPropagation()alert('激活')})
    
    body.addEventListener('click',function(event){alert('取消')})

    a1.addEventListener('click',function(event){
        event.preventDefault()})

阻止冒泡 —> 点击激活,不会弹出取消:

在这里插入图片描述

如何减少 DOM 操作

  • 缓存 DOM 查询结果
  • 多次 DOM 操作,合并到一次插入
<ul id="list"></ul>const list = document.getElementById('list')// 创建一个文档片段,此时还没有插入到 DOM 结构中const frag = document.createDocumentFragment()for(let i =0; i <10; i++){const li = document.createElement('li')
        li.innerHTML =`List item ${i}`// 先插入文档片段中
        frag.appendChild(li)}// 都完成之后,再统一插入到 DOM 结构中
    list.appendChild(frag)

在这里插入图片描述

jsonp 的本质是 ajax 吗

  • 不是,因为没有用到 XMLHttpRequest 对象,所以 jsonp 不属于 ajax。
  • 它是通过能够绕过跨域的 <script> 标签实现的

document load 和 ready 的区别

    window.addEventListener('load',function(){// 页面的全部资源加载完才会执行,包括图片、视频等})

    window.addEventListener('DOMContentLoaded',function(){// DOM 渲染完即可执行,此时图片、视频还可能没有加载完})

== 和 ===

  • == 会尝试类型转换
  • === 严格相等
  • 除了 == null 之外,其他都用 ===

函数声明和函数表达式的区别

  • 函数声明:function fn() {…}
  • 函数表达式:const fn = function () {…}

示例:函数声明

const res =sum(10,20)
    console.log(res)// 30functionsum(x, y){return x + y
    }

示例:函数表达式

const res =sum(10,20)
    console.log(res)// 报错constsum=function(x, y){return x + y
    }

在这里插入图片描述

用 var 声明:
在这里插入图片描述

关于 this 的场景题

  • 第一个输出:this 指向当前对象 obj
  • 第二个输出:this 指向 window
const obj ={count:1,getCount:function(){returnthis.count
        }}
    console.log(obj.getCount())// 1const func = obj.getCount
    console.log(func())// undefined

在这里插入图片描述

new Object() 和 Object.create() 区别

  • {} 等同于 new Object(),原型 Object.prototype
  • Object.create(null) 没有原型
  • Object.create({…}) 可以指定原型

示例:

const obj1 ={a:10,b:20,sum(){returnthis.a +this.b
        }}const obj2 =newObject({a:10,b:20,sum(){returnthis.a +this.b
        }})

在这里插入图片描述
示例:

const obj1 ={a:10,b:20,sum(){returnthis.a +this.b
        }}const obj2 =newObject(obj1)

在这里插入图片描述
示例:

const obj1 = Object.create(null)const obj2 =newObject(null)

在这里插入图片描述
示例:

const obj1 ={a:10,b:20,sum(){returnthis.a +this.b
        }}const obj2 = Object.create(obj1)

在这里插入图片描述

作用域和自由变量

  • let 的 i 和 for 循环里面的 i 不在同一块级作用域,相当于在 for 循环里面用 var 声明
let i 
    for(i =0; i <=3; i++){setTimeout(function(){
            console.log(i)},0)}

在这里插入图片描述

  • for 循环里面用 let 声明,形成块级作用域,i 每增加一次,输出一次
for(let i =0; i <=3; i++){setTimeout(function(){
            console.log(i)},0)}

在这里插入图片描述

作用域和自由变量 2

  • 先把函数当成一条语句,不要看具体内容,等调用它的时候再看里面的内容
let a =100functiontest(){
        console.log(a)// 100
        a =10
        console.log(a)// 10}test()
    console.log(a)// 10

在这里插入图片描述

常见正则表达式

正则表达式30分钟入门教程

// 邮政编码/\d{6}/// 小写英文字母/^[a-z]+$/// 英文字母/^[a-zA-Z]+$/// 日期格式/^\d{4}-\d{1,2}-\d{1,2}$/// 用户名/^[a-zA-Z]\w{5,17}$/

手写字符串 trim

  • 在 String 原型上添加 trim 方法
  • this 指向输入的字符串
  • 使用正则表达式做替换
String.prototype.trim=function(){returnthis.replace(/^\s+/,'').replace(/\s+$/,'')}

获取多个数字中的最大值

  • 把要比较的数转为数组
  • 也可以用 [...arguments] 代替 Array.from(arguments)

示例:

functionmax(){const nums = Array.from(arguments)let max = nums[0]
        nums.forEach(n=>{if(n > max){
                max = n
            }})return max
    }const res =max(-1,-2,2,4,8)
    console.log(res)// 8

class 实现继承

  • extends
  • super
  • 扩展或重写方法
// 父类classPeople{constructor(name){this.name = name
        }eat(){
            console.log(`${this.name} eat food`);}}// 子类classStudentextendsPeople{constructor(name, number){super(name)this.number = number
        }sayHi(){
            console.log(`姓名 ${this.name} 学号 ${this.number}`);}}// 子类classTeacherextendsPeople{constructor(name, major){super(name)this.major = major
        }teach(){
            console.log(`${this.name} 教授 ${this.major}`)}}// 实例const xialuo =newStudent('夏洛','2022')
    console.log(xialuo.name)// 夏洛
    console.log(xialuo.number)// 2022
    xialuo.sayHi()// 姓名 夏洛, 学号 2022
    xialuo.eat()// 夏洛 eat food// 实例const wanglaoshi =newTeacher('王老师','语文')
    console.log(wanglaoshi.name)// 王老师
    console.log(wanglaoshi.major)// 语文
    wanglaoshi.teach()// 王老师 教授 语文
    wanglaoshi.eat()// 王老师 eat food

如何捕获 JS 中的异常

  1. try…catch 手动捕获
try{// todo}catch(ex){
        console.error(ex)}finally{// todo}
  1. 自动捕获
// 自动捕获
    window.onerror=function(message, source, lineNum, colNum, error){// 第一,对于跨域的 js,如 CDN 的,不会有详细的错误报告// 第二,对于压缩的 js,还要配合 sourceMap 反查未压缩代码的行、列}

什么是 JSON

  • JSON 是一种数据格式,本质是一段字符串
  • JSON 格式和 JS 对象结构一致,对 JS 语言更友好
  • window.JSON 是一个全局对象:JSON.stringify(JS 对象转为 JSON 格式) JSON.parse(JSON 格式转为 JS 对象)

获取当前页面 url 参数

  • 传统方式,查找 location.search在这里插入图片描述
  • substr(1) 截取掉字符串的第一个字符
  • 'i' 代表不区分大小写
// 传统方法functionquery(name){const search = location.search.substr(1)// search: 'a=10&b=20&c=30'const reg =newRegExp(`(^|&)${name}=([^&]*)(&|$)`,'i')const res = search.match(reg)if(res ===null){returnnull}
        console.log(res)return res[2]}let res =query('b')
    console.log(res)

在这里插入图片描述

  • 新 API,URLSearchParams
// URLSearchParamsfunctionquery(name){const search = location.search
        const p =newURLSearchParams(search)return p.get(name)}let res =query('b')
    console.log(res)// 20

将 url 参数解析为 JS 对象

传统方式,分析 search:

  • 定义 res 为一个空对象,用来存放对象
  • substr(1) 去掉前面的 ?
  • 两次 split,分别去掉 &=
  • key 充当键,val 充当值
  • 最后返回结果 res

在这里插入图片描述

// 传统方式,分析 searchfunctionqueryToObj(){const res ={}const search = location.search.substr(1)
        search.split('&').forEach(paramStr=>{const arr = paramStr.split('=')const key = arr[0]const val = arr[1]
            res[key]= val
        })return res
    }let res =queryToObj()
    console.log(res)

在这里插入图片描述

使用 URLSearchParams:

// 使用 URLSearchParamsfunctionqueryToObj(){const res ={}const pList =newURLSearchParams(location.search)
        pList.forEach((val, key)=>{
            res[key]= val
        })return res
    }let res =queryToObj()
    console.log(res)

在这里插入图片描述

数组去重

  • 传统方式,遍历元素挨个比较、去重
  • indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
  • 如果没有找到匹配的字符串则返回 -1。
functionunique(arr){const res =[]
        arr.forEach(item=>{if(res.indexOf(item)<0){
                res.push(item)}})return res
    }let res =unique([20,10,20,30,10])
    console.log(res)

在这里插入图片描述

  • 使用 Set(计算效率更高)
functionunique(arr){const newArr =newSet(arr)return[...newArr]}let res =unique([20,10,20,30,10])
    console.log(res)

在这里插入图片描述

手写深拷贝

  • 深拷贝:一个对象B复制另一个对象A,当改变B对象的值是A对象的值不会改变。
functiondeepClone(obj ={}){if(typeof obj !=='object'|| obj ==null){//  obj 是 null,或者不是对象和数组,直接返回return obj
        }// 初始化返回结果let result
        if(obj instanceofArray){
            result =[]}else{
            result ={}}for(let key in obj){// 保证 key 不是原型的属性if(obj.hasOwnProperty(key)){// 递归
                result[key]=deepClone(obj[key])}}// 返回结果 return result
    }const obj1 ={name:'张三',age:{realAge:20},arr:['a','b','c']}const obj2 =deepClone(obj1)
    obj2.name ='李四'
    obj2.age.realAge =22
    obj2.arr[0]='x'
    console.log(obj1.name)// 张三
    console.log(obj1.age.realAge)// 20
    console.log(obj1.arr[0])// a

Object.assign()

  • assign 的属性拷贝是浅拷贝
  • 用于将源对象的所有可枚举属性复制到目标对象中
  • 如果目标对象和源对象有同名属性,或者多个源对象有同名属性,则后面的属性会覆盖前面的属性
  • 如果该函数只有一个参数,当参数为对象时,直接返回该对象;当参数不是对象时,会先将参数转为对象然后返回
let sourceObj ={a:{b:1}}let targetObj ={c:3}let res = Object.assign(targetObj, sourceObj)
    console.log(res)// {c: 3, a: {b: 2}}
    targetObj.a.b =2
    console.log(sourceObj.a.b)// 2

在这里插入图片描述

了解 RAF requestAnimationFrame

  • 要想动画流畅,更新频率要60帧/s,即 16.67ms 更新一次视图
  • setTimeout 要手动控制频率,而 RAF 浏览器会自动控制
  • 后台标签或隐藏 iframe 中,RAF 会暂停,而 setTimeout 不会停止
    #div1 {width: 100px;height: 50px;
        background-color: red;}<div id="div1"></div>const div1 = document.getElementById('div1')let curWidth =100const maxWidth =640functionanimate(){
        curWidth = curWidth +1
        
        div1.style.width =`${curWidth}px`if(curWidth <= maxWidth){
            window.requestAnimationFrame(animate)}}animate()

RAF

优化性能的考虑方面

  • 原则:多使用内存、缓存、减少计算、减少网络请求
  • 方向:加载页面更快,页面渲染更快,页面操作流畅度更好

Map 和 Object 的区别

须知:有序和无序

  • 有序:操作慢
  • 无序:操作快,但无序
  • map、数组是有序的,对象是无序的
  • 结合两者优点:二叉树

Map 和 Object 的区别

  • API 不同,Map 可以以任意类型为 key
  • Map 是有序结构
  • Map 操作同样很快

基本 API:

  • 增改:set
  • 删:delete
  • 长度:size

示例:基本 API(set、delete、size)

const m =newMap([['key1','hello'],['key2',100],['key3',{x:100}]])
    console.log('原始 m', m)
    m.set('name','张三')
    console.log('添加张三', m)
    m.set('key1','hello world')
    console.log('修改 key1', m)
    m.delete('key2')
    console.log('删除 key2', m)
    console.log('有无 key3', m.has('key3'))
    m.forEach((value, key)=> console.log('遍历结果', key, value))
    console.log('m 的长度', m.size)

在这里插入图片描述

  • Map 可以以任意类型为 key
  • 对象只能以字符串作为 key
const m =newMap([['key1','hello'],['key2',100],['key3',{x:100}]])// Map 以任意类型为 keyconst o ={name:'xxx'}
    m.set(o,'object key')functionfn(){}
    m.set(fn,'fn key')
    console.log(m)

在这里插入图片描述

object 有多快?

示例:查找第500万个元素的用时(object)

const obj ={}for(let i =0; i <1000*10000; i++){
        obj[i +'']= i
    }
    console.time('obj find')
    obj['5000000']
    console.timeEnd('obj find')
    console.time('obj delete')delete obj['5000000']
    console.timeEnd('obj delete')

在这里插入图片描述

map 有多快?

示例:查找第500万个元素的用时(map)

const m =newMap()for(let i =0; i <1000*10000; i++){
        m.set(i +'', i)}
    console.time('map find')
    m.has('500000')
    console.timeEnd('map find')
    console.time('map delete')
    m.delete('500000')
    console.timeEnd('map delete')

在这里插入图片描述
可见,都在一个数量级上,相差无几

Set 和 数组的区别

  • API 不同
  • Set 元素不能重复
  • Set 是无序结构,操作很快

示例:set 的 API

  • add 添加
  • delete 删除
  • has 是否有
  • size 长度
const set =newSet([10,20,30])
    console.log('初始值', set)
    set.add(40)
    console.log('添加40', set)
    set.delete(10)
    console.log('删除10', set);
    set.has(30)let length = set.size
    console.log('长度', length);
    set.forEach(val=> console.log('遍历set', val))

在这里插入图片描述

示例:数组去重

  • set 元素是不能重复的(数组去重)
const arr =[10,20,20,30,10]
    console.log(newSet(arr))

在这里插入图片描述

示例:数组有多慢?set 有多快?

  • 新增一条数据
// arr 有多慢?const arr =[]for(let i =0; i <100*10000; i++){
        arr.push(i)}
    console.time('arr unshift')
    arr.unshift('a')
    console.timeEnd('arr unshift')// set 有多快?const set =newSet()for(let i =0; i <100*10000; i++){
        set.add(i)}
    console.time('set add')
    set.add('a')
    console.timeEnd('set add')

在这里插入图片描述

  • 查找 500000,这个元素
// arr 有多慢?const arr =[]for(let i =0; i <100*10000; i++){
        arr.push(i)}
    console.time('arr find')
    arr.includes(500000)
    console.timeEnd('arr find')// set 有多快?const set =newSet()for(let i =0; i <100*10000; i++){
        set.add(i)}
    console.time('set find')
    set.has(50000)
    console.timeEnd('set find')

在这里插入图片描述

WeakMap 和 WeakSet

  • 弱引用,防止内存泄露
  • WeakMap 只能用对象作为 key,WeakSet 只能用对象作为 value
  • 没有 forEach 和 size,只能用 add delete has

WeakMap:

  • WeakMap 弱引用,可防止内存泄露
  • 没有 forEach,size(因为和 key有关,对象不知道什么时候就没了),只能 has delete add

示例:

const wMap =newWeakMap()functionfn(){const obj ={name:'张三'}
        wMap.set(obj,'name info')// 只能用对象作为 key}fn()

在这里插入图片描述
WeakMap 使用场景(避免内存泄露):

// WeakMap 场景(避免内存泄露)const wMap =newWeakMap()const userInfo ={name:'张三'}const cityInfo ={city:'北京'}// 建立一种关联关系,而且两者保持独立,不影响彼此的销毁逻辑
    wMap.set(userInfo, cityInfo)let res = wMap.get(userInfo) 
    console.log(res)
    console.log(userInfo)

在这里插入图片描述
WeakSet

  • WeakMap 弱引用,可防止内存泄露,只能用对象作为 value
  • 没有 forEach,size(因为和 key有关,对象不知道什么时候就没了),只能 has delete add

reduce 的使用

传统方法求和

  • 封装一个 sum 函数
  • 初始化 sum,通过 forEach 遍历数组
  • 返回 sum
functionsum(arr){let sum =0
        arr.forEach(item=> sum += item)return sum
    }const arr =[1,2,3]let res =sum(arr)
    console.log(res)// 6

reduce 传递的参数

  • sum 当前和
  • curVal 当前值
  • index 索引
  • arr 数组
const arr =[1,2,3]const res = arr.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)// 返回值,作为下一次执行时的第一个参数 sum 的值return sum + curVal 
    },0)
    console.log(res)

在这里插入图片描述
reduce 求和

const arr =[1,2,3]const res = arr.reduce((sum, curVal)=> sum + curVal,0)
    console.log(res)// 6

reduce 计数

// 计数const arr =[10,20,30,20,30,10]const n =10const count = arr.reduce((count, val)=>{return val === n ? count +1: count
    },0)
    console.log('count', count)// count 2

输出字符串

示例:map 写法

// 输出字符串const arr =[{name:'张三',age:'20'},{name:'李四',age:'21'},{name:'王五',age:'22'},]const str = arr.map(item=>{return`${item.name} - ${item.age}`}).join('\n')
    console.log(str)

在这里插入图片描述

示例:reduce 写法

// 输出字符串const arr =[{name:'张三',age:'20'},{name:'李四',age:'21'},{name:'王五',age:'22'},]const str = arr.reduce((s, item)=>{return`${s}${item.name} - ${item.age}\n`},'')
    console.log(str)

在这里插入图片描述

再次声明:全篇近两万字,耗时五天完成。涵盖了JavaScript 面试高频考点,码字不易,如果对你有帮助,还请多多支持!(期待你的一键三连【点赞、收藏+关注】)

不积跬步无以至千里 不积小流无以成江海

点个关注不迷路,持续更新中…


本文转载自: https://blog.csdn.net/qq_45902692/article/details/126240337
版权归原作者 前端杂货铺 所有, 如有侵权,请联系我们删除。

“web前端面试宝典——带你直击面试重难点(40个经典题目,涵盖近90%的考点,码字2w,干货满满!)”的评论:

还没有评论