web前端
2023-02-14 09:27:46 15 举报
AI智能生成
面试题
作者其他创作
大纲/内容
防抖:对于短时间内连续触发的事件(如滚动事件,搜索框.),防抖的含义就是让某个时间期限内,事件处理函数只执行一次
节流:(如上拉加载)节流就是保证一段时间内只执行一次核心代码
防抖动是将多次执行变为最后一次执行
节流是将多次执行变成每隔一段时间执行
区别
防抖和节流
即同域名、同端口、同协议的才能互相获取资源
原因:浏览器“同源策略”
jsonp
document.domain + iframe跨域
location.hash + iframe
window.name + iframe
postMessage跨域
跨域资源共享(CORS)
nginx代理跨域
nodejs中间件代理跨域
WebSocket协议跨域
解决方法
跨域
浏览器要花时间去渲染,当它发现了某个部分发生了变化并且影响了布局,就需要倒回去重新渲染
回流
如果只是改变了某个元素的背景颜色或文字颜色等,不影响元素周围或内部布局,就只会引起浏览器的重绘
重绘
(1)页面初始化的时候(2)操作DOM的时候(增加或删除DOM元素)(3)某些元素的尺寸改了(边距,填充,边框,宽高)(4)CSS的属性发生变化(隐藏display:none)(5)内容改变(文本改变或图片改变而引起的的计算值的宽高改变)(6)浏览器窗口尺寸改变(当resize事件发生时)
何时发生回流
(1)不要逐个修改DOM样式,可以预先定义好css的class,然后修改DOM的className,将多个需要进行相同操作的元素一次修改(2)不要把DOM结点的属性值放在一个循环里当成循环的变量(3)当动画元素使用fixed或absolute的position时(脱离了文档流),那么在修改他们的CSS时不会发生回流(4)不要使用table布局,因为可能很小的一个改动都会造成整个table的重新布局(5)在内存中多次操作结点,完成后再添加到文档中去(6)如果要对一个元素进行复杂的操作,可以先隐藏它(display:none),操作完成后再显示(7)对于需要经常取出的引起浏览器重排的属性值,要缓存到变量中
如何减少回流
回流重绘
js优化
200:请求被正常处理
204:请求被受理但没有资源可以返回
2
301:永久性重定向
302:临时重定向
304:在缓存中有该资源,可以直接获取
401:请求需要认证403:禁止访问(譬如可以是未登录时禁止)404:服务器无法找到对应资源
3
4
500:服务器内部错误503:服务器超过最大负荷
5
状态码
协商缓存:是我们通过 http 响应头字段 etag 或者 Last-Modified 等判断服务器上资源是否修改,如果修改则从服务器重新获取,如果未修改则 304 指向浏览器缓存中进行获取
缓存
1.浏览器解析主机名2.DNS进行域名解析,即将语义化的主机名转换成IP地址3.浏览器获得端口号4.浏览器根据得到的ip地址和端口号发起TCP连接5.浏览器发起HTTP请求6.浏览器读取服务器返回的响应报文7.浏览器对返回的HTML进行渲染8.浏览器断开TCP连接
输入url后
1.HTTP 是不安全的,而 HTTPS 是安全的2.HTTP 标准端口是80 ,而 HTTPS 的标准端口是4433.HTTP 无法加密,而HTTPS 对传输的数据进行加密4.HTTP无需证书,而HTTPS 需要CA机构wosign的颁发的SSL证书
与https区别
客户端(浏览器)向服务器请求https连接。服务器返回证书(公钥)到客户端。客户端随机的秘钥A(用于对称加密)。客户端用公钥对A进行加密。客户端将加密A后的密文发送给服务器。服务器通过私钥对密文进行解密得到对称加密的秘钥。客户端与服务器通过对称秘钥加密的密文通信。
https的请求流程
GET请求参数放在URL上,POST请求参数放在请求体里GET请求参数长度有限制,POST请求参数长度可以非常大POST请求相较于GET请求安全一点点,因为GET请求的参数在URL上,且有历史记录GET请求能缓存,POST不能
GET与Post
多路复用服务端推送新的二进制格式header压缩
HTTP2新特性
http
computed:是基于响应式依赖进行缓存的。何为响应式依赖呢?例如声明在data中的变量既有响应式的性质,用通俗一点的话讲就是,计算属性的触发条件是他的依赖变化了才会重新执行计算属性默认只有 getter,不过在需要时你也可以提供一个 setter
watch:侦听器是vue提供的一个来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,选择watch会更合适。
computed、methods和watch的区别
需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点。作用主要是为了高效的更新虚拟DOM。
key
1. new Vue() 首先执行初始化,对data执行响应化处理,这个过程发生在Observer中2. 同时对模板执行编译,找到其中动态绑定的数据,从data中获取并初始化视图,这个过程发生在 Compile中 3. 同时定义一个更新函数和Watcher,将来对应数据变化时Watcher会调用更新函数 4. 由于data的某个key在一个视图中可能出现多次,所以每个key都需要一个管家Dep来管理多个 Watcher 5. 将来data中数据一旦发生变化,会首先找到对应的Dep,通知所有Watcher执行更新函数
methods:就像我们写的普通函数一样,需要我们主动去调用才会执行
vue原理
include: 字符串或正则表达式,只有名称匹配的组件会被缓存exclude: 字符串或正则表达式,名称匹配的组件不会被缓存》max: 数字,最多可以缓存多少组件实例
activated、deactivated
生命周期钩子函数
属性
keep-alive
1.Vue组件可能存在多个实例,如果使用对象形式定义data,则会导致它们共用一个data对象,那么状态变更将会影响所有组件实例,这是不合理的;2.采用函数形式定义,在initData时会将其作为工厂函数返回全新data对象,有效规避多实例之间状态污染问题。3.而在Vue根实例创建过程中则不存在该限制,也是因为根实例只能有一个,不需要担心这种情况。
VUE组件data为什么必须是函数
1.通过新旧虚拟DOM作对比(即diff),将变化的地方更新在真实DOM上
2.vue 2.x中为了降低Watcher粒度,每个组件只有一个Watcher与之对应,只有引入diff才能精确找到发生变化的地方。
3、vue中diff执行的时刻是组件实例执行其更新函数时,它会比对上一次渲染结果oldVnode和新的渲染结果newVnode,此过程称为patch。
4、diff过程整体遵循深度优先、同层比较的策略;两个节点之间比较会根据它们是否拥有子节点或者文本节点做不同操作;
diff
●路由懒加载●keep-alive缓存页面●使用v-show复用DOM●v-for 遍历避免同时使用 v-if●长列表性能优化●事件的销毁●图片懒加载●第三方插件按需引入●无状态的组件标记为函数式组件●子组件分割●变量本地化●SSR
Vue性能优化
虚拟DOM重写基于Proxy的响应式系统TypeScript + 模块化
Vue3.0的新特性
hash(#)是URL 的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页,也就是说 #是用来指导浏览器动作的,对服务器端完全无用,HTTP请求中也不会不包括#;同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;
History:HTML5 History API提供了一种功能,能让开发人员在不刷新整个页面的情况下修改站点的URL,就是利用 history.pushState API 来完成 URL 跳转而无须重新加载页面;
全局:router.beforeEachrouter.afterEach
独享:配置内beforeEnter
组件内:beforeRouteEnterbeforeRouteUpdate beforeRouteLeave
守卫
vue-router
自定义指令
组件
过滤器
方法
注册全局
五大核心属性:state,getter,mutation,action,module
vuex
axios
需要在视图更新之后,基于新的视图进行操作。
$nextTick
vue
SQL注入把SQL命令插入到表单或输入URL查询字符串提交,欺骗服务器达到执行恶意的SQL目的XSS(Cross Site Script),跨站脚本攻击攻击者在页面里插入恶意代码,当用户浏览该页之时,执行嵌入的恶意代码达到攻击目的CSRF(Cross Site Request Forgery),跨站点伪造请求伪造合法请求,让用户在不知情的情况下以登录的身份访问,利用用户信任达到攻击目的
常见
不要信任任何外部传入的数据针对用户输入作相关的格式检查、过滤等操作不要信任在任何传入的第三方数据使用 CORS,设置 Access-Control-Allow-Origin更安全地使用 Cookie设置Cookie为HttpOnly,禁止了JavaScript操作Cookie防止网页被其他网站内嵌为iframe服务器端设置 X-Frame-Options 响应头,防止页面被内嵌
防止
网络安全
包含了元素内容(content)、内边距(padding)、边框(border)、外边距(margin)几个要素
概念
css 外边距合并(叠加)
默认值:即总宽度=margin+border+padding+width
content-box
即总宽度=margin+width
border-box
规定应从父元素继承 box-sizing 属性的值
inherit
box-sizing
width : 0;height: 0; border : 100px solid transparent; border-top : 100px solid blue;
盒模型做三角形
注意点
盒子模型
px
绝对单位
相对根节点html字体大小来计算
rem
\t基准点为相对父节点字体的大小
em
\t相对于父元素的大小设定的比率
%
相对单位
@@keyframes 动画名称{ 0%{} 100%{}}
视窗宽度/高度的百分比,1vw代表视窗宽度/高低的1%\t
vw/vh
当前vw和vh中较小/较高的一个值
vmin/vmax
视窗单位
CSS3单位
id选择器
类选择器
标签选择器
ul>li
子代选择器
ul li
后代选择器
a[rel=\"external\"]
属性选择器
伪类选择器
通过给父级元素添加伪类after,并添加clear: both;属性
css选择符
同权重: 内联样式(标签内部)> 嵌入样式表(当前文件中)>外部样式(外部文件中)
!important >id >class >tag
!important 比内联优先级高
css优先级
CSS属性,花费时间,效果曲线(默认ease),延迟时间(默认0)
transition
动画名称,一个周期花费时间,运动曲线(默认ease),动画延迟(默认0),播放次数(默认1),是否反向播放动画(默认normal),是否暂停动画(默认running)
animation
transform:rotate(30deg);
transform:scale(.8);
transform
css3新特性
设置父元素为相对定位,给子元素设置绝对定位,top: 0; right: 0; bottom: 0; left: 0; margin: auto;
置父元素为相对定位,给子元素设置绝对定位,left: 50%; top: 50%; margin-left: --元素宽度的一半px; margin-top: --元素高度的一半px;
知宽高
设置父元素为相对定位,给子元素设置绝对定位,left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%);
设置父元素为flex定位,justify-content: center; align-items: center;
不知宽高
水平垂直居中
父级添加overflow: auto
浮动元素后面加块级元素,并添加clear: both;属性
清除浮动的方法
overflow:hidden; white-space:nowrap; text-overflow:ellipsis;
一行
text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
多行
文字超出省略号
常见问题
css
const 与 let 变量
模板字面量用倒引号 ( `` )
${ } 表示的占位符
模板字面量
数组解构
对象解构
解构
遍历数组的value
for...of循环
是遍历数组、对象的key
for...in循环
循环
...
展开运算符
普通函数的this指向调用它的那个对象
与普通函数区别:this指向不一样
箭头函数
add()
delete()
clear()
has()
Set()是指有序列表集合 (set中的元素是没有重复的)
new Set()
set(key:value)
get(key)
has(key)
用来存放键值对的集合 key/value
new Map()
3 种状态:pending、fulfilled 或 rejected。
回调地狱,代码难以维护
promise可以支持多个并发的请求,获取并发请求中的数据
promise可以解决可读性的问题,异步的嵌套带来的可读性的问题
promise可以解决信任问题,即先后执行顺序的问题
解决的痛点
类方法,多个 Promise 任务同时执行,返回最先执行结束的 Promise 任务的结果,不管这个 Promise 结果是成功还是失败
Promise.race
类方法,多个 Promise 任务同时执行 ,如果全部成功执行,则以数组的方式返回所有 Promise 任务的执行结果。 如果有一个 Promise 任务 rejected,则只返回 rejected 任务的结果
Promise.all
Promise 常用的方法
async/await定义了异步函数,并在其内部可通过await等待promise对象,阻塞后续的执行
promise
es6新特性
Undefined、Null、Boolean、Number、String、Object、Symbol
类型
typeof
arr instanceof Array
obj instanceof Object
fun instanceof Function
instanceof不能识别出基本的数据类型,但是可以识别出Array、Object、Function,返回布尔
instanceof
num.constructor === Number
str.constructor === String
null、undefined没有construstor方法,因此constructor不能判断undefined和null,返回布尔
constructor
Object.prototype.toString.call(num)
Object.prototype.toString.call(str)
返回[object 类型]
Object.prototype.toString.call()
判断方法
不可以转null和underfined
.toString()
都能转
String()
num + \"\"
隐式转换
转为字符串
如果要转换的字符串中有一个不是数值的字符,返回NaN
Number()
如果第一个字符是数字会解析知道遇到非数字结束
如果第一个字符不是数字或者符号就返回NaN
parseInt(),parseFloat()
str-0或者+str
转为数值类型
0 ''(空字符串) null undefined NaN 会转换成false
其它都会转换成true
隐式转换:!!x
Boolean()
转化为布尔
JSON.stringify(obj)
obj-->string
JSON.parse(str)
string-->obj
object与string
数据类型转换
js类型
添加元素到数组末尾
push(x)
删除数组末尾元素
pop()
删除数组头部元素
shift()
向数组头部添加一个元素
unshift(x)
颠倒数组中元素的顺序
reverse()
删除元素,并向数组添加新元素
splice( 位置,几个)
对数组进行排序
sort()
会改变原来数组的有
从数组中返回特定的元素
slice()
把数组所有元素放入一个字符串,元素通过指定分割符进行分隔
join()
合并两个或多个数组,并合并
concat()
把数组转化为字符串,返回结果
toString()
-返回数组对象的原始值
valueOf()
检测数组元素的每个元素是否都符合条件,返回布尔
检测数组元素中是否有元素符合指定条件
检测数组元素,并返回符合条件所有元素的数组
filter()
通过指定函数处理数组的每个元素,并返回处理后的数组
map()
不会改变原来数组的有
数组的对象方法
原型
当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我们平时所说的原型链的概念。
原型链
原型与原型链
重点:让新实例的原型等于父类的实例。
特点:1、实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。(新实例不会继承父类实例的属性!)
缺点:1、新实例无法向父类构造函数传参。 2、继承单一。 3、所有新实例都会共享父类实例的属性。(原型上的属性是共享的,一个实例修改了原型属性,另一个实例的原型属性也会被修改!)
原型链继承
重点:用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))
特点:1、只继承了父类构造函数的属性,没有继承父类原型的属性。 2、解决了原型链继承缺点1、2、3。 3、可以继承多个构造函数属性(call多个)。 4、在子实例中可向父实例传参。
缺点:1、只能继承父类构造函数的属性。 2、无法实现构造函数的复用。(每次用每次都要重新调用) 3、每个新实例都有父类构造函数的副本,臃肿。
借用构造函数继承
重点:结合了两种模式的优点,传参和复用
特点:1、可以继承父类原型上的属性,可以传参,可复用。 2、每个新实例引入的构造函数属性是私有的。
缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数。
组合继承(组合原型链继承和借用构造函数继承)
重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。
特点:类似于复制一个对象,用函数来包装。
缺点:1、所有实例都会继承原型上的属性。 2、无法实现复用。(新实例属性都是后面添加的)
原型式继承
重点:就是给原型式继承外面套了个壳子。
优点:没有创建自定义类型,因为只是套了个壳子返回对象(这个),这个函数顺理成章就成了创建的新对象。
缺点:没用到原型,无法复用。
寄生式继承
寄生组合式继承
继承
var obj = { foo: \"foo\
浅拷贝
JSON.parse(JSON.stringify(obj));
深拷贝
深拷贝:新对象改变,老对象始终不会改变浅拷贝:第一层不会改变,大于一层会随新对象改变
js对象拷贝
就是访问到的script标签里面包含的内容,或者是直接访问某一个js文件的时候,里面的可以在当前作用域直接执行的所有内容
主线程
setTimeout、setInterval、setImmediate、I/O
宏队列
promise.then、process.nextTick
微队列
1、先执行主线程2、遇到宏队列(macrotask)放到宏队列(macrotask)3、遇到微队列(microtask)放到微队列(microtask)4、主线程执行完毕5、执行微队列(microtask),微队列(microtask)执行完毕6、执行一次宏队列(macrotask)中的一个任务,执行完毕7、执行微队列(microtask),执行完毕8、依次循环。。
执行顺序
event-Loop
闭包就是能读取其他函数内部变量的函数。
1.避免全局变量的污染2.希望一个变量长期存储在内存中(缓存变量)
优点
内存泄露(消耗)常驻内存,增加内存使用量
缺点
闭包
js中this指向的理解
相同点:1,都是用来改变函数this指向的2,第一个参数都是用来指定this指向的上下文、3,都可以利用后续参数传参
call、bind、apply的相同点与不同点
1:一开始从文档的根节点流向目标对象(捕获阶段)2:然后在目标对向上被触发(目标阶段)3:之后再回溯到文档的根节点(冒泡阶段).
DOM 事件有哪些阶段
js
file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去source-map-loader:加载额外的 Source Map 文件,以方便断点调试image-loader:加载并且压缩图片文件babel-loader:把 ES6 转换成 ES5css-loader:加载 CSS,支持模块化、压缩、文件导入等特性style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。eslint-loader:通过 ESLint 检查 JavaScript 代码
常见的Loader
define-plugin:定义环境变量commons-chunk-plugin:提取公共代码uglifyjs-webpack-plugin:通过UglifyES压缩ES6代码
常见的Plugin
1.初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;2.开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;3.确定入口:根据配置中的 entry 找出所有的入口文件;4.编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;5.完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;6.输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;7.输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
构建流程
1.多入口情况下,使用CommonsChunkPlugin来提取公共代码2.通过externals配置来提取常用库3.利用DllPlugin和DllReferencePlugin预编译资源模块 通过DllPlugin来对那些我们引用但是绝对不会修改的npm包来进行预编译,再通过DllReferencePlugin将预编译的模块加载进来。4.使用Happypack 实现多线程加速编译5.使用webpack-uglify-parallel来提升uglifyPlugin的压缩速度。 原理上webpack-uglify-parallel采用了多核并行压缩来提升压缩速度6.使用Tree-shaking和Scope Hoisting来剔除多余代码
如何提高webpack的构建速度
单页应用可以理解为webpack的标准模式,直接在entry中指定单页应用的入口即可,这里不再赘述多页应用的话,可以使用webpack的 AutoWebPlugin来完成简单自动化的构建,但是前提是项目的目录结构必须遵守他预设的规范。 多页应用中要注意的是:1.每个页面都有公共的代码,可以将这些代码抽离出来,避免重复的加载。比如,每个页面都引用了同一套css样式表2.随着业务的不断扩展,页面可能会不断的追加,所以一定要让入口的配置足够灵活,避免每次添加新页面还需要修改构建配置
怎么配置单页应用?怎么配置多页应用?
webpack
vue与react区别
web前端
0 条评论
回复 删除
下一页