百度前端一面

前言

本次主要记录一下神州信息(2023.3.7)、百度前端一面 (2023.3.22中午11点)、联通数科(3.24下午1点半)

问题总结

vue computed和watch的区别?(神州信息)

1. 计算属性 computed

特点:

  • 支持缓存,只有依赖数据发生改变,才会重新进行计算;
  • 不支持异步,当 computed 内有异步操作时无效,无法监听数据的变化;
  • computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的。也就是基于 data 中声明过或者父组件传递的 props 中的数据通过计算得到的值;
  • 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性 是一个多对一或者一对一,一般用computed;
  • 如果 computed 属性值是函数,那么默认会走 get 方法,函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个 set 方法,当数据变化时,调用 set 方法;
2. 侦听属性 watch

特点:

  • 不支持缓存,数据变化,直接会触发相应的操作;
  • watch 支持异步操作;
  • 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
  • 当一个属性发生变化时,需要执行对应的操作,一对多;
  • 监听数据必须是 data 中声明过或者父组件传递过来的 props 中的数据。当数据变化时触发其他操作,函数有两个参数:
    immediate:组件加载立即触发回调函数执行;
    deep: 深度监听;为了发现对象内部值的变化,复杂类型的数据时使用,例如:数组中的对象内容的改变,注意:监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到;

注:当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的,这是和 computed 最大的区别。

详细请看Vue中 computed 和 watch 区别及应用场景详解

vue-router路由模式的区别和原理?

hash模式:

  1. url路径会出现“#”号字符
  2. hash值不包括在Http请求中,它是交由前端路由处理,所以改变hash值时不会刷新页面,也不会向服务器发送请求,所以这也是单页面应用的必备。
  3. hash值的改变会触发hashchange事件
  4. 当我们进行刷新操作,或者直接输入浏览器地址时,hash路由会加载到地址栏对应的页面,而history路由一般就404报错了(刷新是网络请求,没有后端准备时会报错)。

history模式:

  1. history运用了浏览器的历史记录栈,之前有back,forward,go方法,之后在HTML5中新增了pushState()和replaceState()方法,它们提供了对历史记录进行修改的功能,不过在进行修改时,虽然改变了当前的URL,但是浏览器不会马上向后端发送请求。
  2. history的这种模式需要后台配置支持。比如:当我们进行项目的主页的时候,一切正常,可以访问,但是当我们刷新页面或者直接访问路径的时候就会返回404,那是因为在history模式下,只是动态的通过js操作window.history来改变浏览器地址栏里的路径,并没有发起http请求,但是当我直接在浏览器里输入这个地址的时候,就一定要对服务器发起http请求,但是这个目标在服务器上又不存在,所以会返回404

原理:
HashRouter的原理:
通过window.onhashchange方法获取新URL中hash值,再做进一步处理

HistoryRouter的原理:
通过history.pushState 使用它做页面跳转不会触发页面刷新,使用window.onpopstate 监听浏览器的前进和后退,再做其他处理

vue-router常见的面试题

js中promise?

兴业数金之promise

Pending(进行中,初始状态,既不是成功,也不是失败状态。)、Resolved(已完成,又称 Fulfilled)、Rejected(已失败)
这三种状态的变化途径只有2种:异步操作从 未完成 pending => 已完成 resolved异步操作从 未完成 pending => 失败 rejected状态一旦改变,就无法再次改变状态,这也是它名字 promise-承诺 的由来,一个promise对象只能改变一次

什么是Promise,Promise的三种状态

js中this 的指向?

  1. 全局对象中的this指向指向的是window
  2. 全局作用域或者普通函数中的this指向全局window
  3. 在不是箭头函数的情况下,this水远指向最后调用它的那个对象
  4. new关键词改变了this的指向
  5. apply,call,bind可以改变this指向,不是箭头函数
  6. 箭头函数中的this,它的指向在定义的时候就已经确定了
    箭头函数它没有this,看外层是否有函数,有就是外层函数的this,没有就是window
  7. 匿名函数中的this永远指向了window.匿名函数的执行环境具有全局性,因此this指向window

js中原型和原型链?

原型:每个函数都有prototype属性,称之为原型。因为这个属性的值是个毒性,也称之为原型对象
作用:存放一些属性和方法;在JS中实现继承
原型链:每个对象都有一个_ proto_ ,它指向它的prototype原型对象; 它的prototype原型对象又有一个_proto_,指向它的prototype原型对象,就这样层层向上直到最终找到顶级对象Object的prototype,这个查询路径就是原型链。

