前端面试点集合【持续更新】

在这里插入图片描述

面试题

//考察:原型,迭代器,可迭代协议
//让下面的代码成立
var [a,b] = {a:1,b:2}

//在执行这个代码前,执行以下代码
//把对象变成可迭代对象,因为数组就是可迭代对象
Object.prototype[Symbo.iterator] = function(){
	return Object.values(this)
}

React

1.使用 useState 多次渲染,如何优化

2.react的hook组件有哪些?

3.类组件和函数组件有什么不同?

4.react的生命周期

5.useCallBack和useMemo优化在哪里

6.函数渲染安全还是使用类的this渲染安装

7.react源码解刨

Vue

1.vue 响应式原理如何实现?

vue2 通过object.defineProperty(发布订阅模式+数据劫持)
vue3 通过proxy

Observer负责将数据转换成getter/setter形式;
Dep负责管理数据的依赖列表;是一个发布订阅模式,上游对接Observer,下游对接Watcher
Watcher是实际上的数据依赖,负责将数据的变化转发到外界(渲染、回调);
首先将data传入Observer转成getter/setter形式;当Watcher实例读取数据时,会触发getter,被收集到Dep仓库中;当数据更新时,触发setter,通知Dep仓库中的所有Watcher实例更新,Watcher实例负责通知外界
https://juejin.cn/post/6844903597986037768

2.vue中如何让没有响应式数据变成响应式?

3.proxy和object.defineProperty 之间的优缺点

Proxy:

优势:

  1. 性能更高:Proxy 相比 Object.defineProperty 有更好的性能表现,特别是在处理大量数据或嵌套对象时。
  2. 更多的拦截方法:Proxy 提供了丰富的拦截方法,可以拦截对象的读取、赋值、删除等操作,更加灵活。
  3. 更多的应用场景:Proxy 不仅可以实现数据的响应式,还可以用于拦截数组操作、实现数据验证、实现数据持久化等功能。
  4. 语法简洁:Proxy 的语法相对简洁明了,易于理解和使用。

劣势:

  1. 兼容性:Proxy 不支持 IE 浏览器及旧版浏览器,而且在某些情况下可能需要额外的 polyfill。
  2. 不可变性变更:Proxy 无法监听对象属性的变更,比如通过 Object.freeze() 冻结的对象,而 Object.defineProperty 可以监听到。
  3. 部分代理不稳定:Proxy 无法完全模拟原生对象的行为,有时可能会导致一些意外行为或兼容性问题。

Object.defineProperty:

优势:

  1. 兼容性更好:支持大多数现代浏览器以及 IE9+。
  2. 对不可变对象的支持:可以监听到通过 Object.freeze() 冻结的对象的属性变更。
  3. 稳定性:在大多数情况下,Object.defineProperty 可以可靠地实现对象的响应式。

劣势:

  1. 性能较差:Object.defineProperty 需要为每个属性单独设置 getter 和 setter,对于大量数据或嵌套对象,性能较低。
  2. 功能较少:Object.defineProperty 只能监听对象属性的读取和赋值操作,无法拦截其他操作。
  3. 语法繁琐:Object.defineProperty 的语法相对繁琐,需要手动为每个属性设置 getter 和 setter,代码可读性较差。

vue2
vue一般使用template来创建HTML,然后在有的时候,我们需要使用javascript来创建html,这时候我们需要使用render函数。

render参数里有一个函数叫h,h就是对单文件组件进行虚拟DOM的创建,然后通过render进行解析
template最终还是通过render的方式再次进行编译

相同之处:
1.render和template都是创建html
不相同之处:
1.template适合简单逻辑,render适合复杂逻辑
2.template理解容易,但灵活度不够高。自定义render灵活性高,但是对使用者要求高
3.render性能比template高
4.render使用js方式做渲染,template使用html方式做渲染
5.render函数优先级大于template

4.1 什么时候用render函数?

组件复杂时可以用render,简单直接使用template
创建一个各种类型的按钮为例子:
template

<template>
<div class="btn btn-success" v-if="type === 'success'">{{ text }}</div>
<div class="btn btn-danger" v-else-if="type === 'danger'">{{ text }}</div>
<div class="btn btn-warning" v-else-if="type === 'warning'">{{ text }}</div>
</template>

