前端高频面试题—JavaScript篇(三)

💻 前端高频面试题-JavaScript篇(三)🏠专栏:前端面试题
👀个人主页:繁星学编程🍁
🧑个人简介:一个不断提高自我的平凡人🚀
🔊分享方向:目前主攻前端,其他知识也会阶段性分享🍀
👊格言:☀️没有走不通的路,只有不敢走的人!☀️
👉让我们一起进步,一起成为更好的自己!!!🎁

前端高频面试题—JavaScript篇(三)

本文主要讲述的前端高频面试题知识有:

  1. 闭包
  2. 垃圾回收机制
  3. 防抖和节流
  4. 函数柯理化
  5. 浅拷贝和深拷贝的区别
  6. 讲讲事件冒泡和事件捕获以及事件代理

一. 闭包

1.闭包的概念

闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中,闭包会随着函数的创建而被同时创建。

词法(lexical)一词指的是,词法作用域根据源代码中声明变量的位置来确定该变量在何处可用。嵌套函数可访问声明于它们外部作用域的变量。

闭包:函数内的函数

有权访问另一个函数作用域内变量的函数都是闭包。

目的:在函数外部操作函数里面的私有变量(起到保护全局变量的作用)

2. 闭包条件

  1. 需要一个不会被销毁的函数执行空间
  2. 需要直接或间接返回一个函数
  3. 内部函数使用外部函数的私有变量

特点

  1. 可以在函数外面访问到函数内部的变量
  2. 延长了变量的生命周期
  3. 内存溢出

浏览器的垃圾回收机制 : 计数 和 标记

当变量进入环境,要么计数要么给个标记, 如果计数为0, 或者标记为离开环境,垃圾回收机制进行回收,如果无法回收,形成内存溢出。

3.闭包的应用

函数柯理化、函数防抖

了解更多详细知识请跳转【JavaScript】深浅拷贝及闭包详解_繁星学编程的博客-CSDN博客

二. 闭包的问题(垃圾回收机制)

  1. 垃圾回收机制(Garbage Collction)简称GC,是JavaScript中使用的内存管理系统的基本组部分,是为了防止内存泄漏
  2. JavaScript是在创建变量(对象、字符串等)时自动进行了分配内存,并且在不使用他们时“自动释放。”
  3. 内存在不适用的时候就被垃圾回收器自动回收

内存的生命周期

JS环境中分配的内存,一般有如下生命周期:

  1. 内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
  2. 内存使用:即读写内存,也就是使用变量、函数等
  3. 内存回收:使用完毕,由垃圾回收自动回收不再使用的内存

垃圾回收的算法说明

所谓垃圾回收,核心思想就是如何判断内存是否已经不再会被使用了,如果是,就视为垃圾给释放掉

下面介绍两种常见的浏览器垃圾回收算法:引用计数法和标记清除法

1.引用计数

IE采用的引用计数算法,定义“内存不再使用”的标准很简单,就是看一个对象是否有指向它的引用

算法

  1. 跟踪记录每个值被引用的次数。
  2. 如果这个值被引用了一次,那么就会被记录一次。
  3. 多次引用会累加。
  4. 如果减少一个引用就减1。
  5. 如果引用次数是0,则释放内存。

缺点:循环引用

如果两个对象对象互相引用,尽管他们已不再使用,垃圾回收器不会进行回收,导致内存泄漏。

2.标记清除法

现代的浏览器已经不再使用引用计数法了

现代浏览通用的大多是基于标记清除算法的某些改进算法,总体思想都是一致的

核心:

  1. 标记清除算法将“不再使用的对象”定义为“无法达到的对象”。
  2. 标记:就是从根部(在js中就是全局对象)出发定时扫描内存中的对象。凡是能从根部到达的对象,都是还需要使用的。
  3. 回收:那些无法由根部出发触及到的对象被标记为不再使用。

参考文献垃圾回收机制

三. 防抖和节流

(1). 函数防抖

通过setTimeout的方式,在一定的时间间隔内,将多次触发变成一次触发。(通俗的说是在最后一次点击间隔规定时间之后才能再次成功触发,否则触发不成功)

