前端面试题

vue

vue的优点

 1、简单易学,国内使用者多,文献多
 2、学习了angular的双向绑定,react的组件化。
 3、虚拟DOM(下边有描述)
 4、运行速度更快:相比较react而言,操作虚拟DOM,在性能上vue存在很大的优势
 5、让程序员把更多精力放在逻辑处理上

v-model

简单描述: v-model是vue中的双向绑定的指令,能将页面上控件输入的值同步更新到绑定的相关data属性中去,也会在更新data绑定属性的时候,更新到页面输入(输出)控件的值。全写v-model:value="XXX" 简写 v-model="XXX"。一般应用于表单输入框(input,select,textarea)

 1.v-model 跟 v-bind 的区别在于,v-bind是单项绑定,v-model是双向绑定。

 2.v-model通过视图层更新data的原理,可以理解为在input框里面通过v-bind动态绑定一个value,然后在input框里面通过@input(v-on:input)事件输入的值,然后重新给变量赋值就可以了。

虚拟DOM

具体点击这里 (参考文献)
简单描述: 首次渲染会调用一次 patch 并创建新的vnode,不会进行更深层次的比较,然后是在组件中数据发生变化时,会触发 setter 通过 Notify 通知 watcher, 对应的watcher会通知更新并执行更新函数,它会执行 render 函数获取新的虚拟 DOM,然后执行 patch 对比上次渲染结果的老的虚拟DOM,并计算出最小的变化,再根据这个最小的变化去更新真是DOM。
1、Diff 算法
 (1) 只比较同一层级,不跨级比较
 (2)  比较标签名:如果同一层级的比较标签名不同,就直接移除老的虚拟 DOM 对应的节点,不继续按这个树状结构做深度比较,简化比较次数。
(3) 比较key,如果标签名相同,key 也相同,就会认为是相同节点,也不继续按这个树状结构做深度比较,比如我们写 v-for 的时候会比较 key,不写 key 就会报错,这也就是因为 Diff 算法需要比较 key。
  key的作用主要是为了更高效的更新虚拟DOM,因为它可以非常精确的找到相同的节点,因此 patch 过程会非常高效。
  Vue 在 patch 过程中会判断两个节点是不是相同节点时,key 是一个必要条件。比如渲染列表时,如果不写 key,Vue 在比较的时候,就可能会导致频繁更新元素,使整个 patch 过程比较低效,影响性能。
  应该避免使用数组下标作为 key,因为 key 值不是唯一的话可能会导致上面图中表示的 bug,使 Vue 无法区分它他,还有比如在使用相同标签元素过渡切换的时候,就会导致只替换其内部属性而不会触发过渡效果。
  从源码里可以知道,Vue 判断两个节点是否相同时主要判断两者的元素类型和 key 等,如果不设置 key,就可能永远认为这两个是相同节点,只能去做更新操作,就造成大量不必要的 DOM 更新操作,明显是不可取的。

路由守卫

面试简洁回答:三种路由守卫,分别是全局前置守卫、路由独享守卫、组件内守卫。
 共有三种路由守卫,分别是:
   1、全局前置守卫:使用router.beforeEach()方法,用于在路由跳转之前进行拦截和权限校验等操作。
   2、路由独享守卫:在定义时通过beforEnter属性来注册,只对当前路由生效,用于实现特定路由的权限控制。
   3、组件内守卫:在组件通过beforRouterEnter、beforRouteUpdate、beforRouteLeave等属性注册,用于在组件内部控制路由跳转,例如在组件内部进行异步数据加载等操作。

data为什么return

 是为了达成组件与组件之间的数据私有化

v-if 与 v-show 的区别

 v-if 根据判断的条件渲染一块内容,如果不成立就不会渲染到页面上。
 v-show 不管条件是否成立,都会渲染到页面上,只不过是用了display:none隐藏了。

单项 数据流 props 页面刷新 数据丢失 怎么处理

 单项数据流是指父组件通过props向子组件传递数据,子组件只能通过事件向父组件传递数据,这样能够保证组件之间的数据流向清晰明确。

怎么处理数据丢失呢:
 1、将数据传保存到接口里
 2、保存在本地
 3、使用路由参数 可以在路由中定义参数,将需要保留的数据作为参数传递给下一个页面。
 4、vuex持久化
 5、params传参,在路由路径中配置占位符

错误回答:
存放在vuex里,在 Vue 应用中,刷新页面会导致 Vuex 中的数据丢失。当页面刷新时,Vuex 的状态会被重置,所有之前存储的数据都会丢失。

vue跳转传参的区别

路由参数和 props 属性
 1、传参方式不同:路由参数是通过 URL 上的参数传递的,而 props 属性是通过组件之间的属性传递的。
 2、传参类型不同:路由参数只能传递字符串类型的参数,而 props 属性可以传递任意类型的参数。
 3、使用场景不同:路由参数适用于传递简单的参数,如 ID、页面类型等,而 props 属性适用于传递复杂的数据结构,如对象、数组等。
 4、组件耦合度不同:路由参数传递的参数可以在任意组件中获取,而 props 属性传递的参数只能在父组件和子组件之间传递,增加了组件之间的耦合度。
 5、安全性不同:路由参数传递的参数可以被用户轻易地修改,而 props 属性传递的参数只能被组件内部的逻辑所修改,安全性更高。