动态加载JS脚本的方法?(我的百度一面)

动态加载JS脚本有4种方法

vue的图片懒加载?

懒加载就是延时加载(也称为按需加载)。

具体表现为:当我们访问页面时,先将img图片的路径替换成一张占位图的路径,这样就只需请求一次,而当图片进入可视区域时才把其图片的路径替换为真正的路径,从而显示图片,达到懒加载的效果。(即:懒加载就是使用同一张占位图进行占位,然后按需获取图片真正的路径,从而实现懒加载)

技术原理是:先将img的src属性隐藏,而将其真正的地址存放在img标签自定义的属性中(eg:data-src),当图片进入可视区域时,将真正的路径从data-src中取出替换回来,从而显示图片。

优点:页面加载速度快,减轻服务器端的压力,节约流量

路由的懒加载

路由懒加载:当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效。
eg:

const UserDetails = () => import('./views/UserDetails')

懒加载(按需加载)原理分两步:

  • 将需要进行懒加载的子模块打包成独立的文件(children chunk)
  • 借助函数来实现延迟执行子模块的加载代码
    详解路由懒加载

vue中的单向数据流?

  • 在vue中需要遵循单向数据流原则
    在父传子的前提下,父组件的数据发生会通知子组件自动更新
    子组件内部,不能直接修改父组件传递过来的props => props是只读的

单向数据流在Vue中实际表现就是:当Model中的data 发生变化的时候会单向修改View中的值,而View中的值发生变化的时候,Model不会感知。 实际应用就是v-bind 单向数据。
和单向数据流相比,双向数据绑定就是多了View 变化会通知到Model层。 即MVVM的具体实现。无论Model 还是View 中的值发生变化,都会通过ViewModel通知到对方,实现同步。实际应用就是v-model双向数据绑定。

