春招上岸腾讯了,把三月份记的一些笔记按时间顺序放上来。
(只记录了网上摘录的部分,很多笔记在草稿本上,不好放上来)
同时感谢飞书前端年后面试真题,会80%直接进大厂
当然欢迎感兴趣学习方式的同学私信我。
「每日一题」JS 中的闭包是什么?
详解js中的闭包
js闭包的应用
闭包是指那些能够访问自由变量的函数。自由变量是指在函数中使用的既不是函数参数也不是函数的局部变量的变量。
闭包的作用:
当有个函数的内部有个局部变量(n),这个变量无法在外面直接得到时,我们通过在这个函数里面在定义一个函数,并且用这个定义的函数去得到这个局部变量,最后我们在返回这个子函数,就能通过返回的这个函数得到局部变量n
闭包的优点:
闭包的缺点:
通过bind, call, apply三种方式改变某函数的this指向。
三者的区别:
①call和apply两者与bind的区别为:前两者返回的是执行结果,而后者返回的是改变了this指向的函数,如需执行结果则需再调用一次。
②call和apply的区别为:前者传递的是多个参数,后者传递的是一个包含多个参数的类数组。
如何写出一个惊艳面试官的深拷贝
乞丐版:JSON.parse(JSON.stringify());
JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串。
JSON.parse()可以把JSON规则的字符串转换为JSONObject
常规版
function clone(target, map = new Map()) {
if (typeof target === 'object') {
let cloneTarget = Array.isArray(target) ? [] : {};
if (map.get(target)) {
return target;
}
map.set(target, cloneTarget);
for (const key in target) {
cloneTarget[key] = clone(target[key], map);
}
return cloneTarget;
}else{
return target;
}
}
怎么调用CSS样式
文字颜色为红色
使用style标签把css代码放在特定页面的部分中
其中,rel规定当前文档与被链接文档的关系;href规定被链接文档的位置;type规定被链接文档的MIME类型。stylesheet表引入的是外部样式表,text/css表示MIME中的css类型。
为什么要把js放在页面底部,css放在顶部
JS 一定要放在 Body 的最底部吗
因为浏览器生成Dom树的时候是一行一行读HTML代码的,script标签放在最后面就不会影响前面的页面的渲染。
因为此时dom树已经解析完成, 不然会阻塞dom的解析。
前端技术之MVVM软件架构模式
常用的设计模式:创建型模式、结构型模式、行为模式。
重构:设计模式是理想主义(为理想的软件设计提供目标,但是达到这个目标通常很困难,很可能存在过度设计)、重构是实用主义(满足当前需求设计同时,在版本迭代中不断改进当前的设计,尽量靠近设计模式的理想过度,相辅相成的关系,设计模式为重构提供目标,在不断重构中达到理想状态)
200、204、206(可以展开HTTP1.1)
301、302、303、304(可以展开浏览器缓存机制)
400、401、403、404
500、502、503
数字 | 状态 | 说明 |
---|---|---|
0 | unsent | 代理被创建未调用open() |
1 | opend | 已open(),建立连接 |
2 | headers_received | 已send(),获取状态行和响应头 |
3 | loading | 响应体下载中 |
4 | done | 响应体下载完成,可直接使用responseText |
彻底理解浏览器的缓存机制(http缓存机制)
强缓存:expires、cache-control.
协商缓存Etag和If-None-Match、Last-Modefied和If-Modified-Since.
类数组转换成数组的方法
js异步从入门到放弃(一)- Event Loop模型
js异步从入门到放弃(二)- 传统的异步实现方案
js异步从入门到放弃(三)- 异步任务队列(task queues)
js异步从入门到放弃(四)- Generator 封装异步任务
js异步从入门到放弃(实践篇) — 常见写法&面试题解析
理解 JavaScript 的 async/await
async和await
await 是个运算符,用于组成表达式,await 表达式的运算结果取决于它等的东西。
async 函数调用不会造成阻塞,它内部所有的阻塞都被封装在一个 Promise 对象中异步执行。
HTTP1.0和HTTP1.1和HTTP2.0的区别
HTTP1.0、HTTP2.0、HTTP 3.0及HTTPS简要介绍
HTML 的文档流和文本流分别是什么?
文档流是相对于盒子模型讲的,文本流是相对于文子段落讲的。
元素浮动(float)之后,会让它跳出文档流,也就是说当它后面还有元素时,其他元素会无视它所占据了的区域,直接在它身下布局。但是文字却会认同浮动元素所占据的区域,围绕它布局,也就是没有拖出文本流。
元素绝对定位(absolute)后,不仅元素盒子会拖出文档流,文字也会出文本流。那么后面元素的文本就不会在认同它的区域位置,会直接在它后面布局,不会再环绕。
回归标准文档流:
flaot的元素,对父级元素设置overflow: hidden或clear: both,或者对float的元素同时使用clear: both可以回归文档流。
博客园
彻底理解js的事件流
用户的操作会产生事件,事件会在dom元素上进行传播,传播方向:div>body>html>document>window.
事件分为三个阶段:捕获阶段>目标阶段(当前dom上执行的js)>冒泡阶段(向父级dom传播),一般会在冒泡阶段进行干预,例如在页面和页面弹框中都捕获了enter回车事件,一般会在弹框层阻止向上冒泡event.stopPropogation();
事件监听器element.addEventListener(event, function, useCapture);
第一个参数是事件的类型(如“ click”或“ mousedown”)。
第二个参数是我们想要在事件发生时调用的函数。
第三个参数是一个布尔值,指定是使用事件冒泡还是事件捕获。true为捕获,flase为冒泡,默认为flase。
所有事件的顺序是:其他元素捕获阶段事件 -> 本元素代码顺序事件 -> 其他元素冒泡阶段事件。
①function myFuction(a,b){
return a*b;
}
②var x = function (a,b){
return a*b;
}
③var myFunction = new Function("a","b","return a*b");
var x = myFuction(4,3);
详解JavaScript中的Event Loop(事件循环)机制
以下事件属于宏任务:
setInterval()
setTimeout()
以下事件属于微任务:
new Promise()
new MutaionObserver()
当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务永远在宏任务之前执行。
JS CLass类
用实例的_proto_属性为class添加方法
var p1 = new Point(2,3);
var p2 = new Point(3,2);
p1.__proto__.printName = function () { return 'Oops' };
p1.printName() // "Oops"
p2.printName() // "Oops"
var p3 = new Point(4,2);
p3.printName() // "Oops"
JS正则表达式入门,看这篇就够了
正则表达式即浏览器可以识别的规则,有了这个规则,浏览器就可以帮我们判断某些字符是否符合我们的要求。
定义:
//第一种“/正则表达式/”
var reg1=/hello \w{3,12}/g;
//第二种new RegExp('正则表达式')
var reg2=new RegExp("hello \\w{3,12}",'g');
修饰符:
g:全局匹配;i:不区分大小写;m:多行匹配
属性:
global、ignoreCase、lastIndex、multiline、source
方法:
test()、exec()、compile()
例子:检验九位qq号(用^和$指定起止位置)
/^[1-9][0-9]{4,14}$/
String对象里的方法:match()、search()、replace()、split();
面试官连环追问:数组拍平(扁平化) flat 方法实现
const arr = [1, 2, 3, 4, [1, 2, 3, [1, 2, 3, [1, 2, 3]]], 5, "string", { name: "弹铁蛋同学" }];
// 遍历数组的方法有太多,本文只枚举常用的几种
// for 循环
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// for...of
for (let value of arr) {
console.log(value);
}
// for...in
for (let i in arr) {
console.log(arr[i]);
}
// forEach 循环
arr.forEach(value => {
console.log(value);
});
// entries()
for (let [index, value] of arr.entries()) {
console.log(value);
}
// keys()
for (let index of arr.keys()) {
console.log(arr[index]);
}
// values()
for (let value of arr.values()) {
console.log(value);
}
// reduce()
arr.reduce((pre, cur) => {
console.log(cur);
}, []);
// map()
arr.map(value => console.log(value));
const arr = [1,2,3];
①arr instanceof Array
②arr.constructor === Array
③Object.prototype.toString.call(arr) === '[object Array]'
④Array.isArray(arr)
一篇让你明白进程与线程之间的区别与联系
进程是系统资源分配的最小单位,线程是cpu调度的最小单位。
进程间通过TCP/IP端口来交互,线程通过共享内存交互。
一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。
进程间通信IPC
六种通信方式:
Ⅰ、本地进程通信
Ⅱ、网络间进程通信
造成死锁必须达到的4个条件:
银行家算法(避免死锁):
在资源分配之前先计算此次分配资源的安全性,若分配后不会造成系统进入不安全状态则分配否则等待。
I/O 多路复用引入了一些额外的操作和开销,性能更差。但是好处是用户可以在一个线程内同时处理多个 I/O 请求。如果不采用 I/O 多路复用,则必须通过多线程的方式,每个线程处理一个 I/O 请求。
Ⅰ、评判标准:
RAIL:100ms内响应用户的输入,10ms内产生一帧,最大化主线程空闲时间,5s内让页面变得可交互。
R:复杂的js计算尽可能放在后台,避免对用户输入造成阻塞。
A:在一些高压点上,比如动画,尽可能地少做事(如取offst/设置style等操作)
I:用空闲时间来完成一些延后的工作,如先加载页面可见部分,然后利用空闲时间加载剩余部分。
L:禁用渲染阻塞的资源,延后加载
Ⅱ、重排重绘:
减少重排次数和范围:
①样式集中改变
②分离读写操作(不要在两个读操作间加写操作)
③将DOM离线(给元素设置display:none将其从dom渲染树上拿掉,复制节点到dom上)
④使用absolute或fixed脱离文档流。
Ⅲ、将css放将js放底部,避免阻塞dom树的渲染。
Ⅳ、网页图片加载优化:
①优先加载首屏所需图片
②在 HTTP/1.0 和 HTTP/1.1 协议下,由于 Chrome 只支持同域同时发送 6 个并发请求,可以进行域名切分,来提升并发的请求数量,或者使用 HTTP/2 协议
③单位像素优化(减少色板中颜色种类)
④图片像素总数优化(将图片加载尺寸和实际渲染尺寸对比,减少图片大小)
Ⅴ、白屏(从打开一个页面到页面展示画面经历的过程):
Ⅵ、动画性能优化:
①使用精简的DOM
②提倡使用div+css,避免使用table布局因为后者重排和重绘成本较高
③DOM元素读写分离
④让进行大量动画的元素脱离文档流,减少重排开销
⑤缓存DOM元素位置信息,避免不必要的属性读取
⑥尽量使用离线DOM
⑦使用css3 transform优化动画性能
⑧合成层:一般一个元素开启硬件加速后会变成合成层,可以独立于普通文档流中,改动后可以避免整个页面重绘,提升性能。
30 道 Vue 面试题,内含详细讲解
View变化更新Data:事件监听。
Data变化更新View:
优点:
①保证性能下限、②无需手动操作DOM③跨平台
缺点:
无法进行极致优化:在一些性能要求极高的应用中无法进行针对性的极致优化。
实现原理:
①用JS对象模拟真实的DOM树,对真实的DOM进行抽象
②用diff算法比较两颗DOM树的差异
③用patch算法将两个DOM对象的差异应用到真正的DOM树上
跨域资源共享 CORS 详解
什么是跨域?跨域解决方法
解决跨域的方法:
CORS需要浏览器和服务器同时支持。
浏览器端自动完成,不需要用户参与,所以CORS通信的关键是服务器。
①对于简单请求,浏览器会直接发出CORS请求,即在头信息中添加一个Origin字段(包含协议+域名+端口)。
②对于非简单请求,浏览器会先发出一次预检请求。
浅谈 JS 防抖和节流
博客园
BFC——块格式化上下文
应用:
原型链继承、构造函数继承、组合继承、原型链继承、寄生式继承、寄生组合式继承
聊聊V8引擎的垃圾回收
Ⅰ、减少请求数量
Ⅱ、减小资源大小
Ⅲ、优化网络连接
Ⅳ、优化资源加载
Ⅴ、减少重绘、回流
Ⅵ、webpack优化