八股文(一)

news2024/12/25 12:32:14

一、箭头函数和普通函数有什么区别

(1)箭头函数比普通函数更加简洁

(2)箭头函数没有自己的this

箭头函数不同于传统JavaScript中的函数,箭头函数并没有属于⾃⼰的this,它所谓的this是捕获其所在上下⽂的 this 值,作为⾃⼰的 this 值,并且由于没有属于⾃⼰的this,所以是不会被new调⽤的,这个所谓的this也不会被改变

(3)箭头函数继承来的this指向永远不会改变

var id = 'GLOBAL';
var obj = {
  id: 'OBJ',
  a: function(){
    console.log(this.id);
  },
  b: () => {
    console.log(this.id);
  }
};
obj.a();    // 'OBJ'
obj.b();    // 'GLOBAL'
new obj.a()  // undefined
new obj.b()  // Uncaught TypeError: obj.b is not a constructor

(4)call()、apply()、bind()等方法不能改变箭头函数中this的指向

var id = 'Global';
let fun1 = () => {
    console.log(this.id)
};
fun1();                     // 'Global'
fun1.call({id: 'Obj'});     // 'Global'
fun1.apply({id: 'Obj'});    // 'Global'
fun1.bind({id: 'Obj'})();   // 'Global'

(5)箭头函数不能作为构造函数使用 (在JavaScript中,用new关键字来调用的函数,称为构造函数,构造函数首字母一般大写)

  • 由于箭头函数时没有自己的this,且this指向外层的执行环境,且不能改变指向,所以不能当做构造函数使用。

  • 构造函数是通过new关键字来生成对象实例,生成对象实例的过程也是通过构造函数给实例绑定this的过程,而箭头函数没有自己的this。创建对象过程,new 首先会创建一个空对象,并将这个空对象的proto指向构造函数的prototype,从而继承原型上的方法,但是箭头函数没有prototype。因此不能使用箭头作为构造函数,也就不能通过new操作符来调用箭头函数。

原型和原型链具体可看这篇文章JS的基础知识学习(二)(原型和原型链的基础理论)_七小山的博客-CSDN博客

函数 - prototype - 对象(函数的prototype)

对象 - 对象._proto -对象(函数大的prototype)

(6)箭头函数没有自己的arguments

arguments,它是js中函数内置的一个对象,而执行函数方法的实参中值都存储在arguments中;要想获取到这些实参,就需要像 数组 一样,用下标/索引来定位到每个值上面,但是又不能说它是一个数组,因为它里面还有其他的属性,如callee; 并且不能对它使用shift、push、join等方法。而没有传递值的命名参数将会被自动赋予undefined;

arguments.length----参数个数

arguments.callee()---调用自身

 

箭头函数没有自己的arguments对象。在箭头函数中访问arguments实际上获得的是它外层函数的arguments值。

二、 讲讲promise

1、 promise的3种状态和状态转换

(1)promise状态

pending(等待) fullfilled(已完成) rejected(已拒绝)

(2)先看下三种状态的产生

pending状态的Promise

const promise1 = new Promise((resolve,reject) => {
 
})
console.log(promise1);
​

fulfilled状态的Promise

const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve()
    })
})
console.log(promise1);

 

rejected状态的Promise

const promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            reject();
        })
    });
    console.log(promise);
​

(3)从pending状态到fulfilled状态的变化过程

resolve()后状态从pending变为了fulfilled

const promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('resolve前Promise的状态:',promise);
            resolve();
            console.log('resolve后Promise的状态:',promise);
        })
    });

 

(4)从pending状态到rejected状态的变化过程

reject()后状态从pending变为了rejected

const promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log("Promise的状态:reject前:",promise);
            reject();
            console.log("Promise的状态:reject后:",promise);
        })
    });
​

 

 

未调用resolve或者reject时候处于pending状态,调用resolve后处于fullfilled状态,调用reject后处于rejected状态。如果在pending状态时候,执行任务抛出错误,则变成reject状态。 状态变化后,会执行通过then注册的回调。执行顺序和调用then方法的顺序相同。 调用then方法时候,如果状态是pending则注册回调,等到状态改变时候执行,如果状态已经改变则执行相应的回调。

