2023前端面试

Html5新特性?

  • <! DOCTYPE >声明

  • canvas绘图

  • 增强型表单

  • 视频和音频

  • SVG绘图

  • 地理定位

  • 拖放API

  • WebWorker

  • WebStorage

  • WebSocket

css选择器优先级顺序是什么?

  • important > 行内样式 > id选择器 > 类选择器 > 标签选择器 > 子代选择器 >后代选择器 > 伪类选择器

css3新特性?

  • 新增选择器(属性选择器,伪类选择器,伪元素选择器)

  • 盒子模型border-box

  • filter滤镜

  • transition过度

  • transform2D转换

  • 动画animation

垂直居中的方法有哪些?

伪类和伪元素的区别?

  • 伪类存在于dom文档中,无法被dom树选中,伪元素:不存在于dom文档中是一个虚拟元素

三行省略方法?

  • display:webkit-box;-webkit-box-curanten:vartatical,-webkit-line-clamp:3

浏览器从输入url到前端页面展示发生了什么?

  1. 浏览器在本地查找域名的ip地址;

  1. 浏览器与服务器建立tcp连接;

  1. 浏览器发送请求;

  1. 某些服务会做永久重定向;

  1. 浏览器会跟踪重定向地址;

  1. 服务器处理请求发出HTML响应;

  1. 释放tcp连接;

  1. 浏览器显示页面

tcp的三次握手?

  • 第一次握手:客户端TCP进程也先建立传输控制块TCB,然后向服务端发送连接请求报文段,此时SYN=1,随机选定一个初始序号seq=x,,此报文不能携带数据,但是要消耗掉一个序号,发送完毕后,客户端进入SYN-SENT(同步已发送)状态

  • 第二次握手:服务端收到客户端请求连接报文段后,若同意建立连接,则发送确认报文,确认报文中SYN=1、ACK=1,确认号ack=x+1,同时随机选定一个自己序号seq=y,确认报文段同样不能携带数据,但是也要消耗掉一个序号,发送完毕后服务端进入SYN-RCVD(同步收到)状态

  • 第三次握手:客户端收到确认报文后,检查ACK=1,ack=x+1是否正确,若正确,则向服务端发送确认报文,确认报文中ACK=1,ack=y+1,seq=x+1,发送后进入ESTAB-LISHED状态,服务端收到确认报文后,也进入ESTAB-LISHED状态,此时双方TCP连接正式建立。

$set原理?

  • $set是在vue原型上添加$set方法,针对以下三种情况分别进行处理。

1.当key已经存在于target上的时候,直接修改target中对应key的值;

  1. 当target是数组的时候,借助vue内部拦截处理后数组的splice方法进行赋值,vue对数组的原生方法进行拦截处理成响应式,调用这些方法,可以触发界面的更新(后续添加这部分解说),如果只是通过arr[2]=2的方式进行赋值不会触发视图更新

  1. 对于新增的属性,通过defineReactive把数据转化成getter和setter的方式,并触发数据变化通知

$nextTic原理?

  • 将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。

new干了那几件事?

  1. 创建一个空对象,将它的引用赋给 this,继承函数的原型

  1. 通过 this 将属性和方法添加至这个对象

  1. 返回 this 指向的新对象,如果没有手动返回其他的对象

BFC是什么?

  • BFC是块级格式化上下文,是指浏览器中创建了一个独立的渲染区域,并且拥有一套渲染规则,他决定了其子元素如何定位,以及与其他元素的相互关系和作用.

什么是重绘,什么是回流?

  1. 重绘:只改变自身样式,不会影响到其他元素

  1. 回流:当我们对 DOM 的修改引发了 DOM 几何尺寸的变化时,浏览器需要重新计算元素的几何属性然后再将计算的结果绘制出来.

node中的事件循环和浏览器中的事件循环有什么区别?

浏览器事件循环机制中,微任务的任务队列是在每个宏任务执行完之后执行。Node事件循环机制中,微任务会在事件循环的各个阶段之间执行。

vue中created钩子里面如何获取DOM元素?

  • this$nextic(()=>{获取dom}) setTimeOut(()=>{获取dom},time)

vue父子组件生命周期?

  • 加载渲染:父beforeCreate —> 父created —> 父beforeMount —> 子beforeCreate —> 子created —> 子beforeMount —> 子mounted —> 父mounted

  • 更新数据:父beforeUpdate —> 子beforeUpdate —> 子updated —> 父updated

  • 销毁:父beforeDestroy —> 子beforeDestroy —> 子destroyed —> 父destroyed