路由参数又分:
 query传参:
  1.可以使用name ,path , 字符串拼接方式传参
  2.每次刷新不会丢失数据
  3.不能使用props接收数据
 params传参:
  1.路由中不写占位符,只能使用name 传参
  2.不使用占位符,刷新会丢失数据,使用占位符则不丢失数据 所以需要在规则中配置属性名
  3.可以使用props接收数据
provide与inject传参:
优点:孙子组件可以接收,主打的就是一个方便。
缺点:不好维护,官网都说了,怕你 “ 把握不住 ”。

监听子组件

 1、v-on,$emit
 2、ref

template在vue里是什么?为什么用它?会编译成什么标签?

面试简洁回答:1、字符串模板。2、定义组件的结构和行为,用于形成最终的HTML。易于维护,同时实现组件动态化。3、不会被渲染成任何实际HTML标签。
 在Vue中,template标签用于定义组件的结构和行为,Vue会将template中的代码编译成可运行的JavaScript渲染函数,用于生成最终的HTML。使用template可以将组件的代码更加清晰和易于维护,同时实现组件的动态化。在编译时,template会被编译成一个render函数,该函数返回一个虚拟DOM节点,然后将该节点渲染到页面上,因此在运行时,template标签最终不会被渲染成任何实际的HTML标签。

VUEX

Vuex包含了以下几个部分:
  state:用于存储应用中需要共享的状态,即定义数据的地方。
  getters:类似于计算属性,用于从 store 中获取 state 中的派生状态,即对数据的一些操作。
  mutations:用于修改 state 中的状态,但是只能进行同步操作。
  actions:用于处理异步操作,最终还是需要通过提交 mutation 来改变 state 中的状态。
  modules:将 store 分割成多个模块,每个模块都有自己的 state、mutation、action、getter,方便进行代码的管理和维护。

vue传参有几种

在Vue中,组件之间传参的方式有以下几种:
 props:父组件向子组件传递数据。在父组件中通过props属性声明需要传递的数据,然后在子组件中通过props选项接收数据。
 $emit:子组件向父组件传递数据。在子组件中通过$emit方法触发自定义事件,并传递需要传递的数据,然后在父组件中通过v-on监听该事件,接收子组件传递的数据。
  $attrs/$listeners:在父组件中向子组件传递所有的属性和事件。在父组件中通过v-bind=“$attrs"和v-on=”$listeners"将所有属性和事件传递给子组件,然后在子组件中通过inheritAttrs选项和$attrs/$listeners来访问这些属性和事件。
 provide/inject:在父组件中向子孙组件传递数据。在父组件中通过provide提供需要共享的数据或方法,然后在子组件中通过inject注入需要的数据或方法,从而实现跨层级传递数据。
 Vuex:在组件之间共享状态。通过Vuex中的state、getters、mutations和actions等实现组件之间的数据共享。

$nextTick

 在Vue中,$nextTick是一个用于在下次 DOM 更新循环结束之后执行延迟回调的方法。它的作用是在当前数据变化已经完成,并且对应的DOM已经重新渲染之后,再执行回调函数。

JavaScript

变量名区别
var有变量提升,可重复声明 ,有初始提升
let有变量提升,没有初始化提升,值可变,存在暂时性死区所以有变量提升,但是没有提升
const有变量提升,没有初始化提升,值不可变,但如果是定义对象,则属性可变 ,存在暂时性死区

总结:三种声明变量 都是拥有变量提升的 只不过是 let 跟 const 存在暂时性死区 所以表面上没有变量提升,理论上拥有变量提升的

JS类型

 基本类型:number string boolean undefined null symbol bigInt
 引用类型:Object Array Function 等

为什么会有变量提升

简答:因为js的“预编译”所以导致变量提升,js在解析代码时会先对整个作用域进行扫描和解析,找出其中的变量声明和函数声明,并将它们提前到作用域的顶部。所以在声明前调用不会报错。
 变量提升是JavaScript中的一种特性,指的是在代码执行之前,变量的声明部分会被提前到作用域的顶部。
 变量提升的原因是因为JavaScript的解释器在解析代码时,会先对整个作用域进行扫描和解析,找出其中的变量声明和函数声明,并将它们提前到作用域的顶部,这个过程被称为“预编译”

三种缓存方法
 简单描述:session,local,cookie,三种存储方法,session是临时存储只要浏览器不关闭就不会丢失,local是永久存储除非手动删除,否则不会丢失。两种Storage只能存储字符串。Cookie存在跨域,浪费带宽,存储量小(最大4kb)。

1.sessionStorage:临时的会话存储
  只要当前的会话未关闭,存储信息就不会丢失,即便页面刷新或在编辑器中更改了代码,存储的会话信息也不会丢失。反则只要页面关闭了存储的信息都会消失。一般用来放一些临时的数据。