render

<script>
Vue.component("G-Btn", {
		# 获取父级传来的值
       props: {
           type: {
               type: String,
               default: 'default'
          },
           text: {
               type: String,
               default: '按钮'
          }
      },
      # 计算属性
       computed: {
           tag() {
               switch(this.type) {
                   case'success':
                       return 1;
                   case'danger':
                       return 2;
                   case'warning':
                       return 3;
                   default:
                       return 1;
              }
          }
      },
      # 创建html
       render(createElement) {
           return createElement('div', {
               class: {
                   btn: true,
                   'btn-success': this.type==='success',
                   'btn-danger': this.type==='danger',
                   'btn-warning': this.type==='warning'
              },
               on: {
                   click: this.handleClick
              }
          },
           this.$slots.default
          );
      },
       methods: {
           handleClick() {
               console.log('点击成功');
          }
      }
  })

   let appData= new Vue({
       el: "#app"
  })
</script>

5.template渲染过程

Vue推荐在绝大多数情况下使用template来创建你的HTML。但是模版毕竟是模版,不是真实的dom节点。从模版到真实dom节点还需要经过一些步骤:
1.把模版编译为render函数
2.实例进行挂载,根据跟节点render函数的调用,递归的生成虚拟dom
3.通过diff算法对比虚拟dom,渲染到真实dom(类似于react的虚拟DOM渲染过程)
4.组件内部data发生变化,组件和子组件引用data作为props重新调用render函数,生成虚拟DOM,返回到步骤3

6.在 Vue 中为什么不推荐用 index 做 key

1.用 index 作为 key 时,在对数据进行,逆序添加,逆序删除等破坏顺序的操作时,会产生没必要的真实 DOM更新,从而导致效率低

2.用 index 作为 key 时,如果结构中包含输入类的 DOM,会产生错误的 DOM 更新

3.在开发中最好每条数据使用唯一标识固定的数据作为 key,比如后台返回的 ID,手机号,身份证号等唯一值
4.如果不存在对数据逆序添加,逆序删除等破坏顺序的操作时,仅用于渲染展示用时,使用 index 作为 key 也是可以的(但是还是不建议使用,养成良好开发习惯)。

作者:政采云前端团队
链接:https://juejin.cn/post/7026119446162997261
来源:稀土掘金

7.mutation为什么是同步,action为什么是异步的?

Vuex

state:存储公共数据(相当于组件中的data)
mutations:修改数据方法的集合,必须是同步
getters:类似于computed计算属性(利用现有的状态进项计算得到新的数据—派生)
actions:异步操作
modules:模块化拆分
2

8.封装vue3组件的注意问题

前端

1.单向数据流和双向数据流的区别。

2.js中的this指针指向问题

https://zhuanlan.zhihu.com/p/159322871
箭头函数、call、apply、bind等手法改变this指向
在这里插入图片描述

3.call apply修改this指向

4.闭包的坏处,如何使用闭包?

5.原型链

6.作用域和作用域链

作用域:程序中定义变量的区域,它决定了当前执行代码对变量的访问权限
作用域链:可执行代码内部访问变量时,会先查找当前作用域下有无该变量,有则立即返回,没有则会去父级作用域中查找,一直找到全局作用域。这种作用域的嵌套机制称为作用域链

7.堆和栈

在这里插入图片描述

基本数据类型:直接存储在内存中,占据空间小,大小固定,属于被频繁使用的数据。
引用数据类型:同时存储在内存与内存中,占据空间大,大小不固定。引用数据类型将指针存在中,将值存在中。当我们把对象值赋值给另外一个变量时,复制的是对象的指针,指向同一块内存地址。

堆:存储引用类型值的空间
栈:存储基本类型和指定代码的环境

let a={},
b = "0",
c = 0
a[b] = "1111"
a[c] = "2222"
console.log(a[b])
结果为:2222
解刨:
a["0"] = "1111"
a[0]   = "2222"
结论:对象属性不能重复,数字和字符串属性名相同,堆就不重要了
#ES6新增:Symbol 表示独一无二的值
let a={},
b = Symbol("1")
c = Symbol("1")
a[b] = "1111"
a[c] = "2222"
console.log(a[b])
结果为:1111
结论:对象属性名只能是字符串是不严谨的,这里看出还有Symbol的值