单向绑定的优点是相应的可以带来单向数据流,这样做的好处是所有状态变化都可以被记录、跟踪,状态变化通过手动调用通知,源头易追溯,没有“暗箱操作”。同时组件数据只有唯一的入口和出口,使得程序更直观更容易理解,有利于应用的可维护性。缺点则是代码量会相应的上升,数据的流转过程变长,从而出现很多类似的样板代码。同时由于对应用状态独立管理的严格要求(单一的全局store),在处理局部状态较多的场景时(如用户输入交互较多的"富表单型”应用),会显得哕嗦及繁琐。

基本上双向绑定的优缺点就是单向绑定的镜像了。优点是在麦单交万较多的场景下,会简化大量业务无关的代码。缺点就是由于都是“暗箱操作”,我们无法追踪局即状态的变化(虽然大部分情况下我们并不关心:潜在的行为大多也增加了出错时debug的难度。同时由于组件数据变化来源入口变得可能不止一个,新手玩家很容易将数据流转方向弄得紊乱,如果再缺乏一些"管制"手段,最后就很容易因为一处错误操作造成应用雪崩。

Vuex解决了什么问题?

1.我们在使用Vue开发项目中,经常会有通过路由传递参数时,由于参数过多会出现会导致400 Bad Request,vuex可以解决这个问题。
2.解决多个组件共享状态时,单向数据流的简洁性很容易被破坏的问题
3.解决多个视图依赖同一状态的问题
4.解决了在中大型项目中,数据太多时,只需要在vuex更改处理数据,不用去每个页面更改

Vuex的原理?

每一个 Vuex 应用的核心就是 store,里面又包括:
(1)state(数据):用来存放数据源,就是公共状态;
(2)getters(数据加工):有的时候需要对数据源进行加工,返回需要的数据;
(3)actions(事件):要执行的操作,可以进行同步或者异步事件
(4)mutations(执行):操作结束之后,actions通过commit更新state数据源(同步操作)
(5)modules:使用单一状态树,致使应用的全部状态集中到一个很大的对象,所以把每个模块的局部状态分装使每一个模块拥有本身的 state、mutation、action、getters、甚至是嵌套子模块;

vuex的工作流程就是:
(1)通过dispatch去提交一个actions,
(2) actions接收到这个事件之后,在actions中可以执行一些异步|同步操作,根据不同的情况去分发给不同的mutations,
(3)actions通过commit去触发mutations,
(4)mutations去更新state数据,state更新之后,就会通知vue进行渲染

webpack打包的基本原理?

webpack打包原理是根据文件间的依赖关系对其进行静态分析,将这些模块按指定规则生成静态资源,当 webpack处理程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,将所有这些模块打包成一个或多个bundle。

webpack的整个打包流程:

  1. 读取webpack的配置参数;
  2. 启动webpack,创建Compiler对象并开始解析项目;
  3. 从入口文件(entry)开始解析,并且找到其导入的依赖模块,递归遍历分析,形成依赖关系树;
  4. 对不同文件类型的依赖模块文件使用对应的Loader进行编译,最终转为Javascript文件;

浏览器的多进程和js的单线程?

浏览器(多进程)
浏览器是多进程的,拿Chrome来说,每打开一个Tab页就会产生一个进程,使用Chrome打开很多标签页不关,电脑会越来越卡,这是因为消耗了其CPU的缘故。

浏览器包含哪些进程:
Chorme浏览器从关闭到启动,然后新开一个页面至少需要:1个浏览器进程,1个GPU进程,1个网络进程,和1个渲染进程,一共4个进程。
后续如果再打开新的标签页:浏览器进程,GPU进程,网络进程是共享的,不会重新启动,然后默认情况下会为每一个标签页配置一个渲染进程,但是也有例外,比如从A页面里面打开一个新的页面B页面,而A页面和B页面又属于同一站点的话,A和B就共用一个渲染进程,其他情况就为B创建一个新的渲染进程
所以,最新的Chrome浏览器包括:1个浏览器主进程,1个GPU进程,1个网络进程,多个渲染进程,和多个插件进程

JS的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准,因此这是一个矛盾点,是JS的功能决定了它是单线程语言。

详情可以看JS(单线程)与浏览器(多进程)

JS中的作用域和作用域链

作用域:就是变量或者是函数能作用的范围。

  1. 全局作用域:任何不在函数中或是大括号中声明的变量,都是在全局作用域下,全局作用域下声明的变量可以在程序的任意位置访问。
  2. 函数作用域:函数作用域也叫局部作用域,如果一个变量是在函数内部声明的它就在一个函数作用域下面。这些变量只能在函数内部访问,不能在函数以外去访问。
  3. 块级作用域:ES6引入了let和const关键字,和var关键字不同,在大括号中使用let和const声明的变量存在于块级作用域中。在大括号之外不能访问这些变量。

作用域链:当查找变量的时候,会先从当前作用域的变量对象中查找,如果没有找到,就会从父级作用域(上层环境)的变量对象中查找,一直找到全局作用域的变量对象,也就是全局对象。这样由多个作用域的变量对象构成的链表就叫做作用域链。它由当前环境与上层环境的一系列变量对象组成,保证了当前执行环境对符合访问权限的变量和函数的有序访问。
理解Javascript的作用域和作用域链

用几种方式实行元素的水平垂直居中?(代码题目)

简答的发布订阅模式?(代码题目)

JS变量类型?(另一个同学的百度一面面经)

值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型

string ,number,boolean,undefined,null ,Symbol
引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型

通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
判断数据类型

介绍一下let 和const

用const声明的常量,能不能被修改?

箭头函数以及特性?

1、外形不同:箭头函数使用箭头定义,普通函数中没有。
2、箭头函数全都是匿名函数:普通函数可以有匿名函数,也可以有具名函数
3、箭头函数不能用于构造函数:普通函数可以用于构造函数,以此创建对象实例。
4、箭头函数中ths的指向不同:在普通函数中,ths总是指向调用它的对象,如果用作构造函数,它指向创建的对象实例。
5、箭头函数不具有arguments对象:每一个普通函数调用后都具有一个arguments对象,用来存储实际传递的参数。但
是箭头函数并没有此对象。
6、其他区别:箭头函数不具有prototype原型对象。箭头函数不具有super。箭头函数不具有new.target

undefined和null的区别?

undefined和null两种数据类型的区别

css隐藏元素的方法?

(1)dispaly:none 消失+重排+重绘+绑定事件不触发+无过渡;

(2)visibility:hidden 存在+不重排+重绘+绑定事件不触发+有过渡;

(3)opacity:0 存在+不重排+不一定重绘+触发自身绑定+有过渡;

(4)position:absolute 移除视线;

(5)z-index:负值 使用其他元素遮盖;

(6)transform:scale(0,0) 缩放元素为0 存在+绑定事件不触发。

JS事件循环机制?

事件循环机制

跨域?解决跨域的方案?

跨域问题
用vue进行开发,在本地起了一个项目,本地浏览的地址是localhost:8080,这是我们常见的一个地址,但是后端写的接口包括他的地址肯定不是在这个localhost:8080下,那这个时候其实就出现了跨域的情况,一般实际中处理跨域的手段就是借助那个webpack提供的那个webpack_dev-server,由它提供给我们target属性,我们再用这个target属性的时候,就可以把它转到我们的目标服务器上,这是处理跨越的手段,webpack之所以能够解决跨域,原因是本地写项目其实写在了localhost上,webpack就会在本地起一个本地服务器,也就是说这个服务器和我们前端localhost:8080是符合同源策略的,发请求发的是webpack的中间层这个代理服务器上,webpack的中间层提供的服务器和后端的服务器其实是不存在跨域问题的,由它去求求后端服务器,得到数据以后,再由中间层传给我们前端。

如何在webpack中配置跨域?

devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:8989', // target: 表示代理到的目标地址
        secure: false, // 如果是https接口,需要配置这个参数
        changeOrigin: true, // 如果接口跨域,需要进行这个参数配置
        ws: true,
        pathRewrite: {
          '^/api': '' // 自定义
        }
      },
    }
  } 

