前端知识点概览
0、底层
Event Loop事件循环:就是一个执行消息队列的机制
宏任务 微任务
为了解决这种情况,将任务分为了同步任务和异步任务;
而异步任务被分为两种,一种宏任务(MacroTask),一种叫微任务(MicroTask)
先执行宏任务再执行宏任务里面的微任务
宏任务:当前调用栈中执行的代码成为宏任务。(主代码快,定时器等等)。
微任务: 当前(此次事件循环中)宏任务执行完,在下一个宏任务开始之前需要执行的任务,可以理解为回调事件。(promise.then,proness.nextTick等等)。
宏任务中的事件放在callback queue中,由事件触发线程维护;微任务的事件放在微任务队列中,由js引擎线程维护
什么是EventLoop
结束本次宏任务 检查还有没有宏任务需要处理 这个检查的过程是持续进行的 每完成一个任务都会进行一次 而这样的操作就被称为Event Loop
在JavaScript中,任务被分为两种,一种宏任务(MacroTask)也叫Task,一种叫微任务(MicroTask)。
MacroTask(宏任务)
script全部代码、setTimeout、setInterval、setImmediate(浏览器暂时不支持,只有IE10支持,具体可见MDN)、I/O、UI Rendering。
MicroTask(微任务)
Process.nextTick(Node独有)、Promise、Object.observe(废弃)、MutationObserver(具体使用方式查看这里)
浏览器中的Event Loop
Javascript 有一个 main thread 主线程和 call-stack 调用栈(执行栈),所有的任务都会被放到调用栈等待主线程执行。
JS调用栈
JS调用栈采用的是后进先出的规则,当函数执行的时候,会被添加到栈的顶部,当执行栈执行完成后,就会从栈顶移出,直到栈内被清空。
0.1、什么是事件委托
事件委托是把子元素的事件委托给父元素去处理
好处:减少内存消耗和dom操作,提高性能
1、浅拷贝和深拷贝的区别
浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用
深拷贝是拷贝多层,每一层级的数据都会拷贝出来
1.1一段话赘述OOP编程思想
把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inherit)实现类的特化(specialization)与泛化(generalization),再通过多态(polymorphic)实现基于对象类型的动态分派(dynamic allocation)。
简述一下你理解的面向对象:
把一个对象的静态特征和动态特征抽象成属性和方法,也就是把一类事物的算法和数据结构封装在一个类之中,程序就是多个对象和互相之间的通信组成的
1.2、== 和 ===的区别
相同点:都是判定两个值是否相等
不同点:== 只比较值不比较类型,而 ===会判断类型
1.21浏览器通常用采用的垃圾回收有两种方法:标记清除、引用计数
1.3、JS有几种方法判断变量的类型?
typeof
判断基本数据类型,对于引用数据类型除了function返回’function‘,其余全部返回’object’。
instanceof
区分引用数据类型,检测方法是检测的类型在当前实例的原型链上,用其检测出来的结果都是true,不太适合用于简单数据类型的检测,检测过程繁琐且对于简单数据类型中的undefined, null, symbol检测不出来。
constructor
检测引用数据类型,检测方法是获取实例的构造函数判断和某个类是否相同,如果相同就说明该数据是符合那个数据类型的,这种方法不会把原型链上的其他类也加入进来,避免了原型链的干扰。
Object.prototype.toString.call()
适用于所有类型的判断检测,检测方法是Object.prototype.toString.call(数据) 返回的是该数据类型的字符串。(举例:字符串返回的是[object String])
1.4、数组操作方法会改变原数组
会改变:push(),pop(),shift(),unshift() ,splice(),sort(),reverse()。
不变:concat(),split(),slice()。
2、闭包:
(可以看看实例:https://www.cnblogs.com/heyushuo/p/9975911.html)
闭包的特点:可以读取函数内部变量,将函数内部变量的值始终保存在内存中,保护函数内的变量不被更改
用途:
使用闭包可以访问函数中的变量
可以使变量长期保存在内存中
闭包优缺点
作用:读取函数内部的函数,始终保持在内存中
优点:变量长期保持在内存中,不会清除,避免全局污染
缺点:增大内存使用,导致内存泄漏, 网页性能问题
3、如何区分冒泡与捕获
冒泡事件(false):是指子元素向父元素传递的过程
捕获事件(true):是指父元素向子元素传递的过程
4、rem em px的区别
rem css3新增的相对单位,相对于根节点html的字体大小来计算的
em:会继承父级元素的字体大小
px:像素的相对于显示器屏幕分辨率而言的
4.2、选择器的权重
! important - - - infinity
行间样式 - - - 1000
id 选择器 - - - 100
属性、伪类、类名选择器 - - - 10
标签选择器 - - - 1
通配符选择器 - - - 0
4.5、标准模型与怪异模型
标准模型:width + padding + border + margin
怪异模型:width(包含padding+border) + margin
4.6、box-sizing常用的属性有哪些?分别有什么作用?
(1)标准盒模型 box-sizing: content-box;
作用:
宽度和高度分别应用到元素的内容框。
在宽度和高度之外绘制元素的内边距和边框(元素默认效果)。
(2)IE盒模型 box-sizing: border-box;
作用:
元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。
通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。
(3)box-sizing: inherit;继承其父元素的box-sizing 属性的值
5、new操作符具体干了什么呢?
-
创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
-
属性和方法被加入到 this 引用的对象中。
-
新创建的对象由 this 所引用,并且最后隐式的返回 this 。
6、js的数据类型
简单数据类型:Number、String、Boolean、 undefined、object、Null
引用类型:Object Array Function
7、面向对象的特征:封装、继承、抽象、多态
8、vue的实现原理
vue是一个典型的MVVM框架,模型Model是js对象,修改它则视图VIEW自动更新。
vue实现双向数据绑定,需要三大模块:
Observer:能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
Compile:对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定想要的更新函数
Watcher:作为链接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图。
9、vue的生命周期
beforeCreate:组件实例刚被创建
created:组件实例创建完成,属性已绑定,但是DOM还未生成
beforeMount:模板编译
mounted:挂载
beforeUpdate:
updated:更新
beforeDestroy:实例销毁前
destroyed:销毁
10、防抖 :
(实例:https://www.cnblogs.com/momo798/p/9177767.html)
在某段时间内,不管你触发了多少次回调,我都只认最后一次。
a:如果在200ms内没有再次触发滚动事件,那么就执行函数
b:如果在200ms内再次触发滚动事件,那么当前的计时取消,重新开始计时
//防抖例子
functiondebounce(fn,wait){vartimer=null;returnfunction(){varcontext=this,args=arguments;// 如果此时存在定时器的话,则取消之前的定时器重新记时if(timer){clearTimeout(timer);timer=null;}// 设置定时器,使事件间隔指定事件后执行timer=setTimeout(()=>{fn.apply(context,args);},wait);};}
节流:在某段时间内,不管你触发了多少次回调,我都只认第一次,并在计时结束时给予响应。
// 函数节流的实现;functionthrottle(fn,delay){varpreTime=Date.now();returnfunction(){varcontext=this,args=arguments,nowTime=Date.now();// 如果两次时间间隔超过了指定时间,则执行函数。if(nowTime-preTime>=delay){preTime=Date.now();returnfn.apply(context,args);}};}
11、如何理解vue中MVVM模式?
MVVM全称是Model-View-ViewModel;
vue是以数据为驱动的,一旦创建dom和数据就保持同步,每当数据发生变化时,dom也会变化。DOMListeners和DataBindings是实现双向绑定的关键。
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 来统一管理。
12、Vue组件间的参数传递
1.父组件与子组件传值
父组件传给子组件:子组件通过props方法接受数据;
子组件传给父组件:$emit方法传递参数
2.非父子组件间的数据传递,兄弟组件传值
eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用VUEX,具体来说看需求咯。技术只是手段,目的达到才是王道。)
3、多级传值:provide和inject
4、其他用vuex
13、Vue的路由实现:hash模式 和 history模式
hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。
history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。
14、vue路由的钩子函数
首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。
beforeEach主要有3个参数to,from,next:
to:route即将进入的目标路由对象,
from:route当前导航正要离开的路由
next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。
15、vuex是什么?怎么使用?哪种功能场景使用它?
只用来读取的状态集中放在store中; 改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中。
在main.js引入store,注入。新建了一个目录store,….. export 。
场景有:单页应用中,组件之间的状态、音乐播放、登录状态、加入购物车
state
Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。
mutations
mutations定义的方法动态修改Vuex 的 store 中的状态或数据。
getters
类似vue的计算属性,主要用来过滤一些数据。
action
actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。
16、v-if 和 v-show 区别
答:v-if按照条件是否渲染,v-show是display的block或none;
17.computed和watch的区别
computed只有当页面数据变化时才会计算,当数据没有变化时,它会读取缓存。而watch每次都需要执行函数,methods也是每次都需要执行
数据变化时执行异步操作,这个时候使用watch是合适的
分别简述computed和watch的使用场景
computed:当一个属性受多个属性影响的时候就需要用到computed
最典型的例子: 购物车商品结算的时候
watch:当一条数据影响多条数据的时候就需要用watch
例子:搜索数据
18、vue的虚拟dom?
虚拟dom实例(https://www.cnblogs.com/fundebug/p/vue-virtual-dom.html)
虚拟的DOM的核心思想是:对复杂的文档DOM结构,提供一种方便的工具,进行最小化地DOM操作。
VNode是什么?虚拟 DOM是什么?
Vue在 页面上渲染的节点,及其子节点称为“虚拟节点 (Virtual Node)”,简写为“VNode”。“虚拟 DOM”是由 Vue 组件树建立起来的整个 VNode 树的称呼。
19、vue的优点是什么?
低耦合:视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可重用性:你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。
可测试:界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
20、在Vue中使用插件的步骤
采用ES6的import ... from ...语法或CommonJSd的require()方法引入插件
使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })
21、为什么避免 v-if 和 v-for 用在一起
当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,通过v-if 移动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,我们只检查它一次,且不会在 v-if 为否的时候运算 v-for
21.5vue的双向数据绑定原理是什么
vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的
核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法;
在数据渲染时使用prop渲染数据
将prop绑定到子组件自身的数据上,修改数据时修改自身数据来替代prop
watch子组件自身数据的改变,触发事件通知父组件更改绑定到prop的数据
这样做的好处是:父组件数据改变时,不会修改存储prop的子V组件数据,只是以子组件数据为媒介,完成对prop的双向修改。
21.6、vue-router有哪几种导航钩子
全局导航钩子:router.beforeEach,afterEach;
组件内的钩子:beforeRouteEnter,beforeRoutrupdate,beforeRouteLeave,
路由独享钩子:beforeEnter
21.7、vue内置的组件
component组件:有两个属性---is inline-template
渲染一个‘元组件’为动态组件,按照'is'特性的值来渲染成那个组件
2)transition组件:为组件的载入和切换提供动画效果,具有非常强的可定制性,支持16个属性和12个事件
3)transition-group:作为多个元素/组件的过渡效果
4)keep-alive:包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们
5)slot:作为组件模板之中的内容分发插槽,slot元素自身将被替换
21.8、vuex中的getters是干什么的
可以认为是 store 的计算属性。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
21.9、插槽的理解和使用:
https://www.cnblogs.com/mandy-dyf/p/11528505.html
22、网站性能优化
1.尽可能减少HTTP请求
2.使用雪碧图
3.css放在文件最上面防止白屏,闪动,js放在最下面
4.压缩js和css 去除不必要的注释 空格
5.合理使用缓存
6.使用CDN(内容分发网络)
23、什么是盒子模型
网页中的任何一个标签都相当于是一个盒子模型,而所有的盒子模型都存在五个必要的属性:width,height,padding,border,margin.
24、css的预处理器 sass/less
优点:变量,复用,嵌套,运算,继承
缺点:提高了门槛
25、DOM操作——怎样添加、移除、移动、复制、创建和查找节点。
(1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
(2)添加、移除、替换、插入
appendChild()
removeChild()
replaceChild()
insertBefore()
(3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
26、常见的http状态码
200 - 请求成功
301 - 资源(网页等)被永久转移到其它URL
403 - 服务器理解请求客户端的请求,但是拒绝执行此请求
404 - 请求的资源(网页等)不存在
500 - 内部服务器错误
开头为1,2的没有问题
3为重定向
4为客户端错误
5为服务器错误
27、什么是同源策略
所谓同源是指,域名,协议,端口相同。
28、如何防止xss攻击
XSS防御的总体思路是:对输入(和URL参数)进行过滤,对输出进行编码。
29、es6合并对象的方法(对象的属性值为基础类型:深拷贝;引用:浅拷贝)
assign()
1.作用:将多个对象{} 合并成一个独立对象。
2.使用方式: Object.assign(合并的对象,传入合并中的对象....)
let user = {name:'无敌人',age:19};
let page = {pageSize:10,currentPage:1};
let newObj = {};
Object.assign(newObj,user,page);
30、js中怎么知道一个东西是number、string、obj?
typeof运算符用于判断对象的类型,但是对于一些创建的对象,它们都会返回'object',有时我们需要判断该实例是否为某个对象的实例,那么这个时候需要用到instanceof运算符,后续记录instanceof运算符的相关用法。
实例:console.log(typeof(true)); //'boolean'
console.log(typeof '123'); //'string'
console.log(typeof 123); //'number'
console.log(typeof NaN); //'number'
31、promise(ES6)和async/await(ES7)的区别
两者都是做异步处理的;async的执行器与生俱来;
await 使异步转为同步,目的是临时阻塞后续的请求,等待promise,更好的语义化
Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
1)简洁的代码
使用async函数可以让代码简洁很多,不需要像Promise一样需要些then,不需要写匿名函数处理Promise的resolve值,也不需要定义多余的data变量,还避免了嵌套代码。
2) 错误处理:
Promise 中不能自定义使用 try/catch 进行错误捕获,但是在 Async/await 中可以像处理同步代码处理错误
错误栈
如过 Promise 连续调用,对于错误的处理是很麻烦的。你无法知道错误出在哪里。
使用await/async时,你不再需要那么多箭头函数,这样你就可以像调试同步代码一样跳过await语句。
32:js的作用域和作用域链
作用域:
全局作用域:
最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的:
局部作用域:
和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,最常见的例如函数内部
函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
作用域链:
根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问。
33、for of和for in的区别
在循环对象属性的时候,使用for...in,在遍历数组的时候的时候使用for...of。
for...in循环出的是key,for...of循环出的是value
34、如何创建BFC
根标签
float的值不为none
overflow 的值不为 visible
display 的值为 inline-block、table-cell、flex、table-caption或者inline-flex
position 的值为 absolute 或 fixed
35、csrf、xss攻击防御:
1、csrf同源策略:设置cookie的domain;
document.cookie = "username=Darren;path=/;domain=.csdn.net";
2、xss过滤
36、如何实现跨域
1、jsonp:实现简单兼容好,就是只支持get,容易遭到xss攻击;
2、最流行的跨域方案:cors;
3、最简单的nginx
37、一个完整的http过程
1、域名解析;
2、发起tcp三次握手;
3、建立tcp连接后发起http请求;
4、服务器响应http请求,浏览器得到html;
5、浏览器解析html,并请求html代码中的资源;
6、浏览器对页面进行渲染呈现给用户;(解析html构建dom树,构建render,布局render,绘制render)
38、Canvas与SVG的主要区别
从图像类别区分,Canvas是基于像素的位图,而SVG却是基于矢量图形。可以简单的把两者的区别看成photoshop与illustrator的区别。
从渲染模式上来说,Canvas属于 即时模式,而SVG则是 保留模式 ,这两种模式的区别可以参见 cshao 的博文: http://www.lifelaf.com/blog/?p=354。
从结构上说,Canvas没有图层的概念,所有的修改整个画布都要重新渲染,而SVG则可以对单独的标签进行修改。
从操作对象上说,Canvas是基于HTML canvas标签,通过宿主提供的Javascript API对整个画布进行操作的,而SVG则是基于XML元素的。
从功能上讲,SVG发布日期较早,所以功能相对Canvas比较完善。
关于动画,Canvas更适合做基于位图的动画,而SVG则适合图表的展示。关于SVG和Canvas的运行场景可参考MSCN关于 如何为您的网站在Canvas和SVG之间做出选择:
从搜索引擎角度分析,由于svg是有大量标签组成,所以可以通过给标签添加属性,便于爬虫搜索。
39、promise
console.log('here we go');
new Promise( resolve => {
setTimeout( () =>{
resolve('hello');
});
})
.then( value => {
console.log(value);
return new Promise( resolve => {
setTimeout( () => {
resolve('world')
})
})
})
.then( value => {
console.log(value+' world')
})
输出: here we go
输出:hello
输出:world world
40、日常工作中如何管理公共组件?
把公共组件发布到npmjs包管理官网,然后用npm install引入
41、JS的三种加载方式
正常模式
这种情况下 JS 会阻塞浏览器,浏览器必须等待 index.js 加载和执行完毕才能去做其它事情。