8.对象和数组的区别?

区别一:
数组表示有序数据的集合
对象表示无序数据的集合
如果数据对顺序很重要,就用数组,否则用对象
区别二:
数组的数据没有名称,对象的数据有名称

9.闭包

9.1
var test = (function(i){
	return function(){
		alert(i *=2)
	}
})(2)
test(5)
结果为:"4"
因为alert会把值转为字符串

匿名函数可以访问外部 i 的值,因为匿名函数可以创建自己的执行上下文,会创建自己相应的作用域链和变量对象

9.1 执行上下文

每当运行代码时,代码就会执行上下文(执行环境)

执行上下文分为两个阶段:
创建阶段:作用域链(当前变量对象+所有父级变量对象)变量对象(参数,变量,函数声明)this
执行阶段:变量赋值函数引用

执行上下文分为:全局环境函数环境Eval环境

9.2 作用域链
9.2.1 作用域链例子一

作用域链是通过闭包实现

//books执行上下文
fucntion books(){
	var book = "书包里的书本"
	//匿名函数执行上下文
	return function(){
		console.log(book)
	}
}
var bag = books()
//全局执行上下文
bag();

说明:
可执行代码内部访问变量时,会查找当前作用域是否有book变量,有就会立马返回输出,没有就会向父级作用域中查找,知道找到全局作用域

匿名函数执行上下文:{作用域链:{匿名函数变量对象+books变量对象+books变量对象+全局变量对象},{变量对象}}
books执行上下文:{作用域链:{books变量对象+全局变量对象},{变量对象:book}}
全局执行上下文:{作用域链:{全局变量对象},{变量对象:books,bag}}

作用域链的解释:
作用域链都是一层链接一层,每新建一层都会包含之前新建的一层变量对象,最顶层的链层是最优先的。这里的三层中匿名函数就是顶层链,所以是最优先执行
在这里插入图片描述

9.2.2 作用域链例子二
for(var i = 0;i<5;i++){
	setTimeout(function(){
		console.log(i++)
	},4000)
}
console.log(i)
运行结果:
5,5,6,7,8,9

先运行主栈,然后再运行宏任务(setTimeout中的方法)

9.2.3 作用域链例子三
for(var i = 0;i<5;i++){
	//立即执行
	(function(x){
		setTimeout(function(){
		console.log(i++)
	},4000)
	})(i)
}
console.log(i)
运行结果:
501234

先运行主栈,然后再运行宏任务(setTimeout中的方法)

10.null和undefined的区别

  /**
   * null 表示无对象
   * undefined 表示没有值
   */

  /**
   * var a;
   * a没有赋值所以是undefined
   */

  /**
   * document.getElementById("xxxxx")  等到为null
   * 应该获取到一个dom对象,但是xxxxx不存在,所有是no object.所以是null
   */

什么时候用null?
你要表达的数值是一个对象,但是现在没有对象,就可以用null

什么时候用undefined?
当前值可以表示任何东西,但是他没有值,就可以用undefined

11.同步和异步

async function async1(){
	console.log("async1 start")
	await async2()
	console.log("async1 end")
}
async function async2(){
	console.log("async2")
}
console.log("script start")
setTimeout(function(){
	console.log("setTimeout")
},0)
async1();
new Promise(functtion(resolve){
	console.log("promise1")
	resolve();
}).then(function(){
	console.log("promise2")
})
console.log("script end")
运行结果
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout

浏览器是多线程
JS是单线程 => 浏览器只给其中一个线程来渲染

分析:

创建函数 async1
创建函数 async2
="script start"
设置定时器(异步) (宏任务A)
函数执行
	="async1 start"
	await async2() 执行async2,等待返回结果(微任务B)
		="async2"
new Promise会立即执行函数(new的时候是同步)
	="promise1"
		resolve()/reject() (微任务C)
="script end"

主栈第一阶段完成

异步队列分为:微任务队列宏任务队列
宏任务执行完,才到微任务

微任务						宏任务
B:async2的结果,有结果		A:setTimeout()  xxms执行
再执行下面代码				
C:resolve/reject
执行的时候把then/catch
中的方法执行

12.宏任务和微任务

