前端面试题 · JS笔记

注:本文内容源于 哔哩哔哩 up主: 说人话的前端

防抖和节流有什么区别?手写防抖与节流

防抖与节流的共同点、区别及应用场景

防抖与节流的共同点、区别及应用场景

代码实现

<body>
	<h3>防抖</h3>
    <input type="text" />
</body>
<script>
    const oInp = document.querySelector("input")

    oInp.addEventListener("keyup", debounce(function () {
        console.log(oInp.value + "发送请求")
    }))

    function debounce(fn) {
        let timer = null

        return function () {
            if (timer) clearTimeout(timer)
            timer = setTimeout(() => {
                fn.apply(this, arguments)
                timer = null
            }, 1000)
        }
    }
</script>
<body>
	<h3>节流</h3>
    <div draggable="true"></div>
</body>
<script>
    const oDiv = document.querySelector("div")

    oDiv.addEventListener("drag", throttle(function (e) {
        console.log(e.clientX)
    }))

    function throttle(fn) {
        let timer = null

        return function () {
            if (timer) return
            timer = setTimeout(() => {
                fn.apply(this, arguments)
                timer = null
            }, 1000)
        }
    }
</script>

什么是宏任务?什么是微任务?二者有什么区别?

什么是微任务?什么是宏任务?

微任务:Promise、async await
宏任务:setTimeout、setInterval、Ajax、DOM事件

二者的区别

先执行微任务,后执行宏任务

宏任务、微任务、DOM渲染的关系

1.Call Stack清空,触发Event Loop
2.执行微任务
3.DOM渲染
4.执行宏任务

完整Event Loop过程

完整Event Loop过程

Promise代码题

知识点

  • JS 执行顺序:自上而下、先同步再异步、先微任务后宏任务
  • new Promise() → Promise.resolve()
  • then 和 catch 内部没有 throw new Error 相当于 resolve
  • async function 相当于返回 Promise.resolve()
  • await 后面的代码都是异步的

for…in、for…of 有什么区别

for..in和for..of 的区别

是否可枚举:Object.getOwnPropertyDescriptors(obj) -> enumerable: true
是否可迭代:arr[Symbol.iterator] () -> next()

扩展问题

for await … of 有什么作用?
出题目的:考察对异步的掌握情况
for await … of 用于遍历一组Promise
知识点
for await … of 逐个返回结果
Promise.al 返回一组结果

var、let 和 const 有什么区别?

var、let 和 const 的区别

1.块级作用域
var 没有块级作用域,let 和 const 有块级作用域
2.变量提升
var 有变量提升,let 和 const 没有变量提升
暂时性死区报错:let/const 会先被创建出来,但还未绑定值,所以不能用
3.重名
var允许重名,let 和 const 不允许重名(同一个作用域下)

说说原型和原型链是怎么回事?

复习class基础语法

  • class
  • construct
  • extends
  • super
  • in stanceof

什么是原型

显示原型与隐式原型
实例的隐式原型 === 类的显式原型

什么是原型链

原型链图解

手写 instanceof

知识点

instanceof

  • instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
  • 可以判断继承关系,只要是在同一条原型链上,就可以返回 true

代码实现

while (true) {
    if (obj1Proto === null) {
        return false
    } else if (obj1Proto === obj2Proto.prototype) {
        return true
    }
    obj1Proto = obj1Proto.__proto__
}

手写 bind

知识点

  • Function.prototype.myBind 挂载到函数原型上 fn.myBind
  • Array.prototype.slice.call() 转为数组
  • arg.shift() 返回下标为0的元素

代码实现

Function.prototype.myBind = function () {
    const fn = this
    const arg = Array.prototype.slice.call(arguments)
    const _this = arg.shift()
    return function () {
        return fn.apply(_this, arg)
    }
}

this 不同场景如何取值?

普通函数中的 this

  • 严格模式下 this是undefined
  • 非严格模式 this是window

call apply bind 中的 this

情况1 this是window
以 call 为例,bind、apply同理

  • a.call()
  • a.call(undefined)
  • a.call(null)
    情况2 传什么 this就是什么
  • a.apply(‘abc’)
  • a.call(123)
  • const fn = a.bind({x:101}) fn()

定时器中的 this

情况1 定时器 + function
this 是 window
情况2 定时器 + 箭头函数
this 是上层作用域的 this

箭头函数中的 this

  • 有 function 作用域的,this 是上层作用域的 this
  • 没有 function 作用域的,this 是 window

值类型与引用类型有什么区别

值类型

  • String
  • Number
  • Boolean
  • Symbol

引用类型

  • Json
  • Array
  • null

手写深拷贝

JSON.parse(JSON.Stringfy(obj))

不能存放函数、时间对象、正则等

递归

没有考虑循环引用

function deepClone(obj) {
    if (typeof (obj) !== "Object" || obj == null) {
        return obj
    }

    let res = obj instanceof Array ? [] : {}

    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            res[key] = deepClone(obj[key])
        }
    }

    return res
}

lodash.cloneDeep

推荐使用 工作中没必要重复造轮子

何时使用 == ,何时使用 ===

== 会产生隐式类型转换

100 == '100'
0 == ''
0 == false
false == ''
null == undefined

只有obj == null 使用双等

相当于

if (obj === bull || obj === undefined) {
}

什么是truly变量?什么是falsely变量?

truly变量

!!val === true

falsely变量

!!val === false

除了以下五种falsely变量,都是truly变量

  • 数字0
  • NaN
  • 空字符串
  • null
  • undefined

什么是闭包

概念

闭包是作用域的一种特殊应用

触发闭包的情况

1、函数当做返回值被返回
2、函数当做参数被传递
3、自执行匿名函数

闭包的应用

1、隐藏变量
2、解决 for i 的问题

作用域

全局作用域、局部作用域

自由变量

不在自己作用域里的变量,就是自由变量
自由变量的值:在函数定义的地方向上层作用域查找。与函数调用位置无关

手写 flat 方法拍平数组

知识点

Array.concat

  • Array.concat(1,2,[3,4,5])

判断是不是数组

  • xxx instanceof Array
function flat(arr) {
    while (arr.some((item) => item instanceof Array)) {
        arr = Array.prototype.concat.apply([], arr)
    }
    return arr
}

数组去重

set方法

function unique(arr) {
    const set = new Set(arr)
    return [...set]
}

forEach + indexOf

function uniq(arr) {
    const res = []
    arr.forEach(item => {
        if (res.indexOf(item) === -1) {
            res.push(item)
        }
    });
    return res
}

求数组最大值

  • Math.max
function getMax(arr) {
    return Math.max(...arr)
    return Math.max.apply(null, arr)
}
  • Array.sort
function getMax(arr) {
    arr.sort((n1, n2) => {
        return n2 - n1
    })
    return arr[0]
}
  • Array.reduce
function getMax(arr) {
    arr.reduce((n1, n2) => {
        return n1 > n2 ? n1 : n2
    })
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值