防抖的实现思路

  1. 在防抖函数返回的函数的上级作用域设置一个定时器变量t置为null;
  2. 通过t来判断是否是第一次执行。
  3. 如果不是第一次执行,清空定时器
  4. 如果是第一次执行,则通过进行代码执行.
  5. 最后设置定时器,规定时间之后将t设置为null,使得间隔时间之后t为null,间隔时间之后的点击变为第一次点击。

(2). 函数节流

节流指的是减少一段时间内的触发频率。只有在上一次成功触发间隔规定时间之后,才能再次触发。

节流的实现思路

  1. 在返回函数的上级作用域定义一个初始标记flag = false;
  2. 通过判断flag 是否=== true来确定是否已经触发
  3. 如果已经触发(flag === true),则中断函数
  4. 如果没有触发(flag === false),则让flag = false执行代码,执行后将flag = true

(3). 节流与防抖的区别是什么?

  1. 防抖只在最后一次成功点击之后间隔规定时间之后才能再次成功触发,如果在时间间隔之内就被点击,需要重新间隔时间间隔才能点击。
  2. 节流则不同,节流只要在上一次成功触发规定时间之后点击就能再次触发,中间的触发不会产生影响。

了解更多详细知识请跳转【JavaScript】防抖、节流和函数柯理化_繁星学编程的博客-CSDN博客

四. 函数柯里化

作用:把一次传递两个参数,变成两次每次传递一个参数

目的:利用闭包,把第一次传递的参数保存下来(延长变量的生命周期)

function add(num1) {
    return function (num2) {
        return num1 + num2;
    }
}
console.log(add(1));
/*
        ƒ (num2) {
                return num1 + num2;
            }
        */
console.log(add(1)(2)); // 3

了解更多详细知识请跳转【JavaScript】防抖、节流和函数柯理化_繁星学编程的博客-CSDN博客

五. 浅拷贝和深拷贝的区别

(1) 赋值

赋值:把一个数据结构的地址复制一份给另一个变量

(2) 浅拷贝

浅拷贝:原先是什么数据结构,创建一个一模一样的数据结构

依次遍历原始数据结构,把每一个数据复制一份放到新的数据结构内(只能拷贝一次数据结构)
原始数据结构中的key

  • 存储的是基本数据类型,可以拷贝
  • 存储的是引用数据类型无法拷贝
Object.assign

语法:Object.assign(新对象,原始对象)

返回值:把原始对象内的数据浅拷贝一份放入到新对象中

(3) 深拷贝

深拷贝:不管多少层数据结构,都百分百复制一份,变成两个一模一样但是毫不相干的数据结构

实现方式:

  • 方式一:递归
  • 方式二:利用JSON的方法

了解更多详细知识请跳转【JavaScript】深浅拷贝及闭包详解_繁星学编程的博客-CSDN博客

六. 讲讲事件冒泡和事件捕获以及事件代理

首先DOM事件流有三个阶段:

  1. 事件捕获
  2. 事件处理
  3. 事件冒泡

事件捕获:当鼠标点击或者触发DOM事件时,浏览器会从根节点开始由外到内进行传播。(也就是说会从外部元素开始向内部元素依次向内捕获)

事件冒泡:事件有内向外进行传导,当后代元素身上的事件被触发时,外层祖先元素上同类型事件也会触发

事件代理:把子元素上的事件交给父元素来绑定
作用:在父元素的事件内,可以通过e.target来判断准确触发事件的元素

addEventListener

addEventListener的第三个参数就是为冒泡和捕获准备的。

addEventListener有三个参数:

element.addEventListener(event, function, useCapture)
  • 第一个参数是需要绑定的事件
  • 第二个参数是触发事件后要执行的函数
  • 第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数;如果参数为true,则表示在事件捕获阶段调用处理函数。

结束语

希望对您有一点点帮助,如有错误欢迎小伙伴指正。
👍点赞:您的赞赏是我前进的动力!
⭐收藏:您的支持我是创作的源泉!
✍评论:您的建议是我改进的良药!
一起加油!!!💪💪💪

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁星学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值