整理涵盖很全很广的前端知识点

JavaScript010

整理涵盖很全很广的前端知识点,第1张

HTML、CSS相关

html5新特性、语义化

浏览器渲染机制、重绘、重排

网页生成过程:

重排(也称回流): 当 DOM 的变化影响了元素的几何信息( DOM 对象的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。 触发:

重绘: 当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。 触发:

重排优化建议:

transform不重绘,不回流 是因为 transform 属于合成属性,对合成属性进行 transition/animate 动画时,将会创建一个合成层。这使得动画元素在一个独立的层中进行渲染。当元素的内容没有发生改变,就没有必要进行重绘。浏览器会通过重新复合来创建动画帧。

css盒子模型

所有 HTML 元素可以看作盒子,在CSS中, "box model" 这一术语是用来设计和布局时使用。CSS 盒模型本质上是一个盒子,封装周围的 HTML 元素,它包括:边距,边框,填充,和实际内容。 盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。

css样式优先级

!important>style>id>class

什么是BFC?BFC的布局规则是什么?如何创建BFC?BFC应用?

BFC是Block Formatting Context的缩写,即块格式化上下文。 BFC 是CSS布局的一个概念,是一个环境,里面的元素不会影响外面的元素。 布局规则:Box是CSS布局的对象和基本单位,页面是由若干个Box组成的。元素的类型和display属性,决定了这个Box的类型。不同类型的Box会参与不同的 Formatting Context 。 创建:浮动元素display:inline-block position:absolute应用: 1.分属于不同的 BFC 时,可以防止 margin 重叠 2.清除内部浮动 3.自适应多栏布局

DOM、BOM对象

BOM(Browser Object Model) 是指浏览器对象模型,可以对浏览器窗口进行访问和操作。使用 BOM,开发者可以移动窗口、改变状态栏中的文本以及执行其他与页面内容不直接相关的动作。 使JavaScript有能力与浏览器"对话"。DOM (Document Object Model) 是指文档对象模型,通过它,可以访问 HTML 文档的所有元素。DOM是W3C (万维网联盟)的标准。 DOM定义了访问HTML和XML文档的标准: "W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。"W3C DOM标准被分为 3 个不同的部分:

什么是XML DOM ?XML DOM定义了所有 XML 元素的对象和属性,以及访问它们的方法。 什么是 HTML DOM? HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。

JS相关

js数据类型、typeof、instanceof、类型转换

闭包(高频)

闭包是指有权访问另一个函数作用域中的变量的函数 ——《JavaScript高级程序设计》

当函数可以记住并访问所在的词法作用域时,就产生了闭包,

即使函数是在当前词法作用域之外执行 ——《你不知道的JavaScript》

原型、原型链(高频)

原型: 对象中固有的 __proto__ 属性,该属性指向对象的 prototype 原型属性。

原型链: 当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是 Object.prototype 所以这就是我们新建的对象为什么能够使用 toString() 等方法的原因。

特点: JavaScript 对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。

this指向、new关键字

this 对象是是执行上下文中的一个属性,它指向最后一次调用这个方法的对象,在全局函数中, this 等于 window ,而当函数被作为某个对象调用时,this等于那个对象。 在实际开发中, this的指向可以通过四种调用模式来判断。

new

作用域、作用域链、变量提升

继承(含es6)、多种继承方式

(1)第一种是以 原型链的方式来实现继承 ,但是这种实现方式存在的缺点是,在包含有引用类型的数据时,会被所有的实例对象所共享,容易造成修改的混乱。还有就是在创建子类型的时候不能向超类型传递参数。

(2)第二种方式是使用 借用构造函数 的方式,这种方式是通过在子类型的函数中调用超类型的构造函数来实现的,这一种方法解决了不能向超类型传递参数的缺点,但是它存在的一个问题就是无法实现函数方法的复用,并且超类型原型定义的方法子类型也没有办法访问到。

(3)第三种方式是 组合继承 ,组合继承是将原型链和借用构造函数组合起来使用的一种方式。通过借用构造函数的方式来实现类型的属性的继承,通过将子类型的原型设置为超类型的实例来实现方法的继承。这种方式解决了上面的两种模式单独使用时的问题,但是由于我们是以超类型的实例来作为子类型的原型,所以调用了两次超类的构造函数,造成了子类型的原型中多了很多不必要的属性。

(4)第四种方式是 原型式继承 ,原型式继承的主要思路就是基于已有的对象来创建新的对象,实现的原理是,向函数中传入一个对象,然后返回一个以这个对象为原型的对象。这种继承的思路主要不是为了实现创造一种新的类型,只是对某个对象实现一种简单继承,ES5 中定义的 Object.create() 方法就是原型式继承的实现。缺点与原型链方式相同。

(5)第五种方式是 寄生式继承 ,寄生式继承的思路是创建一个用于封装继承过程的函数,通过传入一个对象,然后复制一个对象的副本,然后对象进行扩展,最后返回这个对象。这个扩展的过程就可以理解是一种继承。这种继承的优点就是对一个简单对象实现继承,如果这个对象不是我们的自定义类型时。缺点是没有办法实现函数的复用。

(6)第六种方式是 寄生式组合继承 ,组合继承的缺点就是使用超类型的实例做为子类型的原型,导致添加了不必要的原型属性。寄生式组合继承的方式是使用超类型的原型的副本来作为子类型的原型,这样就避免了创建不必要的属性。

EventLoop

JS 是单线程的,为了防止一个函数执行时间过长阻塞后面的代码,所以会先将同步代码压入执行栈中,依次执行,将异步代码推入异步队列,异步队列又分为宏任务队列和微任务队列,因为宏任务队列的执行时间较长,所以微任务队列要优先于宏任务队列。微任务队列的代表就是, Promise.then , MutationObserver ,宏任务的话就是 setImmediate setTimeout setInterval

原生ajax

ajax 是一种异步通信的方法,从服务端获取数据,达到局部刷新页面的效果。 过程:

事件冒泡、捕获(委托)

event.stopPropagation()或者 ie下的方法event.cancelBubble = true //阻止事件冒泡

ES6

Vue

简述MVVM

MVVM 是 Model-View-ViewModel 缩写,也就是把 MVC 中的 Controller 演变成 ViewModel。Model 层代表数据模型, View 代表UI组件, ViewModel 是 View 和 Model 层的桥梁,数据会绑定到 viewModel 层并自动将数据渲染到页面中,视图变化的时候会通知 viewModel 层更新数据。

谈谈对vue生命周期的理解?

每个 Vue 实例在创建时都会经过一系列的初始化过程, vue 的生命周期钩子,就是说在达到某一阶段或条件时去触发的函数,目的就是为了完成一些动作或者事件

computed与watch

watch 属性监听 是一个对象,键是需要观察的属性,值是对应回调函数,主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,监听属性的变化,需要在数据变化时执行异步或开销较大的操作时使用

computed 计算属性 属性的结果会被缓存,当 computed 中的函数所依赖的属性没有发生改变的时候,那么调用当前函数的时候结果会从缓存中读取。除非依赖的响应式属性变化时才会重新计算,主要当做属性来使用computed 中的函数必须用 return 返回最终的结果computed 更高效,优先使用

使用场景 computed :当一个属性受多个属性影响的时候使用,例:购物车商品结算功能watch :当一条数据影响多条数据的时候使用,例:搜索数据

v-for中key的作用

vue组件的通信方式

父子组件通信

父->子 props ,子->父$on、$emit` 获取父子组件实例parent、 parent 、children Ref获取实例的方式调用组件的属性或者方法Provide、inject` 官方不推荐使用,但是写组件库时很常用

兄弟组件通信

Event Bus实现跨组件通信Vue.prototype.$bus = new Vue() Vuex

跨级组件通信

$attrs、$listeners Provide、inject

常用指令

双向绑定实现原理

当一个 Vue 实例创建时,Vue会遍历data选项的属性,用 Object.defineProperty 将它们转为 getter/setter并且在内部追踪相关依赖,在属性被访问和修改时通知变化。每个组件实例都有相应的 watcher 程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher重新计算,从而致使它关联的组件得以更新。

v-model的实现以及它的实现原理吗?

nextTick的实现

vnode的理解,compiler和patch的过程

new Vue后整个的流程

思考:为什么先注入再提供呢??

答:1、首先来自祖辈的数据要和当前实例的data,等判重,相结合,所以注入数据的initInjections一定要在 InitState 的上面。2. 从上面注入进来的东西在当前组件中转了一下又提供给后代了,所以注入数据也一定要在上面。

vm.[Math Processing Error]mount(vm.mount(vm.options.el) :挂载实例。

keep-alive的实现

作用:实现组件缓存

钩子函数:

原理: Vue.js 内部将 DOM 节点抽象成了一个个的 VNode 节点, keep-alive 组件的缓存也是基于 VNode 节点的而不是直接存储 DOM 结构。它将满足条件 (pruneCache与pruneCache) 的组件在 cache 对象中缓存起来,在需要重新渲染的时候再将 vnode 节点从 cache 对象中取出并渲染。

配置属性:

include字符串或正则表达式。只有名称匹配的组件会被缓存

exclude字符串或正则表达式。任何名称匹配的组件都不会被缓存

max数字、最多可以缓存多少组件实例

vuex、vue-router实现原理

vuex 是一个专门为vue.js应用程序开发的状态管理库。 核心概念:

你怎么理解Vue中的diff算法?

在js中,渲染真实 DOM 的开销是非常大的, 比如我们修改了某个数据,如果直接渲染到真实 DOM , 会引起整个 dom 树的重绘和重排。那么有没有可能实现只更新我们修改的那一小块dom而不要更新整个 dom 呢?此时我们就需要先根据真实 dom 生成虚拟 dom , 当虚拟 dom 某个节点的数据改变后会生成有一个新的 Vnode , 然后新的 Vnode 和旧的 Vnode 作比较,发现有不一样的地方就直接修改在真实DOM上,然后使旧的 Vnode 的值为新的 Vnode 。

diff 的过程就是调用 patch 函数,比较新旧节点,一边比较一边给真实的 DOM 打补丁。在采取 diff 算法比较新旧节点的时候,比较只会在同层级进行。 在 patch 方法中,首先进行树级别的比较new Vnode 不存在就删除old Vnode old Vnode不存在就增加新的 Vnode都存在就执行diff更新 当确定需要执行diff算法时,比较两个 Vnode ,包括三种类型操作:属性更新,文本更新,子节点更新 新老节点均有子节点,则对子节点进行 diff 操作,调用 updatechidren如果老节点没有子节点而新节点有子节点,先清空老节点的文本内容,然后为其新增子节点 如果新节点没有子节点,而老节点有子节点的时候,则移除该节点的所有子节点 老新老节点都没有子节点的时候,进行文本的替换

updateChildren 将 Vnode 的子节点Vch和oldVnode的子节点oldCh提取出来。oldCh和vCh 各有两个头尾的变量 StartIdx和EndIdx ,它们的2个变量相互比较,一共有4种比较方式。如果4种比较都没匹配,如果设置了 key ,就会用 key 进行比较,在比较的过程中,变量会往中间靠,一旦 StartIdx>EndIdx 表明 oldCh和vCh 至少有一个已经遍历完了,就会结束比较。

你都做过哪些Vue的性能优化?

你知道Vue3有哪些新特性吗?它们会带来什么影响?

更小巧、更快速 支持自定义渲染器 支持摇树优化:一种在打包时去除无用代码的优化手段 支持Fragments和跨组件渲染

模板语法99%保持不变 原生支持基于class的组件,并且无需借助任何编译及各种stage阶段的特性 在设计时也考虑TypeScript的类型推断特性重写虚拟DOM 可以期待更多的编译时提示来减少运行时的开销优化插槽生成 可以单独渲染父组件和子组件静态树提升 降低渲染成本基于Proxy的观察者机制 节省内存开销

检测机制 更加全面、精准、高效,更具可调试式的响应跟踪

实现双向绑定 Proxy 与 Object.defineProperty 相比优劣如何?

React

1、react中key的作用,有key没key有什么区别,比较同一层级节点什么意思?

2、你对虚拟dom和diff算法的理解,实现render函数

虚拟DOM 本质上是 JavaScript 对象,是对 真实DOM 的抽象表现。 状态变更时,记录新树和旧树的差异 最后把差异更新到真正的 dom 中 render函数:

3、React组件之间通信方式?

Context提供了一个无需为每层组件手动添加props ,就能在组件树间进行数据传递的方法.如果你只是想避免层层传递一些属性,组件组合( component composition )有时候是一个比 context 更好的解决方案。 5. 组件组合缺点:会使高层组件变得复杂

4、如何解析jsx

5、生命周期都有哪几种,分别是在什么阶段做哪些事情?为什么要废弃一些生命周期?

componentWillMount、componentWillReceiveProps、componentWillUpdate在16版本被废弃,在17版本将被删除,需要使用UNSAVE_前缀使用,目的是向下兼容。

6、关于react的优化方法

使用return null而不是CSS的display:none来控制节点的显示隐藏。保证同一时间页面的DOM节点尽可能的少。

不要使用数组下标作为key 利用shouldComponentUpdate和PureComponent避免过多render function render 里面尽量减少新建变量和bind函数,传递参数是尽量减少传递参数的数量。 尽量将props和state扁平化,只传递component需要的props (传得太多,或者层次传得太深,都会加重 shouldComponentUpdate 里面的数据比较负担),慎将component当作props传入

使用babel-plugin-import优化业务组件的引入,实现按需加载 使用SplitChunksPlugin拆分公共代码 使用动态import ,懒加载React组件

7、绑定this的几种方式

8、对fiber的理解

9、setState是同步还是异步的

10、Redux、React-Redux

Redux的实现流程

用户页面行为触发一个 Action ,然后 Store 调用 Reducer ,并且传入两个参数:当前 State 和收到的 Action 。 Reducer 会返回新的 State 。每当 state 更新之后, view 会根据 state 触发重新渲染。

React-Redux:

Provider :从最外部封装了整个应用,并向 connect 模块传递 store 。Connect :

11、对高阶组件的理解

高阶组件是参数为组件,返回值为新组件的函数。 HOC 是纯函数,没有副作用。 HOC 在 React 的第三方库中很常见,例如 Redux 的 connect 组件。

高阶组件的作用:

12、可以用哪些方式创建 React 组件?

React.createClass()、ES6 class 和无状态函数

13、 React 元素与组件的区别?

组件是由元素构成的。元素数据结构是普通对象,而组件数据结构是类或纯函数。

Vue与React对比?

数据流:

react 主张函数式编程,所以推崇纯组件,数据不可变,单向数据流,

vue 的思想是响应式的,也就是基于是数据可变的,通过对每一个属性建立Watcher来监听,当属性变化的时候,响应式的更新对应的虚拟dom。

监听数据变化实现原理

组件通信的区别:jsx和.vue模板。

性能优化

vuex 和 redux 之间的区别?

从实现原理上来说,最大的区别是两点:

Redux 使用的是不可变数据,而 Vuex 的数据是可变的。 Redux 每次都是用新的 state 替换旧的 state ,而 Vuex 是直接修改

Redux 在检测数据变化的时候,是通过 diff 的方式比较差异的,而 Vuex 其实和Vue的原理一样,是通过getter/setter 来比较的(如果看 Vuex 源码会知道,其实他内部直接创建一个 Vue 实例用来跟踪数据变化)

浏览器从输入url到渲染页面,发生了什么?

网络安全、HTTP协议

TCP UDP 区别

Http和Https区别(高频)

GET和POST区别(高频)

理解xss,csrf,ddos攻击原理以及避免方式

XSS ( Cross-Site Scripting , 跨站脚本攻击 )是一种代码注入攻击。攻击者在目标网站上注入恶意代码,当被攻击者登陆网站时就会执行这些恶意代码,这些脚本可以读取cookie,session tokens ,或者其它敏感的网站信息,对用户进行钓鱼欺诈,甚至发起蠕虫攻击等。

CSRF ( Cross-site request forgery ) 跨站请求伪造 :攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

XSS避免方式:

CSRF 避免方式:

DDoS 又叫分布式拒绝服务,全称Distributed Denial of Service ,其原理就是利用大量的请求造成资源过载,导致服务不可用。

我认为的2020年前端开发者最应该掌握的一些比较火爆的技术与知识点。

1,前端框架和语言层面

9月份 Vue3.0 发布,声称对 TypeScript 有着更好的开发体验,通过从不同框架级别 TS 支持上,我们可以看出社区的整个风向从2019年的大家都去学习应用 TS,变成了大家如何把 TS 用的更好这个方向上来了。

所以我认为今年 TypeScript 的火热程度还是应该排名很靠前的,我今年也使用 TypeScript 重构了 Daruk 的服务框架推出了2.0版本,让 TS 开发者拥有更好的 TS 开发体验。

接下来就是两大重磅框架的更新历程对比,Vue3 前面说了一句。而 React 也在十月也发布了 React 17 的 release 版本。这两大主流框架的频繁更新,也说明了社区和作者都在一同演化。

在 Vue 3中除了更好的支持 TS 外,还更新了Composition API。而 React 17 主要是集中精力在升级体验上,虽然没有新的 Feature 但是提升了和解决了很多之前版本潜在的问题。

要说哪个最火还是要看个人实际的使用场景和喜好,但是2020年来看还没有别的框架可以与之一战。

         

            2,大前端相关技术栈

今年基于Chromium的微软edge浏览器也已经推出。google 在 web 端的发展产生了对开发者深刻的影响。Chrome 80+ 也已经发布多个版本,提供了一系列的新特性,比如Core Web Vitals标准,Desktop PWA等都值得我们去关注。

         

            我们说完了浏览器相关的那点技术之后,再聊聊大前端相关的一些技术实践,比如 Flutter。

很多前端在今年已经从 web 开发转型为 Flutter 开发,学习和使用 Dart 技术来构建 UI,这是很多大厂的前端工程师正在经历的事情(包括我的部门也在尝试这个事情),这个趋势应该在未来几年还会持续。

客户端 electron 在今年也有着长足的进展,一年内多次更新版本一路到了10.1.5。随着疫情影响,国内在线教育的又一波兴起。很多桌面软件,网课软件都在采用这个技术来进行开发,市场上的岗位也开始变多,electron 技术可以说在今年也有火的趋势。

         

            然后我们再看看BFF 层,nestjs依然坚挺,越来越多的人开始跳过学习 express 和 koa 开始学习更丰富的 web 框架了,比如 egg 或者我的 daruk,开发者已经在慢慢形成共识,在 web framework 的路上开始越走越远,裸写 nodejs web 服务的时代已经开始慢慢褪去。

         

            不得不提的还有 serverless 在前端的普及,在2020年到达了一个新的高潮。阿里云,腾讯云,头条云等等国内的互联网厂商也都开始大玩 serverless 概念。从对内服务开始转向对外服务,普及的势头很猛,也有落地的趋势和场景。今年的 D2同样也有 serverless 的专场,可见受重视程度非比寻常。

3,工程化提效和个人素质提升

再离我们近一些的推动生产力的技术,比如据我所知在用 CI/CD 和 pipeline 管理上线流程的公司越来越多,这种去年还可以出去吹一吹的东西,今年也逐步变成了业界标配基础能力,如果不会的同学可要抓紧学习了。

         

            2019年前大家都疯狂吐槽面试刷 medium 题目没用,而2020年后大家开始默认面试某些公司都至少要刷到medium程度的题目。这对很多前端来说是一个心智和素质的提升与转变,大家在接触新技术的同时,也慢慢发现,前端整个职业环境的变化,越来越多的公司对人的整体综合素质要求变高了。