前端开发重要基础知识

1. 元素水平居中与垂直居中

1.1 水平居中
  • 如果它是一个行内元素,就对它的父元素应用:
  • 如果它是一个块级元素,就对它自身应用:
1.2 垂直居中
  • 基于绝对定位的解决方案(分元素宽高固定和不固定两种情况)
  • 基于视口单位的解决方案(只适用于在视口中居中的场景
  • 基于 的解决方案(最佳解决方案), 还可以将匿名容器(即没有被标签包裹的文本节点)垂直居中

2. 简述box-sizing属性的作用

  • content-box:默认的盒子,设置padding和border会撑开盒子,使盒子比原本的宽高更大
  • border-box:包含了padding和border,设置两者不会撑开盒子,盒子大小不会改变
  • inherit:规定应从父元素继承 box-sizing 属性的值

3. 事件循环

所有的任务可以分为同步任务和异步任务,同步任务,顾名思义,就是立即执行的任务,同步任务一般会直接进入到主线程中执行;而异步任务,就是异步执行的任务,比如ajax网络请求,setTimeout 定时函数等都属于异步任务,异步任务会通过任务队列的机制(先进先出的机制)来进行协调。

同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入任务队列。主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)。

4. 词法作用域

词法作用域是作用域的一种工作模型。作用域有两种工作模型:词法作用域和动态作用域。

词法作用域是一套关于引擎如何寻找变量以及会在何处找到变量的规则。词法作用域最重要的特征是它的定义过程发生在代码的书写阶段(假设你没有使用 或)。

而动态作用域并不关心函数和作用域是如何声明以及在何处声明的,只关心它们从何处调用。换句话说,作用域链是基于调用栈的,而不是代码中的作用域嵌套。

JavaScript 并不具有动态作用域,它只有词法作用域,简单明了。但是this 机制某种程度上很像动态作用域。

主要区别:词法作用域是在写代码或者说定义时确定的,而动态作用域是在运行时确定
的。(this 也是!)词法作用域关注函数在何处声明,而动态作用域关注函数从何处调用。

5. 闭包

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

6. var、let、const

let和const定义的变量都会被提升,但是不会被初始化,不能被引用。主要是因为const。const,顾名思义:常量,const的引用不应被改变。如果编译器把const初始化为undefined,之后,又让它等于我们定义的那个值,就改变了const的引用。因此,委员会决定let和const虽然也会发生变量提升,但是没有任何初始值。

var、let和const另外一个重要区别就是let和const只在块级作用域中有效。

const定义的变量不能被更改,其实是const定义的变量的引用不能被更改

let 和 const 变量提升但存在暂时性死区,未初始化或赋值前不允许访问(ReferenceError)

在全局作用域下使用 / 声明变量,变量并不会被挂载到 上(不是全局window对象的属性)

7. Vue的双向绑定原理/h4>

首先需要一个监听器Observer监听数据(model)的变化,具体实现是利用Observer中Object.definePrototype()函数实现监听数据。当你把一个普通的 JavaScript 对象传入 Vue 实例作为 选项,Vue 将遍历此对象所有的属性,并使用 把这些属性全部转为 [getter/setter]。这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在属性被访问和修改时通知变更。
每个组件实例都对应一个 watcher 实例,当数据发生变化就通知订阅者Watcher,并执行绑定的更新函数,从而更新视图。
最后需要一个Compile解析器,解析V-model、V-on等节点,绑定对应的更新函数并初始化这类节点的模板数据。

8. 判断运行中 this 的绑定

需要找到这个函数的直接调用位置,找到之后就可以顺序应用下面这四条规则来判断 this 的绑定对象。

  • 由 new 调用定到新创建的对象。(new绑定)
  • 由 call 或者 apply(或者 bind)调用定到指定的对象。(显式绑定)
  • 由上下文对象调用定到那个上下文对象。(隐式绑定,可能会出现隐式丢失)
  • 默认:在严格模式下绑定到 undefined,否则绑定到全局对象。(默认绑定)

