前端面试必看(持续更新)

事件循环机制

  • 为什么需要事件循环:
    • js是单线程的,某些耗时操作会阻塞代码,所以代码/任务分同步、异步
    • 同步代码交给js引擎,异步代码交给宿主环境
    • 同步代码放入执行栈中,异步代码放入任务队列
    • 执行栈的任务执行一个后,会到任务队列查询是否有未完成的异步任务,有就送到执行栈去执行。

微任务和宏任务

  • js引入promise后,自身也可以发起异步任务了(promise本身同步,then、catch才是异步的),称为“微任务”
    • 微任务是由js引擎发起
      • promise(then、catch)
      • process.nextTick
      • Async/Await
      • Object.observe
    • 宏任务由宿主环境发起
      • script代码块(所谓的宏任务优先是指js在script这个宏任务中执行)
      • setTimeout/setInterval定时器
      • setImmediate定时器

tcp udp

  • tcp面向连接、可靠、有拥塞控制和流量控制、头部开销大,运用在文件传输
  • udp面向无连接、不可靠、无拥塞控制和流量控制、头部开销小、运用在直播、音视频通话

tcp三次握手

  • 为什么需要三次:防止重复连接,网络中可能存在滞留的网络请求,服务器会错误的认为发起了新的连接请求。
  • 两次握手的问题:存在SYN洪水攻击风险,发送大量连接请求;且无法分辨已失效的连接请求。

暂时性死区

es6中的let和Const存在暂时性死区,意思是在块级作用域内,let和const声明的变量已经被编译器加载了,但是不能提前访问,必须在声明语句之后才能访问。该作用域开始到声明变量语句之间的区域称为暂时性死区。

不同于var,var存在变量提升,且重复声明后者会覆盖前者,但let和const不能重复声明已声明过的变量。

var a = 0;
console.log(a,window.a);// 输出 0 0
if(true){
    console.log(a,window.a);// 函数声明会直接提升到块级作用域的最顶端,输出 function a 和 0
    a = 1;  // 取作用域最近的块级作用域的 function a ,且被重置为 1了,本质又是一个 变量的赋值。
    console.log(a,window.a);// a 是指向块级作用域的 a, 输出 1 和 0 
    function a(){} // 函数的声明,执行函数时,变量的定义会同步到函数级作用域(即最外层)
    console.log(a,window.a);// 输出 1 和 1
    a = 21; // 仍然是函数定义块级作用域的 a ,重置为 21
    console.log(a,window.a); // 输出为函数提升的块级作用域的 a, 输出 21,1
    console.log("里面",a);//输出21
}
console.log("外部",a);//输出1

上述例子中,函数的声明会提升到块级作用域的最前面,即先var a ;再到var a = 0,函数的执行会将变量的定义提升到外部(函数级作用域)

map和普通对象

map对象和普通对象的区别:

  • Map对象的键可以是任意类型的数据,而普通对象的键只能是字符串类型。
  • Map对象会保持插入顺序,而普通对象不保证键值对的顺序。
  • Map对象有一些特定的方法来操作和访问键值对,而普通对象使用点语法或方括号语法来操作和访问键值对。
  • Map对象的键值对数量可以通过size属性获取,而普通对象需要手动计算键值对的数量。

Mixin和继承

mixin:

​ 优点:可以将多个对象的属性组合到一个对象

​ 缺点:可能会造成属性冲突或覆盖

继承:

​ 优点:子类可继承父类的方法,并可重写

​ 缺点:容易导致类层次混乱

防抖节流

防抖:

function debounce(fn, wait) {
    let timer = null;
    return function (...args) {
        const context = this
        if(timer) clearTimeout(timer); // 清除之前的定时器
        timer = setTimeout(() => {
            fn.apply(context,args); // 执行传入的函数,并保留函数的上下文和参数
        }, wait);
    };
}

节流:

function throttle(fn,interval){
	let start = 0;
	return function(...args){
		const now = new Date().getTime()
		const wait = interval - (now - start)
		if(wait < 0){
			fn.apply(this,args)
			start = now;
		}
	}
}

事件捕获、执行、冒泡

<!doctype 5>
<html>
  <head></head>
  <body></body>
</html>

document.addEventListener('click', function(e) {
    console.log(e.type, '1');
}, true);

document.body.addEventListener('click', function(e) {
    console.log(e.type, '2');
    e.stopPropagation();
}, true);

document.body.addEventListener('click', function(e) {
    console.log(e.type, '3');
});

document.addEventListener('click', function(e) {
    console.log(e.type, '4');
});

该输出结构为click 1,click 2, click 3, click 4,加了参数true即为捕获阶段执行,故事件先到document再到body,stopPropagation阻止了冒泡,所以click 1不会再输出一遍;没有参数的方法在冒泡阶段执行,此时事件到了body后向上冒泡到document;

原型、原型链

每个函数都有一个prototype属性,称为原型,存放一些属性和方法

每个实例对象都有一个__proto__属性,该属性指向它的原型对象,它原型对象也有__proto__属性,故像链表一样称为原型链;

url到页面渲染

  1. dns解析:域名先在本地浏览器缓存和host文件查找是否有记录,否则查询本地域名服务器-》根域名服务器-》顶级域名服务器-》返回dns地址
  2. 建立tcp连接:浏览器用随机端口号向服务器80端口发起tcp握手
  3. 发送http/https请求:https用到了ssl和tls协议加密数据。
  4. 服务器返回数据:返回响应头和html正文
  5. 浏览器解析并渲染页面:根据Html生成dom-》根据css生成cssDom-》将Dom合并-》计算dom的几何信息-》dom渲染
  6. 断开tcp连接:tcp四次挥手
  • 37
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值