前端面试题

SIX_one

1. 请简单叙述Vue2和Vue3的区别和变化至少说6点?

  • 数据绑定的原理发生了变化:vue2中使用了object.definedProperty(),vue3中使用proxy对数据代理。
  • 建立数据发生了变化:vue2把数据放在data中,vue3把数据放在setup中。
  • 是否支持碎片化:vue2.0只允许有一个根标签,vue3.0支持碎片化,可以拥有对多个根节点。
  • composition API:vue2中采用的是选选项式api,vue3采用的是组合式api
  • 生命周期的不同:vue3在组合式API中使用生命周期钩子函数的时候,使用的时候需要引入,vue中可以直接使用生命周期钩子函数。
  • main.js文件不同:vue2中我们可以使用pototype的形式进行操作,引入的是构造函数,vue3中需要使用结构的形式进行操作,引入的是工厂函数。

2. Vue3中组件通信的方法有些?

  • props:父组件以数据绑定的形式声明要传递的数据,子组件通过defineProperty方法创建props对象,就能拿到父组件传递过来的数据。
父组件
<!-- list是我们要传递的数据 -->
<child-components :list="list"></child-components>
子组件
<template>
  <ul>
    <li v-for="i in props.list" :key="i">{{ i }}</li>
  </ul>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
  list: {
    type: Array
  },
})
</script>
  • emit方式:是vue中最常见的组件通信方式,该方式用于子传父;
子组件
const emits = defineEmits(['add'])
emits('add', 1)

父组件
<!-- add是子组件要传递的动作,handleAdd是监听到之后执行的事件 -->
<child-components @add="handleAdd"></child-components>
<script>
 const list = ref([1,2,3])
 const handleAdd = value => {
  list.value.push(value)
}
</script>

v-model方式 不能严格的作为数据传递的方式,只是减少了代码量。

<ChildComponent v-model:list="list" />
// 等价于
<ChildComponent :list="pageTitle" @update:list="list = $event" />