Vuex、localStorage、sessionStorage和cookie的区别?

  1. vuex:vuex的数据存储在内存中,保密性较高.组件之间传值,响应式

缺点:刷新页面(这里的刷新页面指的是--> F5刷新,属于清除内存了)时vuex存储的值会丢失

2.localStorage:存放的数据大小一般为20Mb生命周期永久生效,除非手动删除否则关闭页面也会存在

同浏览器的不同页面间可以共享相同的localStorage,页面之间传值,非响应式.

3.sessionStorage:存放的数据大小一般为5Mb同源页面数据可共享

缺点:数据随着窗口关闭而清除

4.cookie:存放的数据大小一般为4kb,cookie 可以设置有效时间,如果不设置有效期,那么他默认是随着窗口关闭而清除

缺点:Cookie存储于浏览器,可以被篡改,服务器接收后必须先验证数据的合法性

Vue项目优化:

  • Vue 代码层面的优化

  1. v-if 和 v-show 区分使用场景

  1. computed 和 watch 区分使用场景(computed: 当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算.

watch: 当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作)

  1. v-for 遍历必须为 item 添加 key. 且避免同时使用 v-if

  1. 长列表性能优化

  1. 图片资源懒加载(使用vue-lazyload 插件)

  1. 第三方插件的按需引入

  • webpack 配置层面的优化

  1. Webpack 对图片进行压缩

  1. 减少 ES6 转为 ES5 的冗余代码

  1. 提取公共代码

  • 基础的 Web 技术层面的优化

  1. 开启 gzip 压缩(gizp压缩是一种http请求优化方式,通过减少文件体积来提高加载速度。html、js、css文件甚至json数据都可以用它压缩,可以减小60%以上的体积)

  • 浏览器缓存

  1. 浏览器缓存机制

  1. 强缓存

  1. 协商缓存

vue有哪几种路由守卫?

  • beforeEach 前置路由守卫

  • afterEach 后置路由守卫

  • beforeRouterEnter 进入组件前触发

  • beforeRouteUpdate 路由更新但是内容不会改变

  • beforeRouteLeave 离开前触发

vue双向绑定原理?

  • 通过objest.defineproperty()劫持数据的set和get方法,再结合发布订阅模式来实现

vue2.0与vue3.0响应式原理对比?

  • vue3.0采用Proxy代理整个对象

  • Proxy优势:

  1. 可以直接监听整个对象而非属性;

  1. 可以直接监听数组的变化;

  1. 有13中拦截方法,如ownKeys、deleteProperty、has 等是 Object.defineProperty 不具备的;

  1. 返回的是一个新对象,我们可以只操作新的对象达到目的,而Object.defineProperty只能遍历对象属性直接修改;

  1. proxy 的拦截方式,除了上面的 get 和 set ,还有 11 种拦截方式;

  • Object.defineProperty 的优势如下:

  1. 兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题

vue项目pc端适配不同分辨率屏幕?(转载于:https://blog.csdn.net/cc6_66/article/details/120418867?ops_request_misc=&request_id=&biz_id=102&utm_term=vue%E9%A1%B9%E7%9B%AEpc%E7%AB%AF%E5%B1%8F%E5%B9%95%E9%80%82%E9%85%8D&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-120418867.nonecase&spm=1018.2226.3001.4187

  1. 引入插件

npm install px2rem-loader -S

npm install postcss-px2rem -S

npm i lib-flexible -S

  1. 在根目录新建文件vue.config.js

// 引入等比适配插件

const px2rem = require('postcss-px2rem')

// 配置基本大小

const postcssRem = px2rem({

// 基准大小 baseSize,需要和rem.js中相同

remUnit: 16

})

module.exports = {

publicPath: "./",

lintOnSave: true,

css: {

loaderOptions: {

postcss: {

plugins: [

postcssRem

]

}

}

}

}

  1. 在src下新建util/flexible.js文件

(function(win, lib) {

var doc = win.document;

var docEl = doc.documentElement;

var metaEl = doc.querySelector('meta[name="viewport"]');

var flexibleEl = doc.querySelector('meta[name="flexible"]');

var dpr = 0;

var scale = 0;

var tid;

var flexible = lib.flexible || (lib.flexible = {});

if (metaEl) {

console.warn('将根据已有的meta标签来设置缩放比例');

var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);

if (match) {

scale = parseFloat(match[1]);

dpr = parseInt(1 / scale);

}

} else if (flexibleEl) {

var content = flexibleEl.getAttribute('content');

if (content) {

var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);

var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);

if (initialDpr) {

dpr = parseFloat(initialDpr[1]);

scale = parseFloat((1 / dpr).toFixed(2));

}

if (maximumDpr) {

dpr = parseFloat(maximumDpr[1]);

scale = parseFloat((1 / dpr).toFixed(2));

}

}

}

