前端基础面试题补充

5次阅读

共计 8198 个字符,预计需要花费 21 分钟才能阅读完成。

26、前端性能优化

 react || vue

* 路由懒加载

* vue 组件异步加载

 页面内容

1. 减少 HTTP 

    * 通过 webpack 合并 JS CSS 文件

    * 使用 CSS Sprite 合并图片

    * 使用 Base64 行内图片

    * 用 icon 替换图标

  2. 避免重定向

    * URL 末尾添加 / 例如 http://www.baidu.com/

  3. 缓存 Ajax 请求

    * 设置 Cache-Control (相对过期时间)

  4. 减少页面元素数量

 Javascript

  1. JS 代码尽量放在页面底部, 避免阻塞页面加载

  2. 使用外部的 CSS 可以缓存 CSS

  3. webpack 压缩 js 代码

 图片

  1. CSS Sprite 合并图片

  2. Webp 图片

  3. 不在 HTML 中缩放图片

  4. 非 webp 图片都要压缩后再使用

  5. 使用 Base64 内嵌图片

 CSS

  1. react vue 可以实现 css 样式按需加载, 减少每次加载 CSS 的大小

  2. 压缩 CSS

  3. 使用 CSS3 属性 例如动画使用 transform transiton animtion

 服务器

  1. 使用 CDN(内容分发网络 CDN 是一组分散在不同地理位置的 web 服务器)

  2. 添加 Cache-Control 缓存头

  3. 启用 Gzip 压缩 (图片不要 gzip 压缩)

  4. Ajax 尽可能使用 get 方法, post 方法会多一次请求

  5. 避免 <img src=”” /> 空图片标签

 移动端

  1. 保证所有组件都小于 25K

27、防抖、节流

防抖

在滚动事件中需要做个复杂计算或者实现⼀个按钮的防⼆次点击操作。可以通

过函数防抖动来实现

开始⼀个定时器,只要我定时器还在,不管你怎么点击都不会执⾏回调函数。⼀旦定时器

结束并设置为 null,就可以再次点击了

对于延时执⾏函数来说的实现:每次调⽤防抖动函数都会判断本次调⽤和之前的时间间

隔,如果⼩于需要的时间间隔,就会重新创建⼀个定时器,并且定时器的延时为设定时间

减去之前的时间间隔。⼀旦时间到了,就会执⾏相应的回调函数

节流

防抖动和节流本质是不⼀样的。防抖动是将多次执⾏变为最后⼀次执⾏,节流

是将多次执⾏变成每隔⼀段时间执⾏

28、bind apply call 区别

相同:

1、都是用来改变函数的 this 对象的指向的。

2、第一个参数都是 this 要指向的对象。

3、都可以利用后续参数传参。

区别:

bind 不会立即调用,其他两个会立即调用,apply 与 call 的区别是 apply 第二个参数是数组,但是在确定的参数下,还是最好用 call,call 的效果会更高,但是在函数的延展性上使用 apply 更好

29、如何解决跨域

浏览器的同源策略指 ” 协议 + 域名 + 端⼝ “ 三者相同

1、通过 jsonp 跨域

2、node.js 中间件代理跨域  webpack-dev-server

本地启用 node 服务器 -》node 访问后台接口地址 -》请求这个 node 服务器,拿到数据

3、后端在头部信息⾥⾯设置安全域名  Access-Control-Allow-Origin(CORS)

4、上线以后怎么解决跨域?

  nginx  配置方向代理 

30、怎么判断一个对象的类型

Object.prototype.toString.call(对象)

31、JS 原型、原型链

每个对象都会在其内部初始化⼀个属性,就是 prototype (原型),当我们访问⼀个对象的

属性时

如果这个对象内部不存在这个属性,那么他就会去 prototype ⾥找这个属性,这个

prototype ⼜会有⾃⼰的 prototype,于是就这样⼀直找下去,也就是我们平时所说的

原型链的概念

32、箭头函数 

(1)箭头函数的 this 是在定义的时候就固定不变了 

(2)箭头函数  没有自己的 this 

(3)箭头函数 不能当类 (构造器) 使用  不可以 new 

(4)箭头函数  没有 arguments 

33、深浅拷⻉

(1)浅拷⻉

Object.assign

或者展开运算符 … obj

(2)深拷⻉

一、可以通过 JSON.parse(JSON.stringify(object)) 来解决

JSON.parse(JSON.stringify(object)) 是有局限性的

     1、会忽略 undefined

     2、不能序列化函数

     3、不能解决循环引⽤的对象

二、普通递归函数

三、_.cloneDeep() 深拷贝

34、数组去重⽅法总结

1、利⽤ ES6 Set 去重(ES6 中最常⽤)

2、利⽤ for 嵌套 for,然后 splice 去重(ES5 中最常⽤)

