web基础知识
一、浏览器:
11道浏览器原理面试题
九种跨域方式实现原理(完整版)
1、常见的浏览器内核有哪些?
| 浏览器/RunTime | 内核(渲染引擎) | JavaScript 引擎 |
|---|---|---|
| Chrome | Blink(28~) Webkit(Chrome 27) | V8 |
| FireFox | Gecko | SpiderMonkey |
| Safari | Webkit | JavaScriptCore |
| Edge | EdgeHTML | Chakra(for JavaScript) |
| IE | Trident | Chakra(for JScript) |
| Node.js | - | V8 |
2、浏览器的主要组成部分是什么?
-
用户界面 - 包括地址栏、前进/后退按钮、书签菜单等。除了浏览器主窗口显示的您请求的页面外,其他显示的各个部分都属于用户界面。
-
浏览器引擎 - 在用户界面和呈现引擎之间传送指令。
-
UI呈现引擎 - 负责显示请求的内容。如果请求的内容是 HTML,它就负责解析 HTML 和 CSS 内容,并将解析后的内容显示在屏幕上。
-
网络 - 用于网络调用,比如 HTTP 请求。其接口与平台无关,并为所有平台提供底层实现。
-
用户界面后端 - 用于绘制基本的窗口小部件,比如组合框和窗口。其公开了与平台无关的通用接口,而在底层使用操作系统的用户界面方法。
-
JavaScript 解释器。用于解析和执行 JavaScript 代码。
-
数据存储。这是持久层。浏览器需要在硬盘上保存各种数据,例如 Cookie。新的 HTML 规范 (HTML5) 定义了“网络数据库”,这是一个完整(但是轻便)的浏览器内数据库。
3、浏览器是如何渲染UI的?
- 浏览器获取HTML文件,然后对文件进行解析,形成DOM Tree
- 与此同时,进行CSS解析,生成Style Rules
- 接着将DOM Tree与Style Rules合成为 Render Tree
- 接着进入布局(Layout)阶段,也就是为每个节点分配一个应出现在屏幕上的确切坐标
- 随后调用GPU进行绘制(Paint),遍历Render Tree的节点,并将元素呈现出来
4、浏览器如何解析css选择器?
浏览器会『从右往左』解析CSS选择器。
我们知道DOM Tree与Style Rules合成为 Render Tree,实际上是需要将Style Rules附着到DOM Tree上,因此需要根据选择器提供的信息对DOM Tree进行遍历,才能将样式附着到对应的DOM元素上。
若从左向右的匹配,过程是:
- 从 父
tree开始,遍历子节点
2. 然后各自向子节点tree遍历。
3. 最后遍历目标节点,一颗DOM树的节点动不动上千,这种效率很低。
如果从右至左的匹配:
- 先找到符合条件的最右选择器,再找符合 层层左边选择器
- 最后找到根选择器。
后者匹配性能更好,是因为从右向左的匹配在第一步就筛选掉了大量的不符合条件的最右节点(叶子节点);而从左向右的匹配规则的性能都浪费在了失败的查找上面。
5、浏览器重绘与重排的区别?
- 重排: 部分渲染树(或者整个渲染树)需要重新分析并且节点尺寸需要重新计算,表现为重新生成布局,重新排列元素
- 重绘: 由于节点的几何属性发生改变或者由于样式发生改变,例如改变元素背景色时,屏幕上的部分内容需要更新,表现为某些元素的外观被改变
单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制受到此次重排影响的部分
重排和重绘代价是高昂的,它们会破坏用户体验,并且让UI展示非常迟缓,而相比之下重排的性能影响更大,在两者无法避免的情况下,一般我们宁可选择代价更小的重绘。
『重绘』不一定会出现『重排』,『重排』必然会出现『重绘』。
6、如何触发重排和重绘?
任何改变用来构建渲染树的信息都会导致一次重排或重绘:
- 添加、删除、更新DOM节点
- 通过display: none隐藏一个DOM节点-触发重排和重绘
- 通过visibility: hidden隐藏一个DOM节点-只触发重绘,因为没有几何变化
- 移动或者给页面中的DOM节点添加动画
- 添加一个样式表,调整样式属性
- 用户行为,例如调整窗口大小,改变字号,或者滚动。
7、同源策略、cookie、localstorage、sessionStorage
同源策略: 域名,协议,端口相同
如果不是同源:
(1)Cookie、LocalStorage和IndexDB 无法读取
(2)DOM无法获得
(3)AJAX请求不能发送
# cookie 同源
1.当前域名或者父域名下的Cookie;
2.当前路径或父路径下的Cookie
3.每次发起同域下的 HTTP 请求时,都会携带当前域名下的 Cookie;
4.支持设置为 HttpOnly,防止 Cookie 被客户端的 JavaScript 访问。
| cookie | localstorage | sessionStorage | |
|---|---|---|---|
| 默认浏览器关闭,可以设置 | 永久,需主动removeItem | 会话级别 | 时间 |
| 4k | 5m | 5m | 大小 |
| http请求携带 | 客户端信息存储和使用 | 客户端信息存储和使用 | 特点 |
| 需要封装,推荐jsCookie | 内置api,容易使用 | 内置api,容易使用 | 使用 |
8、浏览器缓存机制
9、postMessage
二、html5
1、如何理解HTML语义化
- 便于代码可读性
- 便于seo
- 有例子举例子
2、哪些是块级元素、哪些是内联元素
Display: block/table: 有div h1 tabble ol ul p等
display:inline/inline-block; 有 span img input button等
三、CSS + flex + less
1、盒模型
box-sizing: content-box|border-box|inherit;
2、块级元素和行内元素
display: none|block|inline-block|flex|inline-block
·块级元素
1.总是从新的一行开始
2.高度、宽度都是可控
3.宽度没有设置时,默认为100%
4.块级元素中可以包含块级元素和行内元素
·行内元素
1.和其他元素都在一行
2.高度、宽度以及内边距都是不可控的
3.宽高就是内容的高度,不可以改变
4.行内元素只能行内元素,不能包含块级元素
3、常用客户端尺寸和移动端尺寸
客户端尺寸:
| % | 百分比 |
|---|---|
| em | 1em 等于当前的字体尺寸。2em 等于当前字体尺寸的两倍。例如,如果某元素以 12pt 显示,那么 2em 是24pt。在 CSS 中,em 是非常有用的单位,因为它可以自动适应用户所使用的字体。 |
| px | 像素 (计算机屏幕上的一个点) |
移动端尺寸:
| % | rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素 |
|---|---|
| rem | 始终是基于根元素 ,代表倍数。设备屏幕的像素,浏览器的默认字体高都是 16px; 可以结合px2rem使用 |
| vh /vw | 等于视口的1/100,window.innerHeight/window.innerWith |
media-query:
4、常用颜色:三基色R(Red)、G(Green)、B(Blue)
| 颜色 | 颜色 HEX | 颜色 RGB |
|---|---|---|
| 黑 black | #000000 | rgb(0,0,0) |
| 红 red | #FF0000 | rgb(255,0,0) |
| 绿 green | #00FF00 | rgb(0,255,0) |
| 蓝 blue | #0000FF | rgb(0,0,255) |
| 黄 yellow | #FFFF00 | rgb(255,255,0) |
| 青蓝 | #00FFFF | rgb(0,255,255) |
| 洋红色 | #FF00FF | rgb(255,0,255) |
| 银色 silver | #C0C0C0 | rgb(192,192,192) |
| 白色 white | #FFFFFF | rgb(255,255,255) |
5、display 和 visiblity 、opacity的区别:
1.当为元素设置display:none;时,元素在页面中不占据任何位置,而visibility:hidden;时,元素依旧占据位置;
opacity: 0也会被子元素继承,但是不能通过设置子元素opacity: 0使其重新显示2.对子元素的影响
父元素为display:none;时,子元素设置display:block;无效
父元素为visibility:hidden;时,子元素设置visibility:visible;元素再次显示3.不管设置哪个,如果子元素为图片的时候,都会请求图片
4.
visibility:hidden比display:none性能上要好,display:none切换显示时,页面产生回流,而visibility切换是否显示时则不会引起回流5.
opacity: 0元素上面绑定的事件是可以触发的6.
transition对于opacity是有效,transition对于visibility也是无效的
6、水平垂直居中、对齐的问题
水平居中:
inline: text-aligin:center;
Block: margin; auto;
absulote: left: 50% + marginl-left
垂直居中:
Inline: line-height 等于height
absulote: top: 50% + margin-top 负值
absulote: transform(-50%, -50%) ===> transform相对自己移动
absulote: top,left,bottom,right = 0; + margin: auto
flex, transform + absolute, 同时适用于水平居中和垂直居中
absolute相对于最近的有定位的元素进行定位
图片和文字的对齐
7、滚动条
.test-1::-webkit-scrollbar {
/*滚动条整体样式*/
width : 10px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
}
.test-1::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
box-shadow : inset 0 0 5px rgba(0, 0, 0, 0.2);
background : #535353;
}
.test-1::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow : inset 0 0 5px rgba(0, 0, 0, 0.2);
border-radius: 10px;
background : #ededed;
}
8、margin 纵向重叠、margin 负值
margin负值:
Margin-top,margin-left 负值,元素向上、元素向左移动
margin-right负值,右侧元素左移,自身不受影响
margin-bottom负值、下方元素上移,自身不受影响
9、BFC 理解和应用 hasLayout
Block format context, 块级盒子上下文
一块独立的渲染区域,内部元素的渲染不会影响边界以为的元素
形成BFC的常见条件:
float 不是none
position: 是absolute 或者fixed
overflow 不是visible
display: flex 、inline-block
清除浮动:
.claerfix::after{ content; '.'; height: 0; display: block; clear: both; visibility:hidden; } .claerfix{ *zoom: 1 }
10、float 布局的问题,以及clearfix
圣杯和双飞翼布局的目的
- 三栏布局, 中间一栏最先加载和渲染
- 两侧内容固定,中间内容随着宽度自适应
- 一般用于PC
11、flex
flex画骰子
12、border的三角形,border属性有哪些问题
13、伪元素和伪类
伪类:L,V,H,A ===> css 相同权重后面覆盖前面
a:link 表示未被访问的链接 (在页面上写了,还没有访问过)
a:visited 表示已经被访问过后的链接 (访问过了,注:判断是否访问过,是以浏览器的浏览记录为依据)
a:hover 表示鼠标指针位于其上的链接
a:active 表示活动链接 (当鼠标点下时的链接)
14、line-height的继承
四、 JS ES6
1、js 的继承 原型 和 ES类原型本质
原型和原型链的图示
属性和方法的执行规则 ===> 通过链查找
new Object( target ) 和Object.create()的区别
{} 等同于new Object(), target__ proto __ = Object.prototype
Object.create(null) 没有原型
Object.create({})指定原型
new 调用
如何实现继承?
2、深度克隆的原理,为什么要实现深度克隆,为什么不使用 JSON.parse(JSON.stringfy(data))、
值类型 和 引用数据类型?
typeof Symbol() // 'symbol'
typeof Number() // 'number'
typeof Sring() // 'string'
typeof Function() // 'function'
typeof Objecr() // 'object' ===> typeof Array()
typeof Boolean() // 'boolean'
typeof null() // 'object' ===> 特殊引用类型,指针指向为空地址
typeof undefined() // 'undefined'
栈(stack)和 堆(heap:一般是在堆的头部用一个字节存放堆的大小)
方法一
function deepClone(obj) {
let newObj = Array.isArray(obj) ? [] : {}
if (obj && typeof obj === "object") {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = (obj && typeof obj[key] === 'object') ? deepClone(obj[key]) : obj[key];
}
}
}
return newObj
}
const newObj = deepClone(oldObj));
方法二
利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反序列化(还原)js对象
const newObj = JSON.parse(JSON.stringify(oldObj));
缺点:
- 如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象;
- 如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象;
- 如果obj里有function,Symbol 类型,undefined,则序列化的结果会把函数或 undefined丢失;
- 如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null
- JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;
方法三
const newObj = Object.assign([],oldObj);
缺点:
- Object.assign只对顶层属性做了赋值,完全没有继续做递归之类的把所有下一层的属性做深拷贝。
3、js 算法、编程
实现一个简易的jQuery,考虑插件和扩展性
手写节流 throttle ===> scroll 滑动触发 、drag 拖动
防抖 debounce ===> search 框输入结束触发
递归 -- 函数自调用 -- 斐波那契 --- 黄金分割数列
柯里化
直角三角形和金字塔效果
javascript 实现杨辉三角
js写九九乘法表的不同写法
手写深度比较、模拟loadash isEqual
实现一个ajax
var xhr= new XMLHttpRequest(), method = "GET", url = "https://developer.mozilla.org/"; xhr.open(method, url, true); xhr.onreadystatechange = function () { if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { console.log(xhr.responseText) } } xhr.send();
值 状态 描述 0UNSENT代理被创建,但尚未调用 open() 方法。 1OPENEDopen()方法已经被调用。2HEADERS_RECEIVEDsend()方法已经被调用,并且头部和状态已经可获得。3LOADING下载中; responseText属性已经包含部分数据。4DONE下载操作已完成。 HTTP状态码分类:
1** 信息,服务器收到请求,需要请求者继续执行操作 2** 成功,操作被成功接收并处理 3** 重定向,需要进一步的操作以完成请求 4** 客户端错误,请求包含语法错误或无法完成请求 5** 服务器错误,服务器在处理请求的过程中发生了错误
十大经典排序算法
- 冒泡排序
- 选择排序
- 插入排序
- 希尔排序
- 归并排序
- 快速排序
- 堆排序
- 计数排序
- 基数排序
4、内置对象Math , Array,Date 的常用API
纯函数: 1.不改变源数组(没有副作用)
数组不突变API:
concat,filter,slice,map,includes indexOf
数组突变API:
push pop shift unshif forEach some every reduce sort reverse join
数组slice -切片 和splice-剪接 的区别 ?
获取多个数字中的最大值 ?
js 生成随机整数,小数?
parseInt(Math.random()*(n-m+1)+m)js数字字符串转成千分位金额?
let num = "1234567"; num = parseFloat(num) num = num.toFixed(2) num = num.replace(/\B(?=(\d{3})+\b)/g,',')
5、作用域和自由变量、闭包、this,执行上下文
作用域:
全局作用域 ===> 凡是跨了自己的作用域的变量都叫自由变量。
函数作用域
块级作用域 ( es6 { } )
闭包: 自由变量的查找,是在函数定义的地方查找,不知在执行的地方
this 的不同应用场景,如何取值?
- 当做普通函数调用 ===> window
- bind call apply ===> 绑定谁就是谁
- 作为对象方法调用 ===> 对象本身
- class 的方法调用 ===> class对象
- 箭头函数 ===> 定义时的父级this
手写bind 函数?
实际开发中闭包的应用场景,举例说明?
- 隐藏数据
- 做一个cache 的工具
6、说说 call, apply, bind
7、promise,generator-yield,async-await, 异步和单线程,宏任务和微任务,(call stack)调用栈,事件循环(event-loop)
异步和单线程:
js 是单线程语言,只能同时做一件事儿
浏览器和nodejs已经支持js启动进程,如 web worker ,但是js执行还是单线程
js 和 DOM 渲染共用一个线程,因为js 可以修改dom结构
遇到等待(网络请求,定时任务)不能卡住
什么是宏任务队列(macrotask callback queue)和微任务队列(microTask callback queue) ===> 事件循环后加人调用栈
浏览器api执行代码,将callback 加入宏任务队列 ===> timer, dom ==> W3C 规范
DOM 渲染后触发,如 setTimeout
js--api 引擎执行代码,将callback 加入微任务队列 ===> promise ===> ES6 语法规定
DOM 渲染前触发, 如 Promise
描述事件循环执行机制(可画图)?
事件循环回调实现原理
1.call stack 2.尝试DOM 渲染 3. 触发event loop
promise解决了什么问题
解决了: 回调地狱/回调嵌套( callBack hell ):改为了then串行代码格式,不是ajax嵌套的模式
promise有哪三种状态,如何变化?
const p3 = new Promise(resolve =>{ resolve(2) }) console.log(p3) /* Promise {<fulfilled>: 2} __proto__: Promise [[PromiseState]]: "fulfilled" [[PromiseResult]]: 2 */pending、resolved、 rejected ===> 状态不可逆
pending: 没有进行resolve或rejeact的 new Promise
resolved: 触发then 的回调
rejected:触发catch 的回调
then, catch ===> 返回的是resolved、rejected的Promise
then、catch对状态的影响?
then和catch的链式调用?
Promise.all 和 Promise.race ?
async await
await 相当于promise 的then ,如果promise.rejected状态时,会中断 async函数执行; 需要加try + catch 捕获错误
await 后面的内容都可以看做callback
同步和异步的区别是什么?
手写用Promise 加载一张图片?
前端使用异步的场景有哪些?
- 网络请求, 如ajax 图片加载
- 定时任务,如setTimeout
for ... of 异步循环===> 没执行完一步才执行下一步; for in 是先遍历完 一起执行
8、es6模块 amd cmd commonJS
ES6 Module 静态引入,编译时引用, 不能条件引入
Commonjs 动态引入,执行时引入
只有ES6 Module才能静态分析,实现Tree-Shaking
9、事件冒泡,事件捕获,事件委托
Js 创建10个 标签, 点击的时候弹出对应的序号
10、typeof 和 instanceof 的区别
instanceof 用于判断一个变量是否属于某个对象的实例, 基于原型链查找
11、Proxy不能被polyfill
Class 可以用 function模拟
Promise 可以用callback 模拟
Prory 的功能不能用Object.definepropty模拟
12、何时使用=== 何时使用 ==
13、列举强制类型装换和隐式类型转换
强制:parseInt parseFloat toSting等
隐式: if、 逻辑运算 、==、+拼接字符串
14、解释jsonp原理、为何不是真正的ajax
浏览器的同源策略 和 跨域
哪些标签能绕过跨域
jsonp的原理
15、函数声明 和函数表达式的区别
结合变量提升---函数声明会在代码加载前预加载,而函数表达式不会
函数声明 function name ()
函数表达式 const fn = function()
五、工程化
webpack
多文件配置多 entry
publicPath: ’cdn‘ 静态文件的cdn
插件:
HtmlWebpackPlugin ===> 注入html,多文件,单独配置
miniCssExtrackPlugin ===> 抽离css
optimization:{
minimizaer: [TerserJSPlugin OptmizaCssAssetsPlugin], ===> 压缩
splitChunks:
// 缓存分组
cacheGroups:{
// 第三方模块
vendor
// 公共模块
common
}
}
webpack--hash
1、hash
hash是跟整个项目的构建相关,只要项目里有文件更改,整个项目构建的hash值都会更改,并且全部文件都共用相同的hash值
2、chunkhash
chunkhash和hash不一样,它根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。公共库和程序入口文件区分开,单独打包构建,接着我们采用chunkhash的方式生成哈希值
3、contenthash
contenthash表示由文件内容产生的hash值,内容不同产生的contenthash值也不一样。
1、前端代码为何要进行构建和打包
2、module chunk bundle 分别是什么
Module: 可以引用的文件,就是一个模块,源码
chunk: 打包的模块的集合---内存的概念
bundle:最终的输出的文件
3、loader 和 plugin的区别
Loader 模块转换器,例如less ---> css
plugin: 扩展插件, 将loader后的文件再进行处理
4、webpack 如何实现懒加载
自带?
5、webpack 常见性能优化
优化babel-loader
IgnorePlugin // 忽略默认引用的包
noParse // 避免重复打包
happypack // 多进程打包
parallelUglyPlugin // 开启多进程打包
热更新 hotModuleReplacementPlugin ===> 不刷新页面
自动刷新 ===> 刷新页面
DllPlugin + DllReferencePlugin ===> 提前编译不变的第三方库
scope Hosting
产出代码优化
体积更小
小图片-base64
合理分包,不重复加载
Bundle 加hash
大文件懒加载
提取公共代码
IgnorePlugin
速度更快、内存使用更少
使用CDN: publicPath: ’cdn‘ 静态文件的cdn
启用 production
自动开启代码压缩
自动删除调式代码
启动 Tree-Shaking ===> 必须ES6 Module 才能让 tree-shaking 生效
scope Hosting
6、babel-runtime 和 babel-polyfill 的区别
babel-polyfill: core + regenerator 集合 ===> babel-polyfill 被babel7.4以后弃用
使用时 需要按需引用
会污染全局
babel-runtime : 一个独立的运行时环境,不会污染全局
产出第三方lib要用babel-runtime
7、webpack 如何实现懒加载
import()
结合 Vue Reack 异步组件
8、babel
babel 只解析语法
core.js ===> babel 核心代码 新语法 polyfill的集合,不支持async await
Regenerator ===> 支持async await
9、前端为何要进行打包和构建?
代码层面:
体积更小(Tree-Shaking、压缩、合并),加载更快
编译高级语法(Ts,Es6+, 模块化, scss)
兼容性和错误检查(polyfill、postcss、eslint)
流程层面:
统一、高效的开发环境
统一的构建流程和产出标准
集成公司构建规范(提测、上线等)
10、babel 和webpack的区别
Babel-js 新语法编译工具,不关心模块化
webpack - 打包工具,多个loader,plugin的集合
六、vue + react + uniapp + taro
1、vue-router 的实现原理
2、vue路由(页面)组件钩子生命周期和组件的生命周期
路由解析流程:
路由独享的守卫, 全局路由守卫,组件内的守卫
Webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue') const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue') const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
- 导航被触发。
- 在失活的组件里调用
beforeRouteLeave守卫。- 调用全局的
beforeEach守卫。- 在重用的组件里调用
beforeRouteUpdate守卫 (2.2+)。- 在路由配置里调用
beforeEnter。- 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter。- 调用全局的
beforeResolve守卫 (2.5+)。- 导航被确认。
- 调用全局的
afterEach钩子。- 触发 DOM 更新。
- 调用
beforeRouteEnter守卫中传给next的回调函数,创建好的组件实例会作为回调函数的参数传入。
组件生命周期
created创建 : 父 ==> 子
mounted渲染: 子 ==> 父
beforeupdate:父 ==> 子
updated: 子 ==> 父
beforeDestroy:父 ==>子
destroyed: 子 ==> 父
keep-alive的周期函数:
activated
deactivated
vue3.0 组件生命周期:
beforeCreate -> 请使用 setup()
created -> 请使用 setup()
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeDestroy -> onBeforeUnmount
destroyed -> onUnmounted
errorCaptured -> onErrorCaptured ===> 捕获一个来自子孙组件的错误时被调用
何时需要使用 beforeDestroy
接触自定义事件event.$off
清除定时器
接触自定义的Dom事件,如window scroll 等
3、react.hook和vue.hook的区别
4、react.hook和react.class-component编程的比较
5、react的组件如何通讯
6、vue的组件如何通讯
父子: Props + $emit 父子传递参数 子组件像父组件分发一个事件
$refs 调用
$parent调用
自定义组件实例:非父子 ===> 自定义事件需要及时解绑
$eventBus?
7、v-show 和 v-if 的区别、
v-if 不会渲染,没有dom结构
v-show 有Dom结构,但是display:none
8、为何 v-for 中的 key
v-for 计算级别高于 v-if 不能同时使用
Diff 算法中通过tag 和key 来判断, 是否是sameNode,减少渲染次数,提升渲染性能
9、描述组件渲染和更新过程
10、vue-model 的实现原理
input 元素的value = this.name
绑定input 事件 this.name = $event.target.value
data 更新触发re-render
11、jsx的本质是什么
12、context 是什么, 有何用途
13、shouldComponentUpdate(SCU)的用途
14、面试redux单项数据流
15、setState是同步还是异步
16、基于vue 或 react 涉及 一个todolist
17、基于vue 或 react 涉及 一个购物车
18、react的可控组价和不可控组件
19、vue-router
前端路由原理:
路由的原理
hashRouter ===> 不会发送到后端
Window.location.assin()
Window.location.replace()
Window.location.onhashChange()
H5 history ===> 需要后端支持,前端需要设置 404
history.pushState() + window.onpopstate
20、$nextTick
1、vue 是异步渲染
2、数据改变时,页面渲染时 会将 data 的修改整合,多次数据变化只会渲染一次
21、vue的常见性能优化
1、合理使用 keepAlive
2、computed ===> 合理使用computed属性的缓存,data不变不会重新计算
3、vue-router 异步加载
4、合理使用 v-show 和 v-if
5、v-for 时加key, 以及避免和v-if同时使用
6、自定义事件、DOM事件及时销毁
7、合理使用异步组件
8、data 层级不要太深 ===> 不理由响应式遍历
22、vuex 的数据结构设计
action:异步操作
action: 可以整合多个mutation
mutation 做原子操作
23、slot 插槽
默认插槽
具名插槽 v-slot
作用域插槽
父级别需要使用插槽组件的内部属性
24、 组件化 + 响应式 + 订阅发布 + diff + 模板编译
数据驱动视图: MVVM,setState
Object.defineProperty ===> 数据描述, 属性描述符
// Object.defineProperty(obj, prop, descriptor) Object.defineProperty(obj, prop, { // 公共控制属性 configurable:true, // 控制属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除 enumerable:true, // 控制出现在对象的枚举属性中 // 数据描述符 value: 42, writable: false // 控制是否能够被赋值 // 存取描述符 get:()=>{}, // 执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值, set:(newVal)=>{}, // 该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象 })描述符默认值汇总
- 拥有布尔值的键
configurable、enumerable和writable的默认值都是false。- 属性值和函数的键
value、get和set字段的默认值为undefined。Proxy
使用时深度监听,性能更好
可监听 新增/删除 属性
可监听数组变化
25、虚拟DOM( Virtual DOM ) 和 diff
Vdom 是实现vue 和 React 的重要基石
diff 算法是vdom中最核心、最关键的部分
树的diff 算法: O(n^3) ===> 优化到了 O(n)
简述diff 算法
Vue:
- 只是比较同一层级,不跨级比较
- tag 不相同,则直接删除重建,不再深度比较
- tag 和 key,两则都相同,则认为是相同节点, 不再深度比较
26、组件 渲染/更新 过程
27、为何组件data 必须是一个函数?
vue组件是一个类,当组件实例化的时候,每个实例data应该不同
28、ajax 请求应该放在哪个生命周期?
mounted
js 单线程,ajax异步获取数据
放在mounted 之前没有用,只会让逻辑混乱
29、请用vnode 描述一个DOM 结构
七、node.js
1、node的事件机制和浏览器的事件机制
八、 http1.0 http1.1 http2.0 webscoket
TCP的三次握手和四次挥手(如果服务端主动关闭连接会怎么样)
- 应用层
- 传输层
- 网络层
- 数据链路层
- 物理层
1、HTTP 属于应用层协议,在传输层使用 TCP 协议,在网络层使用 IP 协议
http 常见的状态码有哪些?
(HTTP状态码分类:)(https://www.runoob.com/http/http-status-codes.html)
| 1** | 信息,服务器收到请求,需要请求者继续执行操作 |
|---|---|
| 2** | 成功,操作被成功接收并处理 |
| 3** | 重定向,需要进一步的操作以完成请求 301 永久重定向 302临时重定向 304 Not Modified |
| 4** | 客户端错误,请求包含语法错误或无法完成请求 404 服务器无法根据客户端的请求找到资源 400客户端请求的语法错误,服务器无法理解 408 服务器等待客户端发送的请求时间过长,超时 403 没有权限 |
| 5** | 服务器错误,服务器在处理请求的过程中发生了错误 500服务器错误 502 bad Gateway 504 网关超时 |
http 常见的header 有哪些
responce-header:
- Cache-Control: private
- Connection: keep-alive
- Content-Encoding: gzip
- Content-Length: 47
- Content-Type: text/html;charset=utf-8
- Date: Tue, 08 Dec 2020 13:06:47 GMT
- Expires: Tue, 08 Dec 2020 13:06:47 GMT
- Server: BWS/1.0
- Vary: Accept-Encoding
- age: 934273
- cache-control: max-age=2592000
- content-type: image/png
- date: Mon, 07 Dec 2020 03:20:20 GMT
- etag: "5e7c3f77-c49" ===> 资源的唯一标识
- expires: Sat, 26 Dec 2020 07:49:07 GMT
- last-modified: Thu, 26 Mar 2020 05:36:55 GMT ===> 资源最后修改时间
Resquest-header:
- Accept: text/plain, /; q=0.01
- Accept-Encoding: gzip, deflate, br
- Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
- Connection: keep-alive
- Cookie: PSTM=1592643412; BAIDUID=4AC4D717D44E368E25736C64885B8FD8:FG=1;
- Host: www.baidu.com
- Referer: https://www.baidu.com/
- Sec-Fetch-Dest:empty
- Sec-Fetch-Mode: cors
- Sec-Fetch-Site: same-origin
- User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
- X-Requested-With: XMLHttpRequest
- (自定义)Token: 213123123
- If-modified-Since: Thu, 26 Mar 2020 05:36:55 GMT
- If-none-match: "5e7c3f77-c49" ===.etag的值
什么是 Restful API?
传统API设计:把每个url当做一个功能
RestfulAPI 设计: 把每个url当做一个唯一的资源
描述一下 http的缓存机制(重要)? -- 静态资源(js css img)
正常url 强缓存200(from cache), 协商缓存(304) 手动 f5 ,点击刷洗,右键刷新 协商缓存(304) 强制:ctrl + f5 优先使用etag,last-modified 只能精确到秒
如果资源被重复生成,而荣内不变,则Etag 更精确一些
http1.0 http1.1 http2.0 区别?
| http1.0 | http1.1 | http2.0 | HTTPS | |
|---|---|---|---|---|
| 短连接 | 默认 keep-alive | Connection: 长连接 | ||
| 缓存 | ||||
| √ | 头部压缩技术 | |||
| expires | cache-control | 缓存字段 | ||
| HTTP1.0中认为每台服务器都绑定一个唯一的IP地址 | 传递主机名(hostname) | host的字段 |
九、Dom Bom的api
DOM:
DOM 是哪种数据结构 ?
Tree
DOM 操作的api ?
getElementById
getElementByClassName
querySelector() // css 选择器
querySelectorAll() // css 选择器
attr 和 property的区别 ?
property 设置的标签属性的值,改变属性值不会对js-dom属性结构改变,不会改变html 结构
attr 操作标签的属性的结构,会对js--dom对象属性结构改变,会改变html结构
attr 和 property 都引起页面重新渲染
一次性插入多个DOM节点,考虑性能 ?
对dom做缓存 ===> createDocumentFragment
常用盒子属性api
网页可见区域宽: document.body.clientWidth(不包括border--scroll);
网页可见区域高: document.body.clientHeight(不包括border--scroll);;
网页可见区域宽: document.body.offsetWidth (包括border--scroll,不包括margin);
网页可见区域高: document.body.offsetHeight (包括border--scroll,不包括margin);
网页正文全文宽: document.body.scrollWidth;
网页正文全文高: document.body.scrollHeight;
网页被拖动的高: document.body.scrollTop;
网页被拖动的左: document.body.scrollLeft;
网页正文部分上: window.screenTop;
网页正文部分左: window.screenLeft;
屏幕分辨率的高: window.screen.height;
屏幕分辨率的宽: window.screen.width;
屏幕可用工作区高度: window.screen.availHeight;
屏幕可用工作区宽度:window.screen.availWidth;盒子边距: node.offseLeft: 到body边框的距离
Window.screen.height:屏幕高度
Window.innerHeight : 网页视口高度
document.body.clientHeight: body内容高度
window.onload 和DOMContentLoaded的区别:
window.addEventListenter('load',function(){
// 页面全部资源加载完才会执行,包括图片,视频等
})
window.addEventListenter('load',function(){
// DOM 渲染完即可执行,图片和视频不一定完成
})
drag 事件
从url 页面加载过程?
DNS解析:域名 -> ip地址
浏览器根据IP地址向服务器发起http 请求
服务器处理http 请求,并返回给浏览器
根据HTML代码生成DOM Tree
根据CSS 代码生成CSSOM
将DOMTree 和 CSSOM 整合Render Tree
遇到

浙公网安备 33010602011771号