//子组件需要emit一个叫update:xxx的事件,再把需要更新的响应式数据传给emit方法的第二个参数即可
const emits = defineEmits(['update:list'])
emits('update:list', arr)

  • provide/inject就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量,实现祖和后代组件间通信
    父组件有一个provide选项提供数据,后代组件有一个inject选项来开始使用这些数据。
    provide(第一个参数是要注入的key,它可以是一个字符串或一个symbol;第二个参数是要注入的值(具体要传递给子孙组件的数据)。
import {reactive,provide} from "vue"; 
let person = reactive({name: '张三',age: 14});
provide('person',person);

inject()函数
定义: 注入一个由祖先(父)组件或整个应用提供的值
实现: 接收父(祖)组件传递过来的值.

nject(第一个参数,第二个参数(可选)):第一个参数是注入的key,来自父(祖)组件,它们两者是需要保持一致的
Vue会遍历父组件链,通过匹配key来确定所提供的值,如果父组件链上多个组件对同一个key提供了之,那么离得更近的将会覆盖链上更远的组件所提供的值
如果没有能通过key匹配到的值,inject()函数将返回undefined,除非提供一个默认值
第二个参数是可选的,即没有匹配到key时,使用默认值,它也可以是一个函数,用来返回某些创建起来比较复杂的值,如果默认值本身就是一个函数,那么必须将false作为第三个参数传入,表明这个函数就是默认值,而不是一个工厂函数。
与注册生命周期钩子的API类似,inject()必须在组件的setup()阶段同步调用

import {inject,toRefs} from  "vue";
const person = inject('person');
// 若是使用解构,则会丢失响应式,修改数据时,页面不会更新,具体解决,可以引入toRef或toRefs函数
const {name,website} = toRefs(person);

模板使用
{{person.name}}---{{person.website}}
  • vuex/pinia Vuex 和 Pinia 是 Vue 3 中的状态管理工具,使用这两个工具可以轻松实现组件通信。
  • eventBus Vue 3 中移除了 eventBus,但可以借助第三方工具来完成。Vue 官方推荐使用 mitt 或 tiny-emitter。

3. 说说对盒子模型的理解?

盒模型都是由四人部分组成的,分别是margin、border、padding和content.
标准盒模型和IE盒模型的区别在于设置width和height时,所对应的范围不同标准盒模型的width和height属性的范围只包含了content,
IE盒模型的width和height属性的范围包含了border、padding和content。
可以通过修改元素的box-sizing属性来改变元素的盒模型
box-sizing: content-box 表示标准盒模型 (默认值)
box-sizing: border-box 表示E盒模型 (怪异盒模型)

4. Css的选择器有哪些?优先级?哪些可以继承

选择器类型:

  • 通配符选择器:*
  • 标签选择器 E
  • id选择器 #id
  • 类选择器 .class
  • 伪类选择器
  • 后代选择器(#box div),选择id为box元素内部所有的div元素
  • 子选择器(.one>one_1),选择父元素为.one的所有.one_1的元素

优先级:
!important>内联 > ID选择器 > 类选择器 > 标签选择器
继承属性:
字体系列属性:font:组合字体、font-family:规定元素的字体系列、font-weight:设置字体的粗细、font-size:设置字体的尺寸、等
文本系列属性:text-indent:文本缩进、text-align:文本水平对刘、line-height:行高、color:文本颜色等。
列表属性:list-style-type:文字前面的小点点样式、list-style-position:小点点位置、list-style:以上的属性可通过这属性集合。

5. 元素水平垂直居中的方法有哪些?如果元素不定宽高呢?

点击查看详情

6. 怎么理解回流跟重绘?什么场景下会触发?

回流:布局引擎会根据各种样式计算每个盒子在页面上的大小与位置
重绘:当计算好盒模型的位置、大小及其他属性后,浏览器根据每个盒子特性进行绘制。
重绘的触发条件
color、backgroundColor、size等改变元素外观的属性
重绘的触发条件
重绘一般发生在 UI 界面;是一个元素外观的改变所触发的浏览器行为,浏览器会根据元素的新属性重 新绘制,使元素呈现新的外观。
回流的触发条件:
任何页面布局和几何属性的改变都会触发重排。

7. 什么是响应式设计?响应式设计的基本原理是什么?如何做?

响应式网站设计(Responsive Web design)是一种网络页面设计布局,页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整。
实现方式
响应式设计的基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理,为了处理移动端,页面头部必须有meta声明viewport。
实现响应式布局的方式有如下:

媒体查询
百分比
vw/vh
rem

- 媒体查询

CSS3中的增加了更多的媒体查询,就像if条件表达式一样,我们可以设置不同类型的媒体条件,并根据对应的条件,给相应符合条件的媒体调用相对应的样式表,通过媒体查询,可以通过给不同分辨率的设备编写不同的样式来实现响应式的布局,比如我们为不同分辨率的屏幕,设置不同的背景图片。

- 百分比

通过百分比单位 " % " 来实现响应式的效果。

- rem
移动端多会采用rem进行页面的布置。
响应式设计实现通常会从以下几方面思考:
- 小结

弹性盒子(包括图片、表格、视频)和媒体查询等技术
使用百分比布局创建流式布局的弹性UI,同时使用媒体查询限制元素的尺寸和内容变更范围
使用相对单位使得内容自适应调节
选择断点,针对不同断点实现不同布局和内容展示。

- 总结

优点:

面对不同分辨率设备灵活性强
能够快捷解决多设备显示适应问题
缺点:
仅适用布局、信息、框架并不复杂的部门类型网站
兼容各种设备工作量大,效率低下
代码累赘,会出现隐藏无用的元素,加载时间加长
其实这是一种折中性质的设计解决方案,多方面因素影响而达不到最佳效果
一定程度上改变了网站原有的布局结构,会出现用户混淆的情况

8. 如果要做优化,CSS提高性能的方法有哪些?

实现方式
实现方式有很多种,主要有如下:

内联首屏关键CSS(通过内联css关键代码能够使浏览器在下载完html后就能立刻渲染)
异步加载CSS(在CSS文件请求、下载、解析完成之前,CSS会阻塞渲染,浏览器将不会渲染任何已处理的内容,前面加载内联代码后,后面的外部引用css则没必要阻塞浏览器渲染。这时候就可以采取异步加载的方案:比如:使用javascript将link标签插到head标签最后)
资源压缩(利用webpack、gulp/grunt、rollup等模块化工具,将css代码进行压缩,使文件变小,大大降低了浏览器的加载时间)
合理使用选择器(我们在编写选择器的时候,可以遵循以下规则:

不要嵌套使用过多复杂选择器,最好不要三层以上,使用id选择器就没必要再进行嵌套;通配符和属性选择器效率最低,避免使用)
减少使用昂贵的属性(在页面发生重绘的时候,昂贵属性如box-shadow/border-radius/filter/透明度/:nth-child等,会降低浏览器的渲染性能)
不要使用@import(css样式文件有两种引入方式,一种是link元素,另一种是@import,
@import会影响浏览器的并行下载,使得页面在加载时增加额外的延迟,增添了额外的往返耗时
而且多个@import可能会导致下载顺序紊乱)

9. 对前端工程师这个职位是怎么样理解的?它的前景会怎么样

10. 说说JavaScript中的数据类型?存储上的差别?

在JavaScript中,我们可以分成两种类型:

基本类型

	基本类型主要为以下6种:
	Number
	String
	Boolean
	Undefined
	null
	symbol

复杂类型
复杂类型统称为Object,我们这里主要讲述下面三种:

Object
Array
Function

两种类型的区别是:存储位置不同

存储区别
基本数据类型和引用数据类型存储在内存中的位置不同:

基本数据类型存储在栈中
引用类型的对象存储于堆中

当我们把变量赋值给一个变量时,解析器首先要确认的就是这个值是基本类型值还是引用类型值

11. 请简单叙述js数据类型判断的方法有哪些?

typeof ,instanceof,Object.prototype.toString.call()

  • typeof它返回值是一个字符串,该字符串说明运算数的类型.
  • instanceof 是用来 判断数据是否是某个对象的实例,返回一个布尔值。
    缺点:对于基本类型的数据,instanceof是不能直接判断它的类型的,因为实例是一个对象或函数创建的,是引用类型,所以需要通过基本类型对应的
    包装对象 来判断。所以对于 null 和 undefined 这两个家伙就检测不了.
  • Array.isArray() 方法:js中的isArray()是Array类型的一个静态方法,使用它可以判断一个值是否为数组。返回一个布尔值。

12. 说说你对闭包的理解?闭包使用场景?

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包.闭包让你可以在一个内层函数中访问到其外层函数的作用域.
使用场景
任何闭包的使用场景都离不开这两点:

创建私有变量
延长变量的生命周期

注意事项
如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响

13. bind、call、apply 区别?如何实现一个bind?

call,apply, bind方法都可以改变函数的this指向
call方法apply调用后函数会立即执行,bind万法不会立即执行函数call方法和bind方法后面跟的是参数列表,apply的参数据是一个数组。

14. Javascript本地存储的方式有哪些?区别及应用场景?

javaScript本地缓存的方法:

cookie
sessionStorage
localStorage
indexedDB
区别:
关于cookie、sessionStorage、localStorage三者的区别主要如下:
存储大小:cookie数据大小不能超过4k,sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
有效时间:localStorage存储持久数据,浏览器关闭后数据不丢失除非主动删除数据; sessionStorage数据在当前浏览器窗口关闭后自动删除;cookie设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
数据与服务器之间的交互方式,cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端; sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
应用场景:
标记用户与跟踪用户行为的情况,推荐使用cookie
适合长期保存在本地的数据(令牌),推荐使用localStorage
敏感账号一次性登录,推荐使用sessionStorage
存储大量数据的情况、在线文档(富文本编辑器)保存编辑历史的情况,推荐使用indexedDB

15. 请叙述Vue2和Vue3数据响应式原理的不同?

vue2响应式:
vue2.0的双向数据绑定是通过数据劫持,结合发布订阅的方式来实现的,也就是说数据和视图同步,数据发生变化,视图也会发生变化,视图变化,数据也会随之发生改变。vue2的双向数据绑定核心是object.definedproperty()方法。给vue中的数据绑定get和set方法,当获取数据的时候,调用get()方法,当修改数据的时候调用set()方法。通过watcher监听器去更新视图,完成数据的双向绑定。
Vue3中的响应式原理:
通过Proxy(代理): 拦截对象中任意属性的变化,包括:属性值的读写,属性的增加,属性的删除等。
对比:
在Vue中,Object.defineProperty无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应。

16. 请叙述Vue2和Vue3的diff算法的区别?

点击详情

17. 请简单叙述你对作用域链得理解?

  • 概念:

作用域,即变量(变量作用域又称上下文)和函数生效(能被访问)的区域或集合

换句话说,作用域决定了代码区块中变量和其他资源的可见性。

  • 作用域分类:

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

18. Vue3中的生命周期函数的变化以及含义?

点击详情

19. Vue3中自定义指令生命周期的变化及含义

自定义指令的生命周期
 自定义指令有五个生命周期(也叫钩子函数),分别是bind,inserted,update,componentUpdated,unbind

**bind:**只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个绑定时执行一次的初始化动作。
**inserted:**被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于document中)。
update:被绑定于元素所在的模板更新时调用,而无论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
componentUpdated:被绑定元素所在模板完成一次更新周期时调用。
unbind:只调用一次,指令与元素解绑时调用。

20. Vue3中的组合式Api有哪些? 和Vue2的Options Api又什么不同?

了解 Options Api
Options API,即大家常说的选项API,即以vue为后缀的文件,通过定义methods,computed,watch,data等属性与方法,共同处理页面逻辑。

Composition
在 Vue3 Composition API 中,组件根据逻辑功能来组织的,一个功能所定义的所有 API 会放在一起(更加的高内聚,低耦合),即使项目很大,功能很多,我们都能快速的定位到这个功能所用到的所有 API,Compositon API,将某个逻辑关注点相关的代码全都放在一个函数里,这样当需要修改一个功能时,就不再需要在文件中跳来跳去。

  • composition APi:

    Vue3.0中一个新的配置向,值为一个函数
    setup是所有Composition API(组合API) ”表演的舞台“
    组件中所有用到的:数据、方法等等,均要配置在setup中

  • setup语法糖

      <script setup> 语法糖里面的代码会被编译成组件setup()函数的内容,不需要通过return
     暴露声明的变量、函数以及import引入的内容,即可在<template/>使用,并且不需要
     export default{}
    
  • ref函数

    作用:定义一个响应式的数据。
    基本类型的数据:响应式依然是靠Object.defineProperty()的get和set完成的
    对象类型的数据:内部“求助”了Vue3.0的一个新的函数------reactive函数

21.css3有什么新特性

  • 新增各种CSS选择器 (: not(input): 所有 class 不是“input”的节点)
  • 圆角 (border-radius:8px)
  • 多列布局 (multi-column layout)
  • 阴影和反射 (Shadoweflect)
  • 文字特效 (text-shadow)
  • 文字渲染"(Text-decoration)
  • 线性渐变 (gradient)
  • 旋转 (transform)
  • 增加了旋转,缩放,定位,倾斜,动画,多背景

23. Vue3中组件通信的流程【父传子,子传父】

父传子( defineProps):

父组件提供数据

父组件将数据传递给子组件 

子组件通过 defineProps 进行接收

子组件渲染父组件传递的数据

子传父(defineEmit):

子组件通过defineEmit获取emit对象
子组件通过emit触发事件 并传递数据
父组件提供方法
父组件通过自定义事件的方式给子组件注册事件

24. Apply/call/bind的原理是什么?

call,apply, bind方法都可以改变函数的this指向
call方法apply调用后函数会立即执行,bind方法不会立即执行函数。
cal方法和bind万法后面跟的是参数列表,apply的参数据是一个数组。

25. 说说你对原型和原型链的理解?

原型?
每一个构造函数都有一个prototype属性,这个属性称之为函数的显示原型
构造函数实例化后或者对象都有一个 prot0_ 属性,称之为对象的隐式原型,后续原型链就是通过proto查找属性的.
原型链?
当我们访问对象的某个属性时,会先从当前对象中查找,如果没有找到的则继续去对象的proto隐士原型中去查找,如果还没找到则继续向上级对象的原型中查找,直到找到顶层Obiec对象,如果没有找到返回undefined,这种通过对象的proto隐式原型查找属性的链条关系称之为原型链。
会先从当前对象中查找,如果没有找到的则继续去对象的proto隐士原型中去查找,,
如果还没找到则继续向上级对象的原型中查找,直到找到顶层Object对象,如果没有找到返回undefined,这种通过对象的 _proto__隐式原型查找属性的链条关系称之为原型链。

26. 说说你对ES6中Generator的理解?

简述:
如果说JavaScript是ECMAScript标准的一种具体实现、Iterator遍历器是Iterator的具体实现,那么Generator函数可以说是Iterator接口的具体实现方式。
执行Generator函数会返回一个遍历器对象,每一次Generator函数里面的yield都相当一次遍历器对象的next()方法,并且可以通过next(value)方法传入自定义的value,来改变Generator函数的行为。
Generator函数可以通过配合Thunk 函数更轻松更优雅的实现异步编程和控制流管理。
原理:
Generator 是 ES6中新增的语法,和 Promise 一样,都可以用来异步编程。

// 使用 * 表示这是一个 Generator 函数
// 内部可以通过 yield 暂停代码
// 通过调用 next 恢复执行
function* test() {
  let a = 1 + 2;
  yield 2;
  yield 3;
}
let b = test();
console.log(b.next()); // >  { value: 2, done: false }
console.log(b.next()); // >  { value: 3, done: false }
console.log(b.next()); // >  { value: undefined, done: true }

27. 说说你对Event Loop的理解

为什么会有event loop
因为js是单线程的,如果某段程序需要等待一会再执行,后面的程序都会被阻塞,这样也就带来了一些问题。为了解决这个问题,js出现了同步和异步两种任务,两种任务的差异就在于执行的优先级不同。event loop就是对任务的执行顺序做了详细的规范。
什么是 event loop
事件循环(event loop)就是 任务在主线程不断进栈出栈的一个循环过程。任务会在将要执行时进入主线程,在执行完毕后会退出主线程。
循环的步骤:
1.把同步任务队列 或者 微任务队列 或者 宏任务队列中的任务放入主线程。
2.同步任务 或者 微任务 或者 宏任务在执行完毕后会全部退出主线程。
在实际场景下大概是这么一个顺序:
1.把同步任务相继加入同步任务队列。
2.把同步任务队列的任务相继加入主线程。
3.待主线程的任务相继执行完毕后,把主线程队列清空。

4.把微任务相继加入微任务队列。
5.把微任务队列的任务相继加入主线程。
6.待主线程的任务相继执行完毕后,把主线程队列清空。
7.把宏任务相继加入宏任务队列。无time的先加入,像网络请求。有time的后加入,像setTimeout(()=>{},time),在他们中time短的先加入。
8.把宏任务队列的任务相继加入主线程。
9.待主线程的任务相继执行完毕后,把主线程队列清空

28. 说说Promise和async/await 的区别?

promise:

Promise是ES6中的新增的异步处理方法,主要是用于解决ES5中使用回调函数产生的地狱回调的问题Promise有三种状态,
pedding准备中,fulfiled已完成,rejected失败,状态只能有准备中=>已完成或准备中=>失败。

async/await:

1.async函数返回的是一个promise函数,可以使用then()回调函数,return返回的值便是then方法里的参数
2.async返回的promise对象只有内部的await全部执行完,才会执行then()的回调函数
3.await语句后面可能会等具体的值也可能会等promise对象,如果是promise对象,一般返回的是resolve的结果,如果是reject,
则后续的await将不会在执行。
4.await命令只能在async函数里,普通函数会报错 

三者区别

promise和 async/await都是解决异步编程的一种方式,但是async/await使得异步代码看起来像同步代码。
函数前面多了一个async关键字。await关键字只能用于async定于的函数内。async函数会隐式地返回一个Promise,
该promise的resolve值就是return的值。

29. 说说浏览器事件循环和nodeJs的事件循环的区别?

点击详情

30. 说说你对浏览器缓存机制的理解

浏览器的缓存机制
浏览器缓存机制有两种,一种为强缓存,一种为协商缓存

对于强缓存,浏览器在第一次请求的时候,会直接下载资源,然后缓存在本地,第二次请求的时候,直接使用缓存。
对于协商缓存,第一次请求缓存且保存缓存标识与时间,重复请求向服务器发送缓存标识和最后缓存时间,服务端进行校验,如果失效则使用缓存。

协商缓存相关设置

Exprires:服务端的响应头,第一次请求的时候,告诉客户端,该资源什么时候会过期。Exprires的缺陷是必须保证服务端时间和客户端时间严格同步。
Cache-control:max-age:表示该资源多少时间后过期,解决了客户端和服务端时间必须同步的问题,
If-None-Match/ETag:缓存标识,对比缓存时使用它来标识一个缓存,第一次请求的时候,服务端会返回该标识给客户端,客户端在第二次请求的时候会带上该标识与服务端进行对比并返回If-None-Match标识是否表示匹配。
Last-modified/If-Modified-Since:第一次请求的时候服务端返回Last-modified表明请求的资源上次的修改时间,第二次请求的时候客户端带上请求头If-Modified-Since,表示资源上次的修改时间,服务端拿到这两个字段进行对比

31. 说说你对浏览器内核的理解

浏览器内核两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎

  • 渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核
  • JS引擎则:解析和执行javascript来实现网页的动态效果

最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎

常见的浏览器内核

Trident内核:IE,MaxThon,TT,The World,360,搜狗浏览器等。[又称MSHTML]
Gecko内核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey等
Presto内核:Opera7及以上。 [Opera内核原为:Presto,现为:Blink;]
Webkit内核:Safari,Chrome等。 [ Chrome的Blink(WebKit的分支)]

32. 说说你对Vue的响应式原理的理解

vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;
VUE双向数据绑定,其核心是 Object.defineProperty()方法,给Vue中的数据绑定get和set方法,当获取数据的时候,调用get方法,修改data中的数据的时候调用set方法,通过watcher监听器去更新视图,完成数据的双向绑定。

 1. 需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter这样的话,
给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化。

 2. compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定
更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。

3.watcher订阅者是observer和compile之间通信的桥梁,主要做的事情是:1*.在自身实例化时往属性订阅器里面添加自己
	2*.组件自身必须有一个update()方法.3*待属性变动dep.notice()通知时,能调用自身的update()方法,
并触发complie中绑定的回调,则功成身退。

4. MVVM作为数据绑定的入口,整合observer、compile和watcher三者,通过observer来监听自己的model数据变化,
通过compile来解析编译模板指令,最终利用watcher搭起来Observer和Compile之间的通信桥梁,达到数据变化,
视图更新,视图交互话变化,数据model变更的双向绑定效果。

33. Methods watch computed区别是什么?

computed

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

对于Watch:
它不支持缓存,数据变化时,它就会触发相应的操作
支持异步监听
监听的函数接收两个参数,第一个参数是最新的值,第二个是变化之前的值
当一个属性发生变化时,就需要执行相应的操作
监听数据必须是data中声明的或者父组件传递过来的props中的数据,当发生变化时,会触发其他操作,函数有两个的参数:
immediate: 组件加载立即触发回调函数0
deep: 深度监听,发现数据内部的变化,在复杂数据类型中使用,例如数组中的对象发生变化。需要注0意的是,deep无法监听到数组和对象内部的变化。当想要执行异步或者昂贵的操作以响应不断的变化时,就需要使用watch。

运用场景:
当需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时都要重新计算。
当需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许执行异步操作(访问一个 API),限制执行该操作的频率,并在得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
Computed 和 Methods 的区别
可以将同一函数定义为一个 method 或者一人计算属性。对于最终的结果,两种方式是相同的
不同点:
·computed: 计算属性是基于它们的依赖进行缓存的,只有在它的相关依赖发生改变时才会重新求值;
·method 调用总会执行该函数

34. 说说你对Virtual DOM的理解?

概述:
虚拟 DOM (Virtual DOM )这个概念相信大家都不陌生,从 React 到 Vue ,虚拟 DOM 为这两个框架都带来了跨平台的能力(React-Native 和 Weex)
实际上它只是一层对真实DOM的抽象,以JavaScript 对象 (VNode 节点) 作为基础的树,用对象的属性来描述节点,最终可以通过一系列操作使这棵树映射到真实环境上。
在Javascript对象中,虚拟DOM 表现为一个 Object对象。并且最少包含标签名 (tag)、属性 (attrs) 和子元素对象 (children) 三个属性,不同框架对这三个属性的名命可能会有差别
创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应。
为什么使用虚拟dom:
DOM是很慢的,其元素非常庞大,页面的性能问题,大部分都是由DOM操作引起的

35. 说说你对nextTick的理解和作用

vue的$nextTick其本质是对js执行原理EventLoop的一种应用。
$nextTick的核心是利用promise,mutationObserver、setImmediate、setTimeout的原生
javascript方法来模拟对应的微/宏任务的实现,本质是为了利用JavaScript的这些异步回调任务队列来实现vue框架中自己的异步回调队列。
nextTick是典型的将底层的javascript执行原理应用到具体案例中的示例,引入异步更新队列机制的原因:

 如果是同步更新,则多次对一个或者多个属性赋值,会频繁触发dom的渲染,可以减少一些无用的渲染。
同时由于virtualDom的引入,每一次状态发生变化之后,状态变化的信号会发送给组件,组件内部使用virtualDom进行计算得
出需要更新的具体的dom节点,然后对dom进行更新操作,每次更新状态后的渲染过程需要更多的计算,而这种无用功也将
浪费更多的性能,所以异步渲染变得更加至关重要。
 vue采用了数据驱动的思想,但是在一些情况下,仍然需要操作dom。有时候,可能遇到这样的情况,
 dom1的数据发生了变化,而dom2需要从dom1中获取数据,那这时候就会发现dom2的试图并没有更新,这时就需要
 用到nextTick了。

36. 说说你对webpack的理解

点击查看详情

37. 谈谈GET和POST的区别

最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。

GET在浏览器回退时是无害的,而POST会再次提交请求。

GET产生的URL地址可以被Bookmark,而POST不可以。
GET请求只能进行url编码,而POST支持多种编码方式
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
GET请求在URL中传送的参数是有长度限制的,而POST没有。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

更详细回答:
GET和POST还有一个重大区别,简单的说:

GET产生一个TCP数据包;POST产生两个TCP数据包。

对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。

因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?

1. GET与POST都有自己的语义,不能随便混用。

2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,
 两次包的TCP在验证数据包完整性上,有非常大的优点。

3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

38. 说说HTTP和HTTPS的区别,HTTPS加密原理是?

HTTPS
HTTPS是在HTTP上建立SSL加密层,并对传输数据进行加密,是HTTP协议的安全版。

HTTPS主要作用是:

1.对数据进行加密,并建立一个信息安全通道,来保证传输过程中的数据安全;

2.对网站服务器进行真实身份认证。

HTTPS替代HTTP的原因

1.通信使用明文(不加密),内容可能被窃听
2.无法证明报文的完整性,报文数据有可能会被篡改
3.不验证通信方的身份,因此有可能遭遇伪装

HTTPS 与 HTTP 的区别
HTTP 是明文传输协议,HTTPS 协议是由 SSL + HTTP 协议构建的可进行加密传输、身份认证的网络协议,HTTPS 协议安全
HTTPS 相比 HTTP 更加安全,对搜索引擎更友好,利于SEO,谷歌、百度优先索引 HTTPS 网页
HTTPS 需要用到SSL证书,而 HTTP 不用
HTTPS 标准端口443,HTTP 标准端口80
HTTPS 基于传输层,HTTP 基于应用层
HTTPS 在浏览器显示绿色安全锁,HTTP 没有显示

加密分类:对称加密 、非对称加密

**对称加密**:加密和解密使用的是同一个秘钥。

**非对称加密**:与对称加密不同,它有两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公钥与私钥是一对,如果用公钥对
数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密。因为加密和解密使用的是两个
不同的密钥,所以这种算法叫作非对称加密算法。

39. TCP为什么要三次握手?

三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包

主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备

第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN©,此时客户端处于 SYN_SENT 状态
第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,为了确认客户端的 SYN,将客户端的 ISN+1作为ACK的值,此时服务器处于 SYN_RCVD 的状态
第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,值为服务器的ISN+1。此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方已建立起了连接。

40. 说说Proxy代理的原理

Proxy的作用
Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。

Proxy可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。

拦截和监视外部对对象的访问
降低函数或类的复杂度
在复杂操作前对操作进行校验或对所需资源进行管理

41. 说说内存泄漏的理解?内存泄漏的情况有哪些?

内存泄漏(Memory leak)是在计算机科学中,由于疏忽或错误造成程序未能释放已经不再使用的内存

并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费

常见内存泄露情况
意外的全局变量
定时器也常会造成内存泄露
没有清理对DOM元素的引用同样造成内存泄露

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值