3、利⽤ indexOf 去重

         新建⼀个空的结果数组,for 循环原数组,判断结果数组是否存在当前元

         素,如果有相同的值则跳过,不相同则 push 进数组

4、利⽤ sort()

         利⽤ sort() 排序⽅法,然后根据排序后的结果进⾏遍历及相邻元素⽐对

5、利⽤对象的属性不能相同的特点进⾏去重

6、利⽤ includes   

          includes 检测数组是否有某个值

7、利⽤ hasOwnProperty

          利⽤ hasOwnProperty 判断是否存在对象属性

8、利⽤ filter

当前元素,在原始数组中的第⼀个索引 == 当前索引值,否则返回当前元素

9、利⽤递归去重

10、利⽤ Map 数据结构去重

           创建⼀个空 Map 数据结构,遍历需要去重的数组,把数组的每⼀个元素作为

           key 存到 Map 中。由于 Map 中不会出现相同的 key 值,所以最终得到的就

           是去重后的结果

11、[…new Set(arr)]

           相对于第⼀种⽅法来说只是简化了代码

35、JS 中 isPrototypeOf 和 hasOwnProperty 的区别

1、isPrototypeOf

isPrototypeOf 是用来判断指定对象 object1 是否存在于另一个对象 object2 的原型链中,是则返回 true,否则返回 false。

2、hasOwnProperty

hasOwnProperty 判断一个对象是否有名称的属性或对象,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。

如果该属性或者方法是该 对象自身定义的而不是器原型链中定义的 则返回 true; 否则返回 false;

36、事件代理

1、事件代理(Event Delegation),⼜称之为事件委托。是 JavaScript 中常⽤绑定事

件的常⽤技巧

2、“事件代理”即是把原本需要绑定的事件委托给⽗元素,让⽗元素担当事件监听的职务。事件代理的原理是 DOM 元素的事件冒泡。使⽤事件代理的好处是可以提⾼性能,⼤量节省内存占⽤,减少事件注册

37、浏览器缓存

浏览器缓存分为强缓存和协商缓存

1、先根据这个资源的⼀些 http header 判断它是否命中强缓存,如果命中,则直接从本地

获取缓存资源,不会发请求到服务器;

2、当强缓存没有命中时,客户端会发送请求到服务器,服务器通过另⼀些 request header

验证这个资源是否命中协商缓存,称为 http 再验证,如果命中,服务器将请求返回,但

不返回资源,⽽是告诉客户端直接从缓存中获取,客户端收到返回后就会从缓存中获取资

源;

3、强缓存和协商缓存共同之处在于,如果命中缓存,服务器都不会返回资源;区别是,强缓

存不对发送请求到服务器,但协商缓存会。

4、当协商缓存也没命中时,服务器就会将资源发送回客户端。

5、当 ctrl+f5 强制刷新⽹⻚时,直接从服务器加载,跳过强缓存和协商缓存;

6、当 f5 刷新⽹⻚时,跳过强缓存,但是会检查协商缓存;

38、宏任务 setTimeout setInterval 微任务 Promise

js 引擎在⼀次事件循环中,会先执⾏ js 线程的主任务,然后会去查找是否有微任务

microtask(promise),如果有那就优先执⾏微任务,如果没有,在去查找

宏任务 macrotask(setTimeout、setInterval)进⾏执⾏

39、React 中的 Key 值

1. 为什么要有 key 值

相同的 key 不会重新渲染

key 是一个字符串,用来唯一标识同父同层级的兄弟元素。当 React 作 diff 时,只要子元素有 key 属性,便会去原 v -dom 树中相应位置(当前横向比较的层级)寻找是否有同 key 元素,比较它们是否完全相同,若是则复用该元素,免去不必要的操作。

但是强烈不推荐用数组 index 来作为 key。如果数据更新仅仅是数组重新排序或在其中间位置插入新元素,那么视图元素都将重新渲染

40、Vue 中 v-if 与 v-show 区别

v-if 控制元素显示隐藏 当条件不成立时不加载 dom 结构

v-else 配合 v -if 使用

v-show 控制元素显示隐藏 当条件不成立时加载 dom 结构通过 css display:none 实现显示隐藏

41、vue 中 $router 和 $route 的区别

1、router 是 VueRouter 的一个对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性,如 router.push 方法,路由跳转,传递参数等。

2、route 为当前 router 跳转对象。里面可以获取当前路由的 name,path,query,parmas 等 可以拿里边的值来做各种判断。

42、Vue 组件中的 data 为什么必须是一个函数

如果 data 是一个函数的话,这样每复用一次组件,就会返回一份新的 data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份 data,就会造成一个变了全都会变的结果。

所以说 vue 组件的 data 必须是函数。这都是因为 js 的特性带来的,跟 vue 本身设计无关。

43、前台路由和后台路由的区别