异步队列分为:微任务队列宏任务队列
宏任务执行完,才到微任务
宏任务队列有:
1.setTimeout()和setInterval()
2.DOM事件
3.AJAX请求

微任务队列有:
1.新程序或子程序被直接执行
2.事件的回调函数
3.Promise .then() .catch() .finally()
4.MutationObserver

遇到new promise直接执行,因为构造方法会直接执行

宏任务和微任务的运行机制
在这里插入图片描述
如果只是简单的宏任务和微任务执行,应该是 微任务 执行比 宏任务 早
两者之间应该是DOM渲染影响
执行顺序:微任务 > DOM渲染 > 宏任务
实例代码

let test = '<p>测试</p>'
$('#box').append(test)

console.log(1)

Promise.resolve().then(()=>{
	console.log('2 promise')
	alert('promise then')
})

setTimeout(()=>{
	console.log('3 setTimeout')
	alert('setTimeout')
},0)

console.log(4)

执行结果:
1->4->弹出promise then,打印2 promise->测试渲染出来, 弹出setTimeout,打印3 setTimeout

参考:https://blog.csdn.net/qq_44624386/article/details/107344664

13.defer和async的区别

因为js是单线程执行,所以async和defer可以解决网络的阻塞的问题,但是两则都只适用于外部脚本
async:异步处理函数
浏览器会立即进行下载,同时继续加载页面。但是async下的脚本具体什么时候执行就说不一定了
在这里插入图片描述
defer:推迟执行函数
不管脚本是否加载完,都会等到浏览器解析完html以后再执行脚本,defer比较适合与DOM有关联的脚本
在这里插入图片描述

14.Promise

Promise优点:
1.Promise能解决异步处理的问题
2.解决回调地狱
3.能对错误代码进行捕获

Promise缺点:
1.无法取消Promise,一旦新建他会立即执行,中途无法取消。
2.如果不设置回调,promise内部抛出的错误,外部是不会获取到。
3.如果处于pending等待状态时,无法得知目前进展到哪一个阶段。

15.typeof和instanceof的区别

typeof:检测数据类型输出类型名称
简单数据类型
Undefined,Null,Boolean,Number和String
复杂数据类型
Object

instanceof:检测对象之间的关联性。(常用在检测该属性和函数是否在原型链中)

16.函数柯里化

/**
   * 什么是柯里化
   * 把接收多个参数的函数编程一个接收一个参数的函数,并返回接收多个参数的时,返回新函数
   * @returns {inner}
   */
  //基本柯里化
  // function add(){
  //     //把保存参数的arguments赋值给args变量
  //     let args = arguments
  //     let inner = function(){
  //       args.push(...arguments)
  //     }
  //     //返回inner内部函数实现基本的柯里化
  //     return inner
  //   }
  //
  //   console.log(add(1));


  // function add(){
  //   //Array.prototype.slice.call是把调用方法的参数截取出来
  //   let args = Array.prototype.slice.call(arguments)
  //   let inner = function(){
  //     args.push(...arguments)
  //     let sum = args.reduce((prev,cur)=>{
  //       return prev+cur;
  //     })
  //     return sum;
  //   }
  //   //返回inner内部函数实现基本的柯里化
  //   return inner
  // }
  //
  // console.log(add(1)(2));

  function add() {
    // 将传入的不定参数转为数组对象
    let args = Array.prototype.slice.call(arguments);

    // 递归:内部函数里面进行自己调用自己
    // 当 add 函数不断调用时,把第 N+1 个括号的参数加入到第 N 个括号的参数里面
    let inner = function() {
      args.push(...arguments);
      return inner;
    }

    inner.toString = function() {
      // args 里的值不断累加
      return args.reduce(function(prev, cur) {
        return prev + cur;
      });
    };

    return inner;
  }

  // 测试一下
  let result = add(1)(2)(3)(4);
  console.log(result.toString());
  //结果为:10

17.虚拟DOM

17.1 什么是虚拟DOM?

虚拟DOM就是一个普通的js对象,用于描述视图的界面结构。
在vue中,每个组件都有一个render函数,每个render函数都会返回一个虚拟DOM树,这也就意味着每个组件都对应一棵虚拟DOM树

17.2 为什么需要虚拟DOM?