2.localStorage:永久存储
  会一直将数据存储在客户端的存储方式,即使关闭了浏览器,下次打开的时候仍然可以看到之前存储的未主动清除的数据(即便是杀毒软件或者是浏览器自带的清除功能,也不能将localStorage存储的数据清除掉)。题外话:uni-app里存储就是使用的local存储方法。

  两种Storage存储方法只能存储字符串数据,对于JS中常用的数组或对象却不能直接存储,它能保存更大的数据(IE8上是10MB,Chrome是5MB),同时保存的数据不会再发送给服务器,避免带宽浪费

3.Cookie
  缺点比较明显: 跨域问题,无法保存太大数据(最大4KB),保存的数据会发送给服务器,不管服务器是否需要,每一次HTTP请求都会携带存储的数据传输到服务器端,非常浪费带宽。

闭包

 闭包的定义:闭包是指有权访问另一个函数作用域中的变量的函数。——《JavaScript高级程序设计》
 我的理解是:暴漏一个能访问(或修改)内部变量的函数,这都属于闭包。

this指向

 普通函数:关于this,谁调用就指向谁,没有调用者,就指向全局对象window。
 箭头函数:箭头函数的this指向于函数作用域所用的对象。

apply()、call()、bind() 区别

 1、共同点 : 都是用来改变 this 指向的

 2、区别:
  (1)call 、apply 可以立即执行;
bind 不会立即执行,因为bind返回的是一个函数,执行的时候需要在后边加上();
  (2)call和bind有多个参数 逗号分隔 就可以了,apply 有多个参数的时候需要传入一个数组进行传参

let callStr = "这是拉拉";
 
let callObj = {
	callStr: "这是obj对象的str"
};
 
function callFun(name, age) {
    this.name = name;
    this.age = age;
    console.log(this, this.callStr);
}
 
callFun.call(callObj);
callFun.apply(callObj);
callFun.bind(callObj)();
// 以上三条都输出: {callStr: "这是obj对象的str", name: undefined, age: undefined} "这是obj对象的str"

callFun.call(callObj, "李四", "22");
callFun.apply(callObj, ["李四", "22"]);
callFun.bind(callObj, "李四", "22")();
// 以上三条都输出 {callStr: "这是obj对象的str", name: "张三", age: 23} "这是obj对象的str"

函数声明和函数表达式有什么区别
// 函数声明 
let add = sum(1,2)
function sum(num1,num2){
	return num1 + num2;
}
//函数表达式 (匿名函数)
let add = function (num1,num2){
	return num1 + num2;
}
console.log( add(1,2) )

// 函数声明 是有提升的,调用的时候可以在声明函数之前使用。
// 匿名函数 没有提升,须在声明(赋值)之后调用。

浅拷贝 深拷贝

 浅拷贝:共同一个内存,新旧一个改变都改变。
 深拷贝:复制一个一模一样的对象,不共享内存,新旧改变不关联。

原型链

具体看这里 (参考文献)看完原型链和es6中的class概念也就明白了
 原型与原型层层相链接的过程即为原型链。

防抖与节流

 防抖:是把多次执行变为最后一次执行
 节流:是将多次执行变成每隔一段时间执行

回流(重排) 重绘

 个人理解:
  1.回流(重排):涉及到尺寸大小导致页面需要从新排版。
  2.重绘:不涉及到兄弟(父级)排版问题,只是单纯改变字体颜色背景颜色一类或类似操作或小型操作。

TCP三次握手四次挥手

全网最简洁易懂 三次握手 四次挥手 解析
 TCP三次握手是建立TCP连接时,客户端向服务器发送SYN,服务器向客户端回复SYN+ACK,客户端再回复ACK,连接建立。四次挥手是终止TCP连接时,客户端向服务器发送FIN,服务器回复ACK,然后服务器向客户端发送FIN,客户端回复 ACK,连接终止。
 SYN:表示同步,用于在TCP连接建立是,客户端向服务器端发送一个SYN标志的信息,表示要建立连接。
 ACK:表示确认,用于在TCP连接建立和终止时,双方进行确认,确保信息的可靠传输。
 FIN:表示结束,用于在TCP连接终止时,客户端或服务器端向对方发送FIN标志的信息,表示要关闭连接。

判断数据类型

typeof // console.log( typeOf ‘123456’ )
instanceof // console.log( ‘123456’ instanceof String )

// typeOf 会直接返回变量类型
// instanceof 是比对 是否是 某某某 类型



HTML

盒子模型

 1、w3c:宽高 只算内容的宽高
 2、IE怪异模型:宽高算上了 border(边框) + padding(内边距) + 内容宽(高)
扩展:
 当设置为box-sizing:content-box时,将采用标准模式解析计算,也是默认模式。
 当设置为box-sizing:border-box时,将采用怪异模式解析计算,这时padding将不会向内压缩内容。

前端优化代码

 可以采用第三方 CDN加速

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值