状态一旦改变,就无法再次改变状态,这也是它名字 promise-承诺 的由来,一个promise对象只能改变一次

const p = new Promise((resolve, reject) => {
    resolve('test');
});
​
p.then(
    data => console.log(1, 'resolve', data),
  data => console.log(1, 'reject', data)
);
​
p.then(
    data => console.log(2, 'resolve', data),
  data => console.log(2, 'reject', data)
);
​
// 执行结果
1 "resolve" "test"
2 "resolve" "test"
const p = new Promise((resolve, reject) => {
  throw new Error('test-error');
  // 由于抛出错误,promise状态已经改变为rejected,再调用resolve将不会改变promise状态
    resolve('test');
});
​
p.then(
    data => console.log(1, 'resolve', data),
  data => console.log(1, 'reject', data)
);
​
p.then(
    data => console.log(2, 'resolve', data),
  data => console.log(2, 'reject', data)
);
​
// 执行结果
1 "reject" Error: test-error
2 "reject" Error: test-error

2、 Promise中回调函数是同步的还是异步的?

  • 回调函数是 什么

    一个函数A,作为另一个函数B的参数,那么函数A就被称为回调函数

  • promise本身 —同步

let obj=new Promise((res,rej)=>{
     console.log('这是promise对象');
});
console.log('哼哼');

 

  • promise的回调函数then --异步

let obj=new Promise((res,rej)=>{
      console.log('这是promise本身');
      res('这是回调函数then的值')
    });
    obj.then((res) => {
      console.log(res);
    });
    console.log('哼哼');

 

3、then的链式调用是同步的还是异步的?

   // 链式调用
        p.then(value => {
 
        }).then(value => {
 
        });

同步

4、catch和then

catch方法和then方法的reject回调用法相同,如果这时候任务处于rejected状态,则直接执行catch,catch的参数就是reject的reason;如果任务处于pending状态,则注册catch回调,等到状态变成rejected时候再执行。

Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数

p.then((val) => console.log('fulfilled:', val))
  .catch((err) => console.log('rejected', err));
​
// 等同于
p.then((val) => console.log('fulfilled:', val))
  .then(null, (err) => console.log("rejected:", err));

三、 apply、bind、call

说下call、apply、bind方法的作用和区别?

具体可以看这篇文章call,apply,bind三者的区别_call和apply及bind三者的区别_七小山的博客-CSDN博客

  • call、apply、bind都是用来改变this指向的,

  • call和apply调用时候立即执行,bind调用不会立即执行而是会返回新的函数。

  • 当需要传递参数时候,call直接写多个参数,apply将多个参数写成数组。

  • bind在绑定时候需要固定参数时候,也是直接写多个参数

  • call和apply第一个参数obj正常都是传入的this,若是没有传,则默认是windows

     let obj = {
                name:'张三',
                age:18,
                func:function(){
                    console.log(this.name + "年龄" + this.age);
                }
            }
            let obj2 = {
                name:'李四',
                age:20
            }
            obj.func.call(obj2) //李四年龄20
            obj.func.apply(obj2); //李四年龄20
            obj.func.bind(obj2)(); //李四年龄20

    这三个结果都一样 bind后面多一个括号是因为 bind返回值是一个函数加上()编程立即执行函数

四、 typescript泛型

泛型,顾名思义,就是可以适用于多个类型,使用类型变量比如T帮助我们捕获传入的类型,之后我们就可以继续使用这个类型。

本质是参数化类型,通俗的将就是所操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和函数的创建中,分别成为泛型类泛型接口泛型函数

(1)泛型-泛型函数

function fn<Type>(value: Type): Type { return value }
// 上面的Type只是一个名字而已,可以改成其他的
 
function fn<T>(value: T): T { return value }

语法:在函数名称的后面写 <>(尖括号),尖括号中添加类型变量,比如此处的 Type。

类型变量 Type,是一种特殊类型的变量,它处理类型而不是值

该类型变量相当于一个类型容器,能够捕获用户提供的类型(具体是什么类型由用户调用该函数时指定)

因为 Type 是类型,因此可以将其作为函数参数和返回值的类型,表示参数和返回值具有相同的类型

类型变量 Type,可以是任意合法的变量名称

调用泛型函数的格式

const num = fn<number>(10)
const str = fn<string>('a')