在渲染时,直接使用真实DOM,因为真实DOM的创建,更新,插入等操作会带来大量的性能损耗,降低渲染效率。所以需要减少对真实DOM的操作

17.3 虚拟DOM是如何转换为真实DOM的?

在一个组件实例首次被渲染时,它先生成虚拟DOM树,然后根据虚拟DOM树创建真实DOM,并把真实DOM(挂载)到页面中适合的位置,此时,每个虚拟DOM便会对应一个真实的DOM

17.4 模板和虚拟dom的关系?

vue框架中有一个compile模块,它主要负责将模版转换为render函数,而render函数调用后得到虚拟DOM。

18.require和import的区别

require/exports

//module.js文件导出
module.exports = {counts, sayHello};

//module.js文件引入
const { xxx } = require('./module.js');

import/exports

//module.js文件导出
exports = {counts, sayHello};

//module.js文件引入
import { xxx } from'./module.js';
  1. import: 是编译时执行,理解为异步加载
  2. require: 是运行时执行,理解为同步加载
  3. 导入require 导出 exports/module.exports 是 CommonJS 的标准,通常适用范围如 Node.js
  4. import/export 是 ES6 的标准,通常适用范围如 React,Vue
  5. require性能比import稍低
    因为 require 是在运行时才引入模块并且还赋值给某个变量,而 import 只需要依据 import 中的接口在编译时引入指定模块所以性能稍高

19.计算属性和methods方法的区别

计算属性 只有当数值更改后才能被触发。如果依赖的值,没有发生改变,使用的就是缓存中的属性

methods方法 无论什么时候,只要你触发了方法,数值都会被重新计算。不存在缓存机制。

20.性能优化

1.1  while循环快还是for循环快?   关于循环
1.2  0是不是比Math.floor性能好?  关于取值
1.3  if else与三元运算符哪个快?   关于逻辑运算
以上都不算不上性能优化,都是执行效率

20.1 输入url与浏览器渲染过程
在这里插入图片描述
20.2 什么是性能?什么是执行效率
操作虚拟dom就是性能问题
vue是数据驱动 => 虚拟dom 操作dom(影响到浏览器速度)

20.3 性能分析
页面加载性能(加载时间,用户体验)
动画与操作性能(是否流畅无卡顿)
内存占用(占用过大,浏览器崩掉等)
电量消耗(游戏方面,可不考虑)

20.4 性能优化有哪些?
a.加载
1.减少http请求 css和图片都能做的事,最好用css,因为图片也是一个请求
2.缩小文件大小(资源压缩)
3.cdn库
4.懒加载:用到什么加载什么。因为加载的东西少,耗时就少了。
5.服务端渲染,预渲染:省掉部分获取数据的接口请求
6.代码分割:并行加载且最大化利用浏览器缓存

b.动画与操作性能
1.减少dom操作 => 文档碎片
2. 避免回流

21.TCP协议三次握手和四次挥手

面试题视频链接
https://www.bilibili.com/video/BV1iE411q7Qd?spm_id_from=333.337.search-card.all.click&vd_source=65e0538de0332111f890a0bd755ca4e7
前端面试题:
https://juejin.cn/post/7049164339630047245

TCP和UDP的区别

22.防抖和节流的应用场景

防抖
防抖,顾名思义,防止抖动。用于将用户的操作行为触发转换为程序行为触发,防止用户操作的结果抖动。一段时间内,事件在我们规定的间隔 n 秒内多次执行,回调只会执行一次。

特点:等待某种操作停止后,加以间隔进行操作

1.持续触发不执行
2.不触发的一段时间之后再执行

节流
节流,顾名思义,控制流量。用于用户在与页面交互时控制事件发生的频率,一般场景是单位的时间或其它间隔内定时执行操作。一段时间内,事件在每次到达我们规定的间隔 n 秒时触发一次。

特点:每等待某种间隔后,进行操作

1.持续触发并不会执行多次
2.到一定时间 / 其它间隔 ( 如滑动的高度 )再去执行

作者:政采云前端团队
链接:https://juejin.cn/post/7018296556323340324

23.Typescript中的extends关键字理解

1.继承/拓展
2.泛型约束
3.条件类型与高阶类型
https://blog.csdn.net/qq_34998786/article/details/120300361