前台路由:跳转页面,不请求服务器

后台路由:接口访问地址,请求服务器

44、ES6 模块与 CommonJS 模块的差异

CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。

CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

45、XSS

XSS 的含义:跨站脚本攻击, 故将跨站脚本攻击缩写为 XSS。恶意攻击者往 Web 页面里插入恶意 Script 代码,当用户浏览该页之时,嵌入其中 Web 里面的 Script 代码会被执行,从而达到恶意攻击用户的目的。

CSRF 全称 cross-site request forgery,名为跨站请求伪造

顾名思义就是黑客伪装成用户身份来执行一些非用户自愿的恶意以及非法操作

(1)CSRF 相对于 XSS 漏洞的危害程度更高一些。

(2)XSS 有局限性,而 CSRF 则不。

(3)CSRF 相当于是 XSS 的基础版,CSRF 能做到的 XSS 都可以做到。

(4)XSS 主要指向客户端,而 CSRF 针对服务端。

(5)XSS 是利用合法用户获取其信息,而 CSRF 是伪造成合法用户发起请求。

预防措施:

  1、验证码

  2、tokenId 令牌

  3、判断请求的 Referer 是否正确

46、做项目流程

* 项目流程

1. 需求评审: 前端 后台 测试 UI 产品 评审需求是否合理 砍掉不合理需求 和

实现难度大的需求

2. UI 出效果图

3. 前后端开始同时开发: 前端封装组件 和 页面

// mock 工具 阿里 RAP

// /abc/ddd {name: ‘ 小花 ’, age: 22}

// /mock/abc/ddd {name: 小白, age: 2}

4. 前端调用 mock 数据接口 (后台) 做静态页面 后台开发接口

5. 测试

  1) 测试环境 测试分支 dev

  2) dev 完全没问题 代码合并到 master 分组 发布上线 master 分支

上线 都是上 master

6. 上线以后 回归测试 有 bug 改

47、diff 算法 

高效的 diff 算法能够保证进行对实际的 DOM 进行最小的变动

但是标准的的 Diff 算法复杂度需要 O(n^3)

这显然无法满足性能要求 要达到每次界面都可以整体刷新界面的目的

势必需要对算法进行优化

React 里结合 Web 界面的特点做出了两个简单的假设

使得 Diff 算法复杂度直接降低到 O(n)

1. 两个相同组件产生类似的 DOM 结构 不同的组件产生不同的 DOM 结构

2. 对于同一层次的一组子节点 它们可以通过唯一的 id 进行区分

不同节点类型的比较

为了在树之间进行比较 我们首先要能够比较两个节点 在 React 中即比较两个虚拟 DOM 节点

当两个节点不同时 应该如何处理 这分为两种情况

1. 节点类型不同

2. 节点类型相同 但是属性不同

节点类型不同 直接删除原节点  插入新节点。

48、虚拟 DOM

虚拟 DOM (VDOM)是真实 DOM 在内存中的表示

UI 的表示形式保存在内存中 并与实际的 DOM 同步

这是一个发生在渲染函数被调用和元素在屏幕上显示之间的步骤 整个过程被称为调和

49、event loop 事件循环机制(宏任务、微任务)

1. 先执行同步任务

2. 微任务调用栈 [resolve(1), resolve(2), resolve(3)]

3. 宏任务(macrotask): setTimeout setInterval I/O(异步操作) DOM 渲染

50、三次握手四次挥手

* 三次握手

第一次握手:客户端给服务器发送一个 SYN 报文。

第二次握手:服务器收到 SYN 报文之后,会应答一个 SYN+ACK 报文。

第三次握手:客户端收到 SYN+ACK 报文之后,会回应一个 ACK 报文。

服务器收到 ACK 报文之后,三次握手建立完成。

* 四次挥手

第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。

第二次握手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。

第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。

第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态

服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。

51、B C

  B: Business 企业 商家

  C: Customer 个人 客户

  B2B 和 C2C 都在第三方平台 B2C 则在自身运营平台

  B2B: 企业与企业 阿里巴巴

  B2C: 商家对个人 卓越 当当 京东

  C2C: 个人对个人的 淘宝的小店铺

52、PV UV

  PV::统计页面节点的点击量

  UV:统计访问某站点的用户数

  实现:

    1. 创建一个 img

    2. img.src = ‘1.gif?name=abc’

  使用: 点击百度按钮 加 pv name=”abc”

    1. pv.js <script src=”pv.js”> sendPv

    2. sendPv({name: “abc”})

53、MVVM 是 Model-View-ViewModel 的缩写

Model 代表数据模型,也可以在 Model 中定义数据修改和操作的业务逻辑。

View 代表 UI 组件,它负责将数据模型转化成 UI 展现出来。