if (!dpr && !scale) {

var isAndroid = win.navigator.appVersion.match(/android/gi);

var isIPhone = win.navigator.appVersion.match(/iphone/gi);

var devicePixelRatio = win.devicePixelRatio;

if (isIPhone) {

// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案

if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {

dpr = 3;

} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){

dpr = 2;

} else {

dpr = 1;

}

} else {

// 其他设备下,仍旧使用1倍的方案

dpr = 1;

}

scale = 1 / dpr;

}

docEl.setAttribute('data-dpr', dpr);

if (!metaEl) {

metaEl = doc.createElement('meta');

metaEl.setAttribute('name', 'viewport');

metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

if (docEl.firstElementChild) {

docEl.firstElementChild.appendChild(metaEl);

} else {

var wrap = doc.createElement('div');

wrap.appendChild(metaEl);

doc.write(wrap.innerHTML);

}

}

function refreshRem(){

var width = docEl.getBoundingClientRect().width;

if (width / dpr > 540) {

width = width * dpr;

}

var rem = width / 100;

docEl.style.fontSize = rem + 'px';

flexible.rem = win.rem = rem;

}

win.addEventListener('resize', function() {

clearTimeout(tid);

tid = setTimeout(refreshRem, 300);

}, false);

win.addEventListener('pageshow', function(e) {

if (e.persisted) {

clearTimeout(tid);

tid = setTimeout(refreshRem, 300);

}

}, false);

if (doc.readyState === 'complete') {

doc.body.style.fontSize = 12 * dpr + 'px';

} else {

doc.addEventListener('DOMContentLoaded', function(e) {

doc.body.style.fontSize = 12 * dpr + 'px';

}, false);

}

refreshRem();

flexible.dpr = win.dpr = dpr;

flexible.refreshRem = refreshRem;

flexible.rem2px = function(d) {

var val = parseFloat(d) * this.rem;

if (typeof d === 'string' && d.match(/rem$/)) {

val += 'px';

}

return val;

}

flexible.px2rem = function(d) {

var val = parseFloat(d) / this.rem;

if (typeof d === 'string' && d.match(/px$/)) {

val += 'rem';

}

return val;

}

})(window, window['lib'] || (window['lib'] = {}));

  1. 在main.js里面引入即可

import './util/flexible.js'

方法二,其他vue项目,pc端屏幕自适应的方法:

第一步 安装lib-flexible

npm i lib-flexible --save

第二步 在项目入口文件main.js中引入lib-flexible

import 'lib-flexible/flexible.js'

第三步 在项目根目录的index.html 头部删除自动生成的meta标签, lib-flexible会根据屏幕自动生成相对于的meta标签

// 删除

<meta name="viewport" content="width=device-width, initial-scale=1.0">

第四步 使用postcss-pxtorem,用于将像素单元生成rem单位。

//安装依赖

npm install postcss-pxtorem -D

第五步 设置规则(在package.json中配置如下)

"postcss": {

"plugins": {

"autoprefixer": {},

"postcss-pxtorem": {

"rootValue": 64,

"propList": [

"*"

]

}

}

}

//另一种可以新建postcss.config.js,写入如下代码

module.exports = {

plugins: {

// 兼容浏览器,添加前缀

autoprefixer: {

overrideBrowserslist: [

"Android 4.1",

"iOS 7.1",

"Chrome > 31",

"ff > 31",

"ie >= 8",

"last 10 versions", // 所有主流浏览器最近10版本用

],

grid: true,

},

"postcss-pxtorem": {

rootValue: 16, //结果为:设计稿元素尺寸/16,比如元素宽320px,最终页面会换算成 20rem

propList: ["*"], //是一个存储哪些将被转换的属性列表,这里设置为['*']全部,假设需要仅对边框进行设置,可以写['*', '!border*']

unitPrecision: 5, //保留rem小数点多少位

//selectorBlackList: ['.radius'], //则是一个对css选择器进行过滤的数组,比如你设置为['fs'],那例如fs-xl类名,里面有关px的样式将不被转换,这里也支持正则写法。

replace: true, //这个真不知到干嘛用的。有知道的告诉我一下

mediaQuery: false, //媒体查询( @media screen 之类的)中不生效

minPixelValue: 12, //px小于12的不会被转换

},

},

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值