24.跨域是怎么引起?

跨域就是同源策略引起

同源策略: 同端口 同域名 同协议(如果这三个里有一个不同,就叫不同源)
跨域: 违反同源策略

常见的跨域方式有哪些?

  1. jsonp
    html中的script src属性获取其他源的数据

  2. .cors 跨域资源共享 支持所有的主流浏览器
    XMLHttpRequest 发送请求的时候,如果不同源
    后台处理: 请求头部设置 Access-control-allow-origin

  3. h5 window.postMessage跨域
    window.postMessage(“字符串”,“*”)

注意:vue的跨域: proxy代理跨域(本质上就是cors跨域)
vue.config.js里进行配置

25.AMD与CMD区别

https://juejin.cn/post/6844903541853650951#heading-2

26.资源提示符

资源提示符跟浏览器渲染密切相关

  1. async //异步加载
  2. defer //延迟加载
  3. preload //加载优先级大于prefetch
  4. prefetch //加载优先级较低,浏览器空闲时才加载
    preload,prefetch加载的资源重复时,浏览器不会进行重复请求

27.脚本加载失败该怎么办?

1.什么时候重试?
使用window.addEventListener捕获脚本报错的时候重试
2.如何重试?
使用document.write阻塞浏览器进行重试

<!DOCTYPE html>
<html lang="en">
<head>
    <script>
        //需要替换的域名
        const domains = [
            "unpkg.com",
            "www.bootcdn.cn",
            "www.staticfile.org",
            "cdn.baomitu.com",
            "cdn.bytedance.com",
        ]
        //重试次数
        const maxRetry = 3;
        const retryInfo = {}
        window.addEventListener('error',(e)=>{
            //通过标签,判断是脚本爆出的错误
            const tag = e.target
            //什么时候触发脚本加载失败?
            if(tag.tagName === "SCRIPT" && !(e instanceof ErrorEvent)){
                let url = new URL(tag.src)
                if(!retryInfo[url.pathname]){
                    retryInfo[url.pathname]={
                        time:0,
                        nextIndex:0,
                    }
                }
                const info = retryInfo[url.pathname]
                if(maxRetry>=info.time){
                    url.host = domains[info.nextIndex]
                    //阻塞页面后续的加载
                    document.write(`<script src="${url.toString()}">\<\/script>`)

                    info.time++;
                    info.nextIndex = (info.nextIndex+1)%domains.length
                }
            }
        },true)
    </script>
</head>
<body>
<script src="https://333.com/vue"></script>
<script src="https://4444.com/pinia"></script>
</body>
</html>

28.计算属性(computed)和监听器(watch)的区别

  1. 计算属性的应用场景是计算的内容需要依赖多个属性的情况
    侦听器的应用场景是计算的内容依赖一个属性的情况
  2. 计算属性缓存结果时每次都会重新创建变量
    而侦听器是直接计算,不会创建变量保存结果
  3. computed的结果是通过return返回的,而watch不需要return
  4. watch中的参数可以得到侦听属性改变的最新结果,而computed函数没有这种参数。

29.typescript类型有多少种

基本类型
number string boolean symbol null undefined bigint

引用类型
object array tuple(元组) function

特殊类型
any void unknow never enum(枚举)

30.外包线上面试前端