一定要注意,有些调用可能在无意中使用默认绑定规则。如果想“更安全”地忽略 this 绑定,你可以使用一个 DMZ 对象,比如 = Object.create(null),以保护全局对象。

回调函数丢失 this 绑定是很常见的

ES6 中的箭头函数并不会使用四条规则的绑定规则,而是根据当前的词法作用域来决定 this,具体来说,箭头函数会集成外层函数调用的 this 绑定(无论 this 绑定到什么)。这其实和 ES6 之前代码中的 self = this 机制一样的。

前端开发重要基础知识

硬绑定过的函数不可能再修改它的 。

中实现了硬绑定的内置方法:

第三方库的许多函数,以及 语言和宿主环境中许多新的内置函数,都提供了一个可选的参数,通常被称为“上下文”,其作用和 一样,确保你的回调函数使用指定的 ,比如

new绑定

在 中,构造函数只是一些使用 操作符时被调用的函数。它们并不会属于某个类,也不会实例化一个类。实际上,它们甚至都不能说是一种特殊的函数类型,它们只是被 操作符调用的普通函数而已。实际上并不存在所谓的“构造函数”,只有对于函数的“构造调用”。

使用 来调用函数,或者说发生构造函数调用时,会自动执行下面的操作。

  • 创建(或者说构造)一个全新的对象。
  • 这个新对象会被执行 [[Prototype]] 连接。
  • 这个新对象会绑定到函数调用的 this。
  • 如果函数没有返回其他对象,那么 表达式中的函数调用会自动返回这个新对象。

软绑定

硬绑定会大大降低函数的灵活性,使用硬绑定之后就无法使用隐式绑定或者显示绑定来修改 。

如果可以给默认绑定制定一个全局对象和 以外的值,那就可以实现和硬绑定相同的效果,同时保留隐式绑定或者显示绑定修改 的能力。

软绑定方法:

它会对指定的函数进行封装,首先检查调用的 ,如果 绑定到全局对象或者 ,那就把指定的默认对象 绑定到 ,否则不会修改 。

9. JS有没有指针

JavaScript中没有指针,引用的工作机制也不尽相同。在JavaScript中变量不可能成为指向另一个变量的引用。
JavaScript引用指向的是值。如果一个值有10个引用,这些引用指向的都是同一个值,他们相互之间没有引用/指向关系。

10. 深拷贝浅拷贝

浅拷贝:复制一层对象的属性,并不包括对象里面的引用类型的数据,当改变拷贝的对象里面的引用类型时,源对象也会改变。

深拷贝:重新开辟一个内存空间,需要递归拷贝对象里的引用,直到子属性都为基本类型。两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。

slice()、concat、Array.from()、… 操作符:只能实现一维数组的深拷贝

Object.assign({}, obj):只能实现一维对象的深拷贝

JSON.parse(JSON.stringify(obj)):可实现多维对象的深拷贝,但会忽略

11. 箭头函数与普通函数的区别

  • 箭头函数是匿名函数,不能作为构造函数,不能使用new
  • 箭头函数不能绑定arguments,取而代之用rest参数解决
  • 箭头函数没有原型属性
  • 箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值

12. 绝对定位与相对定位

  • Absolution:元素会脱离文档流,定位是相对于离它最近的且不是static定位的父元素而言,若该元素没有设置宽度,则宽度由元素里面的内容决定,且宽度不会影响父元素,定位为absolution后,原来的位置相当于是空的,下面的的元素会来占据。

  • Relative:元素仍处于文档流中,定位是相对于原本自身的位置,若没有设置宽度,则宽度为父元素的宽度,该元素的大小会影响父元素的大小。

13. JavaScript是单线程的

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

所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。

为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。

14. 说一说 http 和 https