这样,通过泛型就做到了让 id 函数与多种不同的类型一起工作,实现了复用的同时保证了类型安全

(2)泛型-类型推断简化函数调用

function fn<T>(value: T): T { return value }
// 省略 <number> 调用函数
let num = fn(10)
let str = fn('a')
  • 在调用泛型函数时,可以省略 <类型> 来简化泛型函数的调用

  • 此时,TS 内部会采用一种叫做类型参数推断的机制,来根据传入的实参自动推断出类型变量 Type 的类型

  • 比如,传入实参 10,TS 会自动推断出变量 num 的类型 number,并作为 Type 的类型

  • 推荐:使用这种简化的方式调用泛型函数,使代码更短,更易于阅读

  • 说明:当编译器无法推断类型或者推断的类型不准确时,就需要显式地传入类型参数

(3)总结

定义一个函数或类时,有些情况下无法确定其中要使用的具体类型(返回值、参数、属性的类型不能确定,此时泛型便能够发挥作用。

五、 JavaScript 防抖和节流

1、防抖与节流是什么

本质上是优化高频率执行代码的一种手段

如:浏览器的 resize、scroll、keypress、mousemove 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能

为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用 防抖(debounce) 和 节流(throttle) 的方式来减少调用频率

  • 防抖:就是一定时间内,只会执行最后一次任务;

  • 节流:就是一定时间内,只执行一次 ;

定义

(1)防抖:n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时

防抖具体指的是某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次。假如我们设置了一个等待时间 3 秒的函数,在这 3 秒内如果遇到函数调用请求就重新计时 3 秒,直至新的 3 秒内没有函数调用请求,此时执行函数,不然就以此类推重新计时

防抖实现原理就是利用定时器,函数第一次执行时设定一个定时器,并且通过闭包缓存起来,之后调用时发现已经设定过定时器就清空之前的定时器,并重新设定一个新的定时器,如果存在没有被清空的定时器,当定时器计时结束后触发函数执行。

(2)节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效

函数节流指的是某个函数在一定时间间隔内(例如 3 秒)只执行一次,在这 3 秒内 无视后来产生的函数调用请求,也不会延长时间间隔。3 秒间隔结束后第一次遇到新的函数调用会触发执行,然后在这新的 3 秒内依旧无视后来产生的函数调用请求,以此类推。函数节流非常适用于函数被频繁调用的场景,例如:window.onresize() 事件、mousemove 事件、上传进度等情况。

实现原理就是通过一个布尔类型变量来判断是否可执行回调,当变量为true时,生成一个定时器,同时将变量取反通过闭包保存起来,当定时器执行完回调后,再将变量变为true,在变量为期false间,调用节流函数不会生成定时器。

2、防抖案例

(1)搜索

<button id="debounce">搜索!</button>
​
<script>
     const dd = document.querySelector("#debounce");
      dd.addEventListener("click", debounce());
​
      function debounce() {
        let timer; // 使用闭包,多次调用都能访问到同一个变量,而不是生成新的变量
        return function () {
        // 每次当用户点击/输入的时候,把前一个定时器清除
          clearTimeout(timer);
          timer = setTimeout(() => {
           // 然后创建一个新的 setTimeout,
        // 这样就能保证点击按钮后的 interval 间隔内
       // 如果用户还点击了的话,就不会执行 定时器里面的内容
            // 需要防抖的操作...
            console.log("防抖成功!");
          }, 500);
        };
      }
</script>

​(2)滚动

 let timer;
      window.onscroll = function () {
        console.log(
          "上一个定时器的序号" +
            timer +
            "滚动" +
            document.documentElement.scrollTop
        );
        clearTimeout(timer);
​
        timer = setTimeout(function () {
          //滚动条位置
          let scrollTop =
            document.body.scrollTop || document.documentElement.scrollTop;
          console.log("滚动条位置:" + scrollTop);
        }, 500);
      };

 

3、节流案例

(1)搜索点击

<button id="throttle">点我节流!</button>
​
<script>
    $('#throttle').on('click', throttle());
    
    function throttle(fn) {
        let flag = true;
        // 使用闭包,方法多次调用都能访问到同一个变量,而不是生成新的flag变量
        return function () {
            if (!flag) { return; }
            flag = false;
            setTimeout(() => {
                console.log("节流成功!");
                flag = true;
            }, 1000);
        };
    }
</script>
​

4、总结

(1)防抖

单位时间内,频繁触发事件,只执行最后一次

典型场景:搜索框搜索输入

代码思路是利用定时器,每次触发先清掉以前的定时器(从新开始)

(2)节流

单位时间内,频繁触发事件,只执行一次

典型场景:高频事件快速点击、鼠标滑动、resize事件、scroll事件

代码思路也是利用定时器,等定时器执行完毕,才开区定时器(不要打断)


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/384211.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

希赛PMP模拟题2022(第9套)

希赛PMP模拟题2022&#xff08;第9套&#xff09; 22 需求和范围 区别 21 什么阶段&#xff1f; 在开发过程中不断衡量 价值 和优先级关系排序20 产品路线图 回顾 团队沟通方式 无法面对面沟通时候 其他人参与 了解项目 需求发布计划 风险 排序发表计划 vs 评审会议 老母鸡 是…

ESP-C3入门14. 实现基本的web server

ESP-C3入门14. 实现基本的web server一、ESP32 IDF创建WEB SERVER的流程1. 配置web服务器2. 注册 URI处理器3. 实现 URI处理器函数4. 处理HTTP请求5. 处理web socket连接6. 注册 URI 处理函数7. 启动HTTP服务器8. 发送响应9. 关闭 http 服务二、本要主要使用API的说明1. httpd_…

编码器的作用和功能有哪些

编码器的作用和功能有哪些 最近很多咨询编码器的作用的&#xff0c;小编结合一下线上和线下的资料&#xff0c;总结了一下&#xff0c;供大家参考。 要说编码器&#xff0c;它的作用很多&#xff0c;主要是用来测量机械运动的速度、位置、角度、距离或计数的&#xff0c;编码器…

SkyWalking使用案例-2

文章目录SkyWalking实现基于容器环境Dubbo微服务链路跟踪部署Dubbo Provider构建Dubbo Provider镜像运行dubbo-provider部署Dubbo Consumer构建Dubbo Consumer镜像运行dubbo-consumer验证SkyWalking收集python项目数据Skywalking告警Skywalking指标Skywalking告警规则SkyWalkin…

62. 不同路径

62. 不同路径 一个机器人位于一个 m∗nm * nm∗n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路…

virtualbox7虚拟机中安装苹果macOS big sur系统详细教程

第1步&#xff0c;在 Windows 10/11 PC 上启用虚拟化。 现在的电脑一般都默认开启虚拟化技术了。 如果你遇到一些报错&#xff0c;比如收到错误消息“无法在虚拟机上打开会话”&#xff0c;可以查看 如果没有遇到问题&#xff0c;可以直接进入到第二步。 第2步&#xff0c;在…

【Spark分布式内存计算框架——Spark Streaming】12. 偏移量管理(上)代码重构与Checkpoint 恢复

6. 偏移量管理 针对前面实现【百度热搜排行榜Top10】实时状态统计应用来说&#xff0c;当应用关闭以后&#xff0c;再次启动&#xff08;Restart&#xff09;执行&#xff0c;并没有继续从上次消费偏移量读取数据和获取以前状态信息&#xff0c;而是从最新偏移量&#xff08;L…

JVM 不同垃圾回收器的日志格式分析

1、GC日志采集 在服务器上我们需要配置一些参数才能采集到历史的GC日志信息&#xff0c;这些参数通常在项目启动的时候就需要指定&#xff0c; 如果你项目是jar包&#xff0c;可以按照下面方式指定这些GC参数即可。 下面这些参数意思是把GC日志记录到/opt/app/abc-user/ard-…

蓝桥杯备赛——Echarts学习

文章目录前言学习 ECharts 的方法快速上手基础知识option 配置选项可选配置title 标题组件tooltip 提示框组件axisPointer 坐标轴指示器legend 图例组件toolbox 工具栏坐标轴xAxis和yAxisseries &#xff08;[ ]用数组表示,数组里是一个个数据对象&#xff09;饼状图散点图交互…

盘点代码情诗集合❤,程序员表白的巅峰之作,特此奉献

程序员怎么表白&#xff1f;写代码啊&#xff01;每到情人节&#xff0c;程序员们就纷纷出动&#xff0c;各种别出心裁的表白代码倾囊相送。我曾被大批表白代码砸晕&#xff0c;沉浸在“虚拟的”幸福感中不能自拔。我在众多代码中精选了以下几十条&#xff0c;每一条都是文学素…

Python中的遍历字典的键和值

一、Python的字典在项目的开发过程中&#xff0c;如果遇到有映射关系的内容可以考虑使用Python中的字典进行存储数据&#xff0c;字典中冒号前的数据称为【键】、冒号后的数据称为【值】。二、Python字典的用法2.1、Python的定义#Python字典的定义 字典名称{键1:值1,键2:值2,键…

JavaScript Date 日期对象

文章目录JavaScript Date 日期对象Date 对象Date 对象属性Date 对象方法创建日期设置日期两个日期比较JavaScript Date 日期对象 日期对象用于处理日期和时间。 Date 对象 Date 对象用于处理日期与实际。 创建 Date 对象&#xff1a; new Date(). 以上四种方法同样可以创建…

Validate端口使用手册

知行之桥EDI系统从2020版本开始引入了Validate端口&#xff0c;用来实现对XML数据文件进行一些规则的验证&#xff0c;保证XML数据文件的有效性。本文将介绍如何使用Validate端口。 端口创建 同其他功能性端口一样&#xff0c;只需要将Validata端口从左侧的端口清单拖拽到右侧…

子数组达到规定累加和的最大长度系列问题

文章目录1、题目一&#xff1a;正整数数组中子数组累加和 KKK 最大长度1.1 题目描述1.2 思路分析1.3 代码实现2、题目二&#xff1a;整数数组中子数组累加和为 KKK 的最大长度2.1 题目描述2.2 思路分析2.3 代码实现2.4 引申变形2.5 技巧应用题2.5.1 剑指 Offer II 010. 和为 k …

关于HTTP/3的小知识点

客户端用 TCP 发送了三个包&#xff0c;但服务器所在的操作系统只收到了后两个包&#xff0c;第一个包丢了。那么内核里的 TCP 协议栈就只能把已经收到的包暂存起来&#xff0c;“停下”等着客户端重传那个丢失的包&#xff0c;这样就又出现了“队头阻塞”。由于这种“队头阻塞…

Kubernetes之存储管理(中)

NFS网络存储 emptyDir和hostPath存储&#xff0c;都仅仅是把数据存储在pod所在的节点上&#xff0c;并没有同步到其他节点&#xff0c;如果pod出现问题&#xff0c;通过deployment会产生一个新的pod&#xff0c;如果新的pod不在之前的节点&#xff0c;则会出现问题&#xff0c…

CV——day81(1) 读论文: 基于自监督一致性学习的驾驶场景交通事故检测(有源码)

Traffic Accident Detection via Self-Supervised Consistency Learning in Driving Scenarios 基于自监督一致性学习的驾驶场景交通事故检测I. INTRODUCTIONIII. OUR APPROACHA. 帧预测B. 物体位置预测C. 驾驶场景上下文表示(DSCR)D. 协作多任务一致性学习E.交通事故判定IV. E…

UART串口通信协议

一、协议 1.1 消息格式 串口协议是一种全双工、异步通信协议&#xff0c;不需要同步时钟&#xff0c;数据的发送是一位一位的发送&#xff0c;完整的一帧数据通常由起始位、数据、奇偶校验位和停止位组成 1.2 波特率 为确保正确的收发信息&#xff0c;双方必须设置相同的波…

火山引擎 DataLeap:揭秘字节跳动数据血缘架构演进之路

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 DataLeap 是火山引擎数智平台 VeDI 旗下的大数据研发治理套件产品&#xff0c;帮助用户快速完成数据集成、开发、运维、治理、资产、安全等全套数据中台建设&#x…

MySQL 中的锁有哪些类型,MySQL 中加锁的原则

锁的类型MySQL 找那个根据加锁的范围&#xff0c;大致可以分成全局锁&#xff0c;表级锁和行级锁。全局锁全局锁&#xff0c;就是对整个数据库加锁。加锁flush tables with read lock解锁unlock tables全局锁会让整个库处于只读状态&#xff0c;之后所有的更新操作都会被阻塞&a…