ViewModel 监听模型数据的改变和控制视图⾏为、处理⽤户交互,简单理解就是⼀个同 步 View 和 Model 的对象,连接 Model 和 View

在 MVVM 架构下,View 和 Model 之间并没有直接的联系,⽽是通过

ViewModel 进⾏交互,Model 和 ViewModel 之间的交互是双向的,因 此 View 数据的变化会同步到 Model 中,⽽ Model 数据的变化也会⽴即反

应到 View 上。

ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,⽽

View 和 Model 之间的同步⼯作完全是⾃动的,⽆需⼈为⼲涉,因此开 发者只需关注业务逻辑,不需要⼿动操作 DOM,不需要关注数据状态的同 步问题,复杂的数据状态维护完全由 MVVM 来统⼀管理

54、浏览器对 html 渲染 

1. 解析 html 和构建 dom 树是同步进行的,这个过程就是逐行解析代码,包括 html 标签和 js 动态生成的标签,最终生成 dom 树。

2. 构建呈现树,就是把 css 文件和 style 标签的中的内容,结合 dom 树的模型,构建一个呈现树,写到内存,等待进一步生成界面。呈现树一定依赖 dom 树,呈现节点一定会有对应的 dom 节点,但是 dom 节点不一定会有对应的呈现节点,比如,被隐藏的一个 div。

3. 布局,这一步就是结合呈现树,把 dom 节点的大小、位置计算出来。虽然呈现节点已经附着在都没节点上,会有对元素大小、位置的定义,但是浏览器还需要根据实际窗口大小进行计算,比如对 auto 的处理。

4. 绘制,把 css 中有关颜色的设置,背景、字体颜色等呈现出来。

55、fetch 和 ajax 的主要区别

  1. fetch()返回的 promise 将不会拒绝 http 的错误状态 即使响应是一个 HTTP 404 或者 500

  2. 在默认情况下 fetch 不会接受或者发送 cookies

56、react 渲染机制:

    React 整个的渲染机制就是在 state/props 发生改变的时候 重新渲染所有的节点 构造出新的虚拟 Dom tree 跟原来的 Dom tree 用 Diff 算法进行比较 得到需要更新的地方在批量造作在真实的 Dom 上,由于这样做就减少了对 Dom 的频繁操作 从而提升的性能

57、Vue 实现数据双向绑定的原理:

vue 实现数据双向绑定主要是: 采⽤数据劫持结合发布订阅模式·的⽅式

通过 Object.defineProperty() 来劫持各个属性的 setter, getter 在数据变动时发布消息给订阅者, 触发相应监听回调. 整合 Observer, Compile 和

Watcher 三者, 通过 Observer 来监听⾃⼰的 model 的数据变化,通过 Compile 来解 析编译模板指令 (vue 中是⽤来解析 {{}}) 最终利⽤ watcher 搭起 observer 和

Compile 之间的通信桥梁, 达到数据变化 —> 视图更新; 视图交互变化 input —>

数据 model 变更双向绑定效果

58、vue 和 react 区别

没有双向绑定

vue MVVM

vue2 Object.defineProperty()

vue3 proxy

react diff 算法

react 丰富的插件库

react 上手难

59、调用 setState 发生一些什么(异步)

在代码调用 setState 之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程。经过调和过程 React 会构建新的 React 元素树  然后会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化的渲染。React 能够精确地知道哪些位置发生了改变,这就保证了按需更新,而不是重新渲染。

setstate 是异步的,但是在 ajax 里是同步的

60、链表:

      * 单向链表: 单向链表包含两个域 一个是信息域 一个是指针域

      * 双向链表: 每个节点有 2 个链接 一个是指向前一个节点 另一个则指向后一个节点

      * 循环链表: 循环链表就是首节点和末节点被连接在一起

      循环链表中第一个节点之前就是最后一个节点

    * 数组和链表的区别:

        * 链表是链式的存储结构 数组是顺序的存储结构

        * 链表通过指针来连接元素 数组则是把所有元素按次序依次存储

        * 链表的插入删除元素相对数组较为简单 但是寻找某个元素较为困难

        * 数组寻找某个元素较为简单 但插入与删除比较复杂

        * 自我理解

          * 数组便于查询和修改 但是不方便新增和删除

          * 链表适合新增和删除 但是不适合查询

61、computed 和 watch 的区别

           computed 对于其中变量的依赖是多个的,它的函数中使用了多个 this.xxx , 只要其中一个发生了变化,都会触发这个函数。而 watch 的依赖则是单个的,它每次只可以对一个变量进行监控。

62、position 有哪些值

    1、static:默认值;

    2、绝对定位:absolute

    3、相对定位:relative

    4、固定定位:fixed

    5、粘性布局  sticky

63、DOM2 事件的三个阶段

(1)捕获阶段

(2)目标阶段

(3)冒泡阶段

正文完
 0