https的SSL加密是在传输层实现的

14.1 http和https的基本概念
  • http:超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP) ,用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。

  • https:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层, HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。

https协议的主要作用是:建立一个信息安全通道,来确保数组的传输,确保网站的真实性。

14.2 http和https的区别/h5>

http传输的数据都是未加密的,也就是明文的,网景公司设置了SSL协议来对http协议传输的数据进行加密处理,简单来说https协议是由http和ssl协议构建的可进行加密传输和身份认证的网络协议,比http协议的安全性更高。
主要的区别如下:

  • Https协议需要ca证书,费用较高。
  • http是超文本传输协议,信息是明文传输, https则是具有安全性的ssI加密传输协议。
  • 使用不同的链接方式,端口也不同,一般而言,http协议的端口为80,https的端口为443
  • http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
14.3 https协议的工作原理

客户端在使用HTTPS方式与Web服务器通信时 有以下几个步骤

客户使用https url 访问服务器,则要求web服务器建立ssI链接。
web服务器接收到客户端的请求之后,会将网站的证书(证书中包含了公钥)返回或者说传输给客户端。
客户端和web服务器端开始协商SSL链接的安全等级,也就是加密等级。
客户端浏览器通过双方协商一致的安全等级, 建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站。
web服务器通过自己的私钥解密出会话密钥。 web服务器通过会话密钥加密与客户端之间的通信。

14.4 https协议的优点

使用HTTPS协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;

HTTPS协议是由SSL+HTTP协议构建的可进行加密传输,身份证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取,改变,确保数据的完整性。

HTTPS是现行框架最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人的攻击成本。

谷歌曾在2014年8月份调整搜索算法,并称“比起同等HTTP网站,采用HTTPS加密的网站在搜索结果中的排名更高”。

14.5 https协议的缺点

https握手阶段比较费时,会使页面加载时间延长50%,增加10%~20%的耗电。

https缓存不如http高效,会增加数据开销。

SSL证书也需要钱,功能越大的证书费用越高。

SLL证书需要绑定IP ,不能再同一个ip绑定多个域名,ipv4资源支持不了这种消耗。

15. 为什么说 http 是无状态的

  • 协议的状态是指下一次传输可以“记住”这次传输信息的能力。
  • http是不会为了下一次连接而维护这次连接所传输的信息,为了保证服务器内存。
  • 比如客户获得一张网页之后关闭浏览器,然后再一次启动浏览器,再登录该网站,但是服务器并不知道客户关闭了一次浏览器。
  • 由于Web服务器要面对很多浏览器的并发访问,为了提高Web服务器对并发访问的处理能力,在设计HTTP协议时规定Web服务器发送HTTP应答报文和文档时,不保存发出请求的Web浏览器进程的任何状态信息。这有可能出现一个浏览器在短短几秒之内两次访问同一对象时,服务器进程不会因为已经给它发过应答报文而不接受第二期服务请求。由于Web服务器不保存发送请求的Web浏览器进程的任何信息,因此HTTP协议属于无状态协议(Stateless Protocol)。

Cookie是客户端的存储空间,由浏览器来维持具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案cookie和session起到保存客户端状态的作用,但是它们并没有改变http协议本身这种无状态的性质,可以理解为在应用上做了状态保留。

16. HTTP协议是无状态的和Connection: keep-alive的区别

  • 无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。
  • 是一个无状态的面向连接的协议,无状态不代表不能保持连接,更不能代表使用的是协议(无连接)。
  • 从起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。
  • 不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。

17. 简述flex-box布局

又叫弹性盒子布局。简单来说,它是一种CSS快速布局方式,相比于传统文档流布局方式,具有简洁、高效和响应式等优点。它主要在轴和容器(父容器和子容器)上做文章。

父容器可以设置子容器统一排列方式,主轴方向:justify-content,交叉轴方向:align-items。

