前端面试题目-高频问题集合

发布于:2025-05-31 ⋅ 阅读:(21) ⋅ 点赞:(0)

1.CSS里面水平垂直居中的方法

1.CSS里面水平垂直居中的方法

    弹性布局
    display: flex;               /*先开启flex布局*/
    justify-content: center;     /*实现水平居中*/
    jalign-items: center;        /*实现垂直居中*/
      

    网格布局
    display: grid;           /*先开启grid布局*/
    place-items: center;     /*实现水平垂直居中*/



    绝对定位 + Transform
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);


    绝对定位 + 负边距
    position: absolute;
    width: 200px;
    height: 100px;
    left: 50%;
    top: 50%;
    margin-left: -100px;          /* width/2 */
    margin-top: -50px;            /* height/2 */

    Table-Cell 布局
    .parent {
        display: table-cell;
        vertical-align: middle; /* 垂直居中 */
        text-align: center;     /* 水平居中 */
    }
    .child {
        display: inline-block;  /* 行内块元素 */
    }

    行内元素居中
    .parent {  
       text-align: center;      /* 水平居中 */
       line-height: 400px;      /* 垂直居中(需等于容器高度) */
    }
    .child {
       display: inline-block;
       vertical-align: middle;  /* 微调垂直对齐 */
    }

    绝对定位 + margin 自动填充
    .child {
      width: 200px;
      height: 100px;
      margin: auto;
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
    }

2. 简单冒泡排序

function test(){
   let arr = [8,6,2,7,1,3,5,4];
   let len = arr.length;
   for(let i=0;i<len-1;i++){
     for(let j=0;j<len-1;j++){
       if(arr[j]>arr[j+1]){
         [arr[j],arr[j+1]] = [arr[j+1],arr[j]]
        }
     }
   }
   return arr
}

2. 数组操作

输入 const arr = [1, '2', [null, ['1'], NaN, null, '0']];
输出 [0,1,2]
const result = [...new Set(
  arr.flat(Infinity)
    .map(item => Number(item))
    .filter(num => !Number.isNaN(num))
)].sort((a, b) => a - b);

console.log(result);
输入数组 const array = [2,1,3,4,5,6,1,5,1];
输出数组字符串 [2,[1,1,1],3,4,[5,5],6]
const elementMap = new Map();
array.forEach(val => {
  if (!elementMap.has(val)) {
     elementMap.set(val, []);
  }
  elementMap.get(val).push(val);
});

const processed = new Set();
const result = [];
array.forEach(val => {
if (!processed.has(val)) {
   const group = elementMap.get(val);
   result.push(group.length > 1 ? [...group] : val);
   processed.add(val);
}
});
console.log(JSON.stringify(result))

其他前端八股文知识点

--js的数据类型
6种。Number、String、Boolean、Null、undefined、object、ES6 中新增了一种 Symbol ,可解决属性名冲突问题,bigInt可操作大整数。
Object 包含了Data、function、Array等。这三种是常规用的。

--vue双向绑定原理
1.vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;
2.核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法;
3.介绍一下Object.defineProperty()方法
(1)Object.defineProperty(obj, prop, descriptor) ,这个语法内有三个参数,分别为 obj (要定义其上属性的对象) prop (要定义或修改的属性) descriptor (具体的改变方法)
(2)简单地说,就是用这个方法来定义一个值。当调用时我们使用了它里面的get方法,当我们给这个属性赋值时,又用到了它里面的set方法

--Vue2.0和Vue3.0有什么区别
1.重构响应式系统,使用Proxy替换Object.defineProperty
Proxy优势:
•可直接监听数组类型的数据变化
•监听的目标为对象本身,不需要像Object.defineProperty一样遍历每个属性,有一定的性能提升
•可拦截apply、ownKeys、has等13种方法,而Object.defineProperty不行
•直接实现对象属性的新增/删除
2.新增Composition API,更好的逻辑复用和代码组织
•重构 Virtual DOM
•模板编译时的优化,将一些静态节点编译成常量
•slot优化,将slot编译为lazy函数,将slot的渲染的决定权交给子组件
•模板中内联事件的提取并重用(原本每次渲染都重新生成内联函数)
•代码结构调整,更便于Tree shaking,使得体积更小
•使用Typescript替换Flow