vue

  1. v-model实现原理

  2. MVVM简要
    https://zhuanlan.zhihu.com/p/59467370

  3. 父子组件通信方式有哪些?vue的通信有哪些?(说出三个)

  4. 父子组件生命周期执行顺序

  5. computed和watched的使用场景和区别

  6. 模板数据不同步,该如何同步?

  7. vue2和vue3使用什么实现双向绑定?实现原理是什么?

  8. keep-alive使用场景有哪些?

  9. 虚拟dom是干什么的?什么是虚拟dom?
    9.1 虚拟dom是js和dom之间的映射缓存,一个普通的obj对象,用于描述视图的界面结构。每个render都会返回自己的一个虚拟dom树
    9.2 虚拟dom作用是提高渲染效率
    https://blog.csdn.net/weixin_44231864/article/details/115264217

  10. vue中data某一个属性值发生改变后,视图会立即同步执行,并重新渲染吗?
    不会,因为vue内部有优化机制,异步渲染。使用nexTick函数(dom更新循环结束之后延迟执行回调)

  11. vue内部有哪些优化机制?

  12. mixins和extends的区别

  13. vite和webpack的区别,rollup是什么?
    ⭐构建速度
    Webpack: Webpack的构建速度相对较慢,尤其在大型项目中,因为它需要分析整个依赖图,进行多次文件扫描和转译。
    Vite: Vite以开发模式下的极速构建著称。它利用ES模块的特性,只构建正在编辑的文件,而不是整个项目。这使得它在开发环境下几乎是即时的。
    ⭐配置复杂度
    Webpack: Webpack的配置相对复杂,特别是在处理不同类型的资源和加载器时。
    Vite: Vite鼓励零配置,使得项目起步非常简单,但同时也支持自定义配置,使其适用于复杂项目。
    ⭐编译方式
    Webpack: Webpack使用了多种加载器和插件来处理不同类型的资源,如JavaScript、CSS、图片等。
    Vite: Vite利用ES模块原生支持,使用原生浏览器导入来处理模块,不需要大规模的编译和打包。
    ⭐应用场景
    Webpack: 适用于复杂的大型项目,特别是需要大量自定义配置和复杂构建管道的项目。
    Vite: 更适用于小到中型项目,或者需要快速开发原型和小型应用的场景。
    ⭐打包原理
    Webpack: Webpack的打包原理是将所有资源打包成一个或多个bundle文件,通常是一个JavaScript文件。
    Vite: Vite的打包原理是保持开发时的模块化结构,使用浏览器原生的导入机制,在生产环境中进行代码分割和优化

  14. ref和reactive的区别
    ⭐ref处理基础类型,通过普通的get,set劫持
    ⭐reactive处理引用类型,针对对象,用的是proxy代理,极好的支持对象监听。(处理了vue2中object.definePorperty的痛点)

css

  1. em rem px rpx的区别和移动端适配问题

  2. css选择器优先级

  3. 什么是盒子模型?它有哪些元素?有几种模式?

  4. display: none与visibility: hidden的区别

  5. 使用box-sizing设置的属性(border-size,content-size),说出当前div的宽度

  6. 什么是重排和重绘?

  7. height和line-height的区别?

height:一个死值,就是这个盒子的高度
line-height:是每一行文字的高度,如果文字换行,则整个盒子高度会增大(行数*高度)

javascript

  1. 多个对象合并 多个数组合并方式有哪些,说出es5和es6

  2. JavaScript 数据类型和数据结构
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures

  3. sessionStorage,localstorage,cookie的区别
    在这里插入图片描述

  4. 防抖和节流的区别和概念

  5. get和post的区别

  6. 什么是作用域?

  7. 闭包有哪些应用场景?

  8. 防抖和节流的区别有些哪些?
    防抖和节流的区别

  9. 浏览器输入url后执行的整个过程。
    1.浏览器根据请求的 URL 交给 DNS 域名解析,找到真实 IP ,向服务器发起请求
    2.服务器交给后台处理完成后返回数据,浏览器接收⽂件( HTML、JS、CSS 、图象等)
    3.浏览器对加载到的资源( HTML、JS、CSS 等)进⾏语法解析,建立相应的内部数据结构 (如 HTML 的 DOM);
    4.载⼊解析到的资源⽂件,渲染页面,完成。

  10. 什么情况会发生跨域?有哪些解决方案?

  11. html5有哪些新特性?

  12. es6有哪些?es5有哪些?

  13. 四种判断数据类型的方法有哪些?

  14. 关于TCP三次握手
    https://zhuanlan.zhihu.com/p/425162304

  15. http和https的区别和优缺点,概念

typescript

  1. typeof与keyof的区别
  2. interface与type的区别
  3. typescript的高级用法

其他

  1. websocket和socket的区别
  2. 使用Vue时,有哪些优化的方案?
    2.1 vue渲染优化:异步加载,服务端渲染,浏览器缓存等技术优化网页渲染性能
    2.2 vm中间件优化:简化vm中间件和优化代码
    2.3 通过代码重构,使用cdn加速

我的知识盲区

1.js中,什么是类型化数组(es6)?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沉默小管

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值