主轴决定容器水平方向的排列,交叉轴决定容器垂直方向的排列,可以自定义主轴方向(上下左右),主轴沿逆时针旋转90°得到交叉轴。子容器可以设置自身排列方式。

元素水平垂直居中采用flex-box,相比于传统布局,就很简单

18. 简述babel的作用

babel是一个node命令行工具,它的作用是对我们源代码进行转码(把es6转为es5),因为有些浏览器不支持ES6语法的JavaScript代码

19. 生命周期函数的调用顺序

实例创建阶段

  • beforeCreate():在实例被完全创建出来之前执行,该函数执行时,data 和 methods 中的数据还没有被初始化
  • created():data 和 methods 已经被初始化好了
  • beforeMounte():表示模板已经在内存中编译完成了,但尚未渲染到页面中,页面中元素的内容还只是模板字符串
  • mounted():表示内存中的模板已经渲染到页面上了,用户已经可以看到渲染好的页面了

运行中的两个函数

  • beforeUpdate():表示页面还没有被更新(但数据已经更新了)
  • update():页面和 data 数据已经同步了,都是最新的

附上在各过程中父子组件的执行顺序

  • 加载渲染过程
  • 子组件更新过程
  • 父组件更新过程
  • 销毁过程

20. vue 组件交互的几种方式

20.1 props/$emit
  • 父组件向子组件传值:父组件通过 props 向下传递数据给子组件。

    父组件以属性绑定的形式传递到子组件内部,供子组件使用;子组件把父组件传递过来的属性,先在 props 数组中定义一下,这样才能使用这个数据

  • 子组件向父组件传值(通过事件形式):子组件通过events给父组件发送消息,实际上就是子组件把自己的数据发送到父组件

20.2 $emit / $on

这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级

20.3 vuex

Vuex实现了一个单向数据流,在全局拥有一个State存放数据,当组件要更改State中的数据时,必须通过Mutation进行,Mutation同时提供了订阅者模式供外部插件调用获取State数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走Action,但Action也是无法直接修改State的,还是需要通过Mutation来修改State的数据

vuex 是 vue 的状态管理器,存储的数据是响应式的。但是并不会保存起来,刷新之后就回到了初始状态,具体做法应该在vuex里数据改变的时候把数据拷贝一份保存到localStorage里面,刷新之后,如果localStorage里有保存的数据,取出来再替换store里的state。

20.4 $attrs / $listeners

多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此Vue2.4 版本提供了另一种方法—-/

与 是两个对象, 里存放的是父组件中绑定的非 Props 属性(class 和 style 除外),里存放的是父组件中绑定的(不含 .native 修饰器的) 非原生事件。

20.5 provide/inject

Vue2.2.0新增API,这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。一言而蔽之:祖先组件中通过provide来提供变量,然后在子孙组件中通过inject来注入变量。
provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系

20.6 $parent / $children与 ref
  • :如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
  • / :访问父 / 子实例

需要注意的是:这两种都是直接得到组件实例,使用后可以直接调用组件的方法或访问数据。

这两种方法的弊端是,无法在跨级或兄弟间通信

20.7 总结

常见使用场景可以分为三类:

  • 父子通信:

父向子传递数据是通过 props,子向父是通过 events();通过父链 / 子链也可以通信( / );ref 也可以访问组件实例;provide / inject API;

  • 兄弟通信:

Bus;Vuex

  • 跨级通信:

Bus;Vuex;provide / inject API、

21. 块级元素 行内元素的区别是什么了这两种还有哪些

  • 块级元素会独占一行,其宽度自动填满其父元素宽度;行内元素不会独占一行,相邻的行内元素会排列在同一行里,直到一行排不下,才会换行,其宽度随元素的内容而变化

  • 块级元素可以设置 width, height属性,行内元素设置width, height无效

  • 块级元素可以设置

    来源:search rm

    声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年1月16日
下一篇 2021年1月16日

相关推荐