http304状态码的含义?

网络状态响应码用来表示网页服务器HTTP响应状态的3位数字代码。请求状态码如果1开头就是临时相应,2开头一般表示成功,3开头是重定向,4开头是客户端错误,5开头是服务器错误。平时常见的响应状态码包括:200(成功)、301(永久重定向)、302(临时重定向)、304(未修改)、400(错误请求)、401(未授权)、403(禁止)、404(未找到)、500(服务器内部错误)、503(服务不可用)

浏览器缓存的全过程:
浏览器第一次加载资源,服务器返回 200,浏览器从服务器下载资源文件,并缓存资源文件与 response header,以供下次加载时对比使用;
下一次加载资源时,由于强制缓存优先级较高,先比较当前时间与上一次返回 200 时的时间差,如果没有超过 cache-control 设置的 max-age,则没有过期,并命中强缓存,直接从本地读取资源。如果浏览器不支持HTTP1.1,则使用 expires 头判断是否过期;
如果资源已过期,则表明强制缓存没有被命中,则开始协商缓存,向服务器发送带有 If-None-Match和 If-Modified-Since 的请求;
服务器收到请求后,优先根据 Etag 的值判断被请求的文件有没有做修改,Etag 值一致则没有修改,命中协商缓存,返回 304;如果不一致则有改动,直接返回新的资源文件带上新的 Etag 值并返回 200;
如果服务器收到的请求没有 Etag 值,则将 If-Modified-Since 和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回 304;不一致则返回新的 last-modified 和文件并返回 200;

用户输入一个url之后,会发生什么?

1、浏览器的地址栏输入URL并按下回车
2、浏览器查找当前URL是否存在缓存,并比较缓存是否过期
3、DNS解析URL对应的IP
4、根据P建TC连接(三次握手)
5、HTTP发起请求
6、服务器处理请求,浏览器接HTTP响应
7、渲染页面,构建DOM树
8、关闭TCP连接(四次挥手)

用两个栈模拟一个队列?(代码题目)

ES6新增哪些特性?(联通数科)

前端 ES6 十个新特性总结

promise有哪三种状态?

项目中用到了什么路由?

全局路由守卫:只要路由发生了路由变化,守卫就能够监听到。

  • beforeEach :全局前置守卫,
  • beforeResolve: 全局解析守卫,确保在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被正确调用。
  • afterEach: 全局后置守卫,对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。

路由独享守卫:只负责一条路的守卫,beforeEnter;

组件路由守卫:只负责单个组件的守卫。

  • beforeRouteEnter (在渲染该组件的对应路由被验证前调用);
  • beforeRouteLeave (在导航离开渲染该组件的对应路由时调用);
  • beforeRouteUpdate(在当前路由改变,但是该组件被复用时调用)。
    应用场景:在在线商城项目中,每一步路由跳转都要判断用户是否登录,只有当用户登录后,才能够跳转到其他页面,如果用户没有跳转,就只能去login页面,这时候就要使用全局路由守卫。如果用户想去查看支付成功的页面,那么必须先去支付页面进行支付,而不能直接从首页跳转到支付成功的页面,这时就要用路由独享守卫。

输入一个url会发生什么?

js事件循环机制?

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

纵有千堆雪与长街

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值