--常用浏览器的内核
浏览器的内核的种类很多,常见的浏览器内核可以分为四种:Trident、Gecko、Blink、Webkit。
1. Trident (IE内核)
 国内很多的双核浏览器的其中一核便是 Trident,美其名曰 "兼容模式"。
 代表 IE、傲游、世界之窗浏览器、Avant、腾讯TT、猎豹安全浏览器、360极速浏览器、百度浏览器等。
 Window10 发布后,IE 将其内置浏览器命名为 Edge,Edge 最显著的特点就是新内核 EdgeHTML。
2. Gecko(firefox)
    FireFox(火狐浏览器) 采用该内核,Gecko 的特点是代码完全公开,因此,其可开发程度很高,全世界的程序员都可以为其编写代码,增加功能。 可惜这几年已经没落了, 比如 打开速度慢、升级频繁。
3.webkit(Safari)
   傲游浏览器3、 Apple Safari (Win/Mac/iPhone/iPad)、Symbian手机浏览器、Android 默认浏览器。
4.Chromium/Blink(chrome)
   在 Chromium 项目中研发 Blink 渲染引擎(即浏览器核心),内置于 Chrome 浏览器之中。Blink 其实是 WebKit 的分支。大部分国产浏览器最新版都采用Blink内核。

--闭包定义
函数A中的函数B,能够访问函数A中的变量,函数B就是一个闭包,闭包的变量是存储在堆内存中。
function A(){
var a="外面的变量"
    window.B=function(){
    console.log(a);
}
}

--继承
这个继承最为简单,它的实现原理是,每一个AO对象都有一个prototype,返回对象类型原型的引用,所以可以给它赋值一个对象,就可以实现简单的原型链继承。
function Animal(){
    this.eat = function(){
        alert("我会吃");
    }
}

function Bird(){
    this.fly = function(){
        alert("我会飞");
    }
}
//设置Bird类的原型为一个Animal对象
Bird.prototype = new Animal();

var pigeon = new Bird();
pigeon.fly();
pigeon.eat();

--WEB工作原理
HTTP处理流程:建立连接–>客户端浏览器发送请求信息—>web服务器解析请求并找到相应的资源将文件以及其它信息组成HTTP响应返回客户端–>关闭连接。

--watch和computed的区别
computed:
计算属性,有缓存机制;不能接受参数;可以依赖其他computed,甚至是其他组件中的data;不能与data中的属性重复。计算属性适合一个数据受多个数 据影响

watch:
侦听属性,可接受两个参数;监听时可触发一个回调,并做一些事情;监听的属性必须存在;允许异步。监听器适合一个数据影响多个数据。

--var,const,let区别
var定义的变量可以修改,如果不初始化会输出undefined,不会报错;const定义的变量不可以修改,而且必须初始化;let是块级作用域,函数内部使用let定义后,对函数外部无影响。

--Vue中的的通信方式有几种?
props/$emit 适用父子组件通信
ref与parent/children适用父子组件通信
EventBus(事件总线) 适用于父子、隔代、兄弟组件通信
attrs/listeners 适用于隔代组件通信
provide/inject 适用于隔代组件通信
vuex 适用于父子、隔代、兄弟组件通信
slot插槽方式

--vue与angular和react的对比
1、vue在设计之初参考了很多angularjs的思想
2、vue相对比与angular比较简单
3、 vue相对比与angular比较小巧,运行速度快
4、 vue与angular数据绑定都可以用{{}}
5、vue指令用v-xxx angularjs用ng-xxx
6、vue数据放在data对象里面,angular数据绑定到$scope对象上
vue对比react
1、vue与react都使用 virtual DOM
2、vue与react都提供了组件化的视图组件
3、 vue与react将注意力集中保持在核心库,有丰富的插件库
4、react使用jsx渲染页面,vue使用更简单的模版
5、vue比react运行速度更快

--VUE服务器端的渲染
要使用服务器端渲染,需要使用server-entry.js和client-entry.js两个入口文件,两者都会使用到app.js进行打包,其中通过server-entry.js打包的代码是运行在node端,二通过client-entry.js打包代码运行在客户端。

--watch和computed的区别
computed:
计算属性,有缓存机制;不能接受参数;可以依赖其他computed,甚至是其他组件中的data;不能与data中的属性重复。计算属性适合一个数据受多个数 据影响

watch:
侦听属性,可接受两个参数;监听时可触发一个回调,并做一些事情;监听的属性必须存在;允许异步。监听器适合一个数据影响多个数据。

--var,const,let区别
var定义的变量可以修改,如果不初始化会输出undefined,不会报错;const定义的变量不可以修改,而且必须初始化;let是块级作用域,函数内部使用let定义后,对函数外部无影响。

--详解vue生命周期
每个Vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是vue的生命周期。
在vue一整个的生命周期中会有很多钩子函数      
beforeCreate(创建前状态)
created(创建完毕状态;在这个生命周期之间,进行初始化事件,进行数据的观测,可以看到在created的时候数据已经和data属性进行绑定(放在data中的属性当值发生改变的同时,视图也会改变)。
但是此时还是没有el选项)
beforeMount(挂载前状态;首先会判断对象是否有el选项。如果有的话就继续向下编译,如果没有el选项,则停止编译,也就意味着停止了生命周期,直到在该vue实例上调用vm.$mount(el))
mounted(挂载结束状态;因为此时还有DOM元素挂在到页面上,还是JavaScript中的虚拟DOM形式存在的)
beforeUpdate(更新前状态)
updated(更新完成状态;当vue发现data中的数据发生了改变,会触发对应组件的重新渲染,先后调用beforeUpdate和updated钩子函数)
beforeDestroy(销毁前状态;钩子函数在实例销毁之前调用。在这一步,实例仍然完全可用。)
destroyed(销毁完成状态;钩子函数在Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。)

--vue 父子组件的生命周期顺序,加载渲染过程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

--Cookies、localStorage和sessionStorage三者之间的区别
cookies是会话机制,它是在设置的时间内(自己设置的)有效,存储的数据大小在4k左右,只能作用于当面目录以及当前的子目录。
​ localStorage是属于本地存储的一种,是永久存储,除非手动删除,否则一直有效,储的数据大小在20M左右。
​ sessionStorage也是属于本地存储的一种,是临时存储,在关闭当前页面或者当前浏览器窗口前有效,存储的数据大小在5M左右。
 cookies的安全性比loaclStorage和sessionStorage的安全性好。

--ES6的特性,Promise的理解
1.变量声明:const和let ,let表示声明变量,而const表示声明常量,两者都为块级作用域;
   const 声明的变量都会被认为是常量,意思就是它的值被设置完成后就不能再修改了:如果const的是一个对象,对象所包含的值是可以被修改的。抽象一点儿说,就是对象所指向的地址没有变就行。
   let 和 const 声明只在最靠近的一个块中(花括号内)有效;
   const 在声明时必须被赋值
2. 箭头函数(Arrow Functions)
  不需要 function 关键字来创建函数
  省略 return 关键字
  继承当前上下文的 this 关键字,箭头函数不能用作构造器,没有单独的this,和 new一起用会抛出错误
  var add = (a, b) => a + b;
3. 函数的参数默认值
4. for...of 和 for...in
   for...of 用于遍历一个迭代器
   for...in 用来遍历对象中的属性
5. ES6 中支持 class 语法
   ES6的class不是新的对象继承模型,它只是原型链的语法糖表现形式。函数中使用 static 关键词定义构造函数的的方法和属性。
6.ES6 原生提供了 Promise 对象。Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。
   对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:
   pending: 初始状态,不是成功或失败状态。
   fulfilled: 意味着操作成功完成。
   rejected: 意味着操作失败。

--CSS预处理器(sass或less)
1.用一种专门的编程语言,为CSS增加了一些编程的特性,将CSS作为目标生成文件,然后开发者就只要使用这种语言进行编码工作

--深拷贝和浅拷贝的区别
1.假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。
2.深拷贝,是拷贝对象各个层级的属性,拷贝对象的地址。   JSON.parse(JSON.stringify())
3.浅拷贝,指针指向堆中相同的地址,所有会改变原来的数据。 Object.assign();Array.prototype.slice()

--页面优化有哪些方面
1.利用浏览器缓存 :
 强缓存:不用请求服务器,直接使用本地的缓存。强缓存是利用 http 响应头中的Expires或Cache-Control实现的。
Cache-Control的优先级高于Expires。
Cache-Control:服务器返回的相对时间。
Expires:服务器返回的绝对时间。
协商缓存:浏览器发现本地有资源的副本,但是不太确定要不要使用,于是去问问服务器。
当浏览器对某个资源的请求没有命中强缓存(也就是说超出时间了),就会发一个请求到服务器,验证协商缓存是否命中。
2.资源压缩合并,减少http请求
   合并图片(css sprites)、CSS和JS文件合并、CSS和JS文件压缩
   图片较多的页面也可以使用 lazyLoad 等技术进行优化。    
3.非核心代码异步加载 --> 异步加载的方式 --> 异步加载的区别
  动态脚本加载
  defer、async   

--单页面应用(SPA)的理解
  就是指一个系统只加载一次资源,之后的操作交互、数据交互是通过路由、ajax来进行,页面并没有刷新。就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。
  页面切换跳转时,并不需要做html文件的请求,这样就节约了很多http发送时延,我们在切换页面的时候速度很快。
  优点:
 1、用户操作体验好,用户不用刷新页面,整个交互过程都是通过Ajax来操作。
 2、适合前后端分离开发,服务端提供http接口,前端请求http接口获取数据,使用JS进行客户端渲染。
 缺点:
 1、首页加载慢
 单页面应用会将js、 css打包成一个文件,在加载页面显示的时候加载打包文件,如果打包文件较大或者网速慢则用户体验不好,首屏时需要请求一次html,同时还要发送一次js请求,两次请求回来了,首屏才会展示出来。相对于多页应用

--js创建对象的三种方法
1.第一种方式,字面量 var o1 = {name: "o1"}
2.第二种方式,通过构造函数 var vm = new Vue({ // 选项})
3.第三种方式,Object.create
var  p = {name: "p"}
var o4 = Object.create(p)

--v-if 和 v-show 的区别)
1. v-show 只是简单的控制元素的 display 属性,而 v-if 才是条件渲染(条件为真,元素将会被渲染,条件为假,元素会被销毁)
2. v-show 有更高的首次渲染开销,而 v-if 的首次渲染开销要小的多;
3. v-if 有更高的切换开销,v-show 切换开销小;

--vue中v-for中key值的作用
1.vue和react都实现了一套虚拟DOM,使我们可以不直接操作DOM元素,只操作数据便可以重新渲染页面。而隐藏在背后的原理便是其高效的Diff算法。
2.key的作用主要是为了高效的更新虚拟DOM
3. 两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构;同一层级的一组节点,他们可以通过唯一的id进行区分。

--uni-app的介绍
uni-app是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台。

--解决跨域问题
1.通过jsonp的方法:jsonp原理就是通过script标签引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。
所以jsonp是需要服务器端的页面进行相应的配合的。(即用JavaScript动态加载一个script文件,同时定义一个callback函数给script执行而已。)
​<script type="text/javascript">
    function dosomething(jsondata){
        //处理获得的json数据
    }
</script>
<script src="http://example.com/data.php?callback=dosomething"></script>
2.通过后台服务设置响应头允许跨域(CORS方式)
3.通过代理去请求第三方接口
2.document.domain + iframe跨域,此方案仅限主域相同,子域不同的跨域应用场景。
3.location.hash + iframe
4. window.name + iframe跨域
5.postMessage是HTML5 XMLHttpRequest Level 2中的API

--判断数据类型
1、typeof
   typeof是一个操作符,右侧跟一个一元表达式,返回这个表达式的数据类型,以字符串的形式表示。
2、instanceof
    利用instanceof来判断A是否为B的实例,表达为A instanceof B,返回一个布尔值。
instanceof的原理是通过检测对象的原型链上是否含有类型的原型。
3、constructor
    每个构造函数都会有一个prototype属性,即为构造函数的原型对象,而原型对象中会有一个constructor属性指回到构造函数。
    当利用构造函数创建新对象时,原型上的constructor属性也会被遗传到新创建的对象上,从原型链的角度讲,构造函数也代表了对象的类型。
4、Object.prototype.toString.call()
    toString()方法是Object原型上的方法,调用此方法,返回格式为[object,xxx],xxx即为判断的结果。
    对于Object对象可以直接调用Object.prototype.toString(),对于其他数据类型,需要通过.call()来调用。
 
--面向过程和面向对象的区别
  1.面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
  2.面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

--webpack与vue-cli的关系
  vue-cli是基于nodejs+webpack封装的命令行工具。你可以理解为汇集了各种命令的 bash,或者bat。
  用vue-cli执行build,实际上是webpack做的。原本需要自己配置webpack的相关配置,被cli简化了。并且按照vue的用户习惯整理了一套构建和目录规范

--webpack的原理
webpack是一个现代化javascript应用程序的静态模块打包器(module bundler),是一种实现前端模块化的构建工具。
webpack打包过后是将一个一个的模块变成了一个对象,key是模块路径,值是模块里面的代码,只是代码被转化成了字符串,被放在eval环境里面,
这样实现的基础是,webpack实现了一个函数_webpack_require()函数,用来引入不同的模块,进而处理模块之间的关系。
主要靠两个对象:compiler对象和compilation对象
compiler 对象包含了 Webpack 环境所有的的配置信息,包含 options,loaders,plugins 这些信息,这个对象在 Webpack 启动时候被实例化,它是全局唯一的,可以简单地把它理解为 Webpack 实例;
compilation 对象包含了当前的模块资源、编译生成资源、变化的文件等。当 Webpack 以开发模式运行时,每当检测到一个文件变化,一次新的 Compilation 将被创建。
compilation 对象也提供了很多事件回调供插件做扩展。通过 Compilation 也能读取到 Compiler 对象。
compiler 代表了整个 webpack 从启动到关闭的生命周期,而 compilation 只是代表了一次新的编译。
compiler 和 compilation 都继承自 Tapable,可以直接在Compiler 和 Compilation 对象上广播和监听事件
webpack 插件是一个具有 apply 方法的 JavaScript 对象
webpackOptionsApply
调用 new WebpackOptionsApply().process 方法,加载各种内置插件
注入 EntryOptionPlugin 插件,处理 entry 配置
根据 devtool 值判断后续用那个插件处理 sourcemap,可选值:EvalSourceMapDevToolPlugin、SourceMapDevToolPlugin、EvalDevToolModulePlugin
注入 RuntimePlugin ,用于根据代码内容动态注入 webpack 运行时
entry: 定义整个编译过程的起点
output: 定义整个编译过程的终点
module: 定义模块module的处理方式
plugin 对编译完成后的内容进行二度加工
resolve.alias 定义模块的别名

--webpack优化项目
1、CommonsChunkPlugin提取公共代码
 dll-plugin进行大文件单独打包,缓存(常用的库不需要重复打包,后面直需要引用进去就可以)
 删除无用的依赖(后面会提到
 选择性的弃用一些依赖
 代码压缩
2.优化打包时间
externals 避免打包大的第三方依赖
happypack 多进程处理,缓存
缓存与增量构建
减少构建搜索或编译路径 alias resolve
具象打包的范围 include exclude

--防抖和节流
防抖:触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间。
节流:高频事件触发,但在 n 秒内只会执行一次,所以节流会稀释函数的执行频率
区别:防抖动是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行。

--栈和堆的区别
申请方式的不同。栈由系统自动分配,而堆是人为申请开辟;
申请大小的不同。栈获得的空间较小,而堆获得的空间较大;
申请效率的不同。栈由系统自动分配,速度较快,而堆一般速度比较慢;
存储内容的不同。栈在函数调用时,函数调用语句的下一条可执行语句的地址第一个进栈,然后函数的各个参数进栈,其中静态变量是不入栈的。而堆一般是在头部用一个字节存放堆的大小,堆中的具体内容是人为安排;
底层不同。栈是连续的空间,而堆是不连续的空间。

--TCP和UDP的区别
TCP(传输控制协议)和UDP(用户数据报协议)是互联网传输层常用的两种协议。
TCP:面向连接的协议,提供可靠的数据传输,通过三次握手建立连接,并使用滑动窗口和确认机制保证数据的可靠性。通过重传、确认和流量控制等机制确保数据的可靠传输,适用于对可靠性要求较高的应用,但会引入较大的传输延迟和额外的开销。面向连接的协议,需要在通信双方建立连接后才能进行数据传输,适用于需要确保数据完整性和顺序的应用,如HTTP、FTP等
UDP:面向无连接的协议,不提供可靠性保证,数据被封装成数据报直接发送,无需建立连接和维护状态。无可靠性保证,数据传输更快,适用于对实时性要求较高、丢失部分数据可容忍的应用,如音视频流媒体。无连接的协议,数据包独立发送,适用于需要快速传输和广播的应用,如DNS、实时游戏等。
其他比较要点
1. TCP协议相对复杂,需要维护连接状态和处理各种机制,而UDP较为简单,传输开销较小。
2. TCP在网络拥塞时会自适应降低传输速率,而UDP不具备拥塞控制机制。
3. TCP支持点对点传输和多播传输,而UDP支持点对点、多播和广播传输。


网站公告

今日签到

点亮在社区的每一天
去签到