2019前端面试复习总结

2019前端面试复习总结

1、 js的运行机制

同步和异步

js是单线程的语言,但它既能执行同步任务,又能执行异步任务。首先,它有一个主线程,所有的同步任务都放在主线程的执行栈中执行,主线程里一段事件内只能做一件事。它还有一个任务队列,所有的异步任务不会直接放入主线程中,而是先进入任务队列,每当某一个异步任务执行完成之后,会在任务队列中添加一个事件。当主线程中所有的异步任务执行完成,系统会自动读取任务队列有哪些事件,并且事件对应的方法放入主线程的执行栈中执行。并且不断的重复这个过程,这个过程也叫做event loop(事件循环)。js中的定时器、dom事件、promise都是异步任务。

并发和并行

并发是个宏观的概念,表示由一个核心在一段时间内通过任务间的切换完成多个任务的一种方式。

并行是一个宏观的概念,表示由多个核心同时完成多个任务的方式称之为并行。

回调函数与回调地狱

在某一个方法的参数里放一个函数,这个函数就称之为回调函。

回调地狱,就是回调函数里又调用方法,方法的参数里又放函数。

回调地狱的根本问题

1、嵌套函数存在耦合性,一旦有所改动,就会牵一发而动全身,影响后面的代码执行。 2、嵌套函数一多,就很难定位和处理错误。

2、js常见的数据类型

原始数据类型

string、boolean、number、null、undefined、symbol(es6新增的类型,特点为一但定义无法更改,适合用来作为对象的属性名,使其在上游定义的属性不会在下游被覆盖掉,还有一个symbol()方法可以将其他类型转为symbol型)

复杂数据类型

object、array

两者区别

原始类型存储的是值,复杂类型存储的是指针,原始数据类型赋值给另一个变量,原来的数据修改了,另一个变量不会修改。复杂数据类型赋值给另外一个变量,实际上是将指针赋值给了另一个变量,指针对应的数据并没有复制,所以当原值修改时,变量也会修改,变量的值修改,原值也会修改。

浅拷贝、深拷贝

浅拷贝用来解决对象第一层的复制问题

	let a={age:1}
	let b=Object.assign({},a)//方法1,assign
	let c={...a}//方法2,es6的展开运算符
复制代码

深拷贝是复制一个复杂数据类型下面所有层级的所有数据

方法1

	let a={age:1}
	let b=JSON.parse(JSON.stringify(a))
复制代码

方法2

MessageChannel

原型链

对象都有原型,原型也是对象,原型也有原型,这样就构成了一个对象的序列,就叫原型链

3、vue知识点

数据驱动(两大核心之一)

数据驱动,既视图是由数据生成的,我们要修改试图不需要修改dom,而是只需要修改数据,相比于传统的修改dom,大大的减少了代码量。特别是当交互特别复杂的时候,只关注数据的修改会让代码的逻辑变得非常清晰,因为dom是对数据的映射,所有逻辑都是对数据的修改,而不用触碰dom,这样特别有利于代码的维护。数据驱动的原理是依赖收集的观测机制,vue在实例化过程中,会遍历传给实例化对象的data选项 ,遍历其所有的属性,并使用Object.definedPropety给这些属性添加set和get方法。同时每一个实例对象都有一个watcher实例对象。它会在模板编译过程中用get方法去访问data属性,watcher此时就会报用到的data属性记为依赖,这样就建立了视图和数据之间的联系。当之后我们渲染视图的依赖 发生改变(既数据的set方法被调用)的时候。watcher会对比前后两个数值是否发生变化,然后通知视图确定是否进行渲染,这样就实现了所谓的数据对视图的驱动。

组件系统(两大核心之一)

组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。组件需要注册后才可以使用,注册有全局注册和局部注册两种方式。组件的创建是新创建一个vue文件,template写html代码,script写js代码,style写css代码。

生命周期钩子

主流程钩子:beforeCreated(data和props中数据访问不到),created(可以拿到data和props中的数据),beforeMount(创建虚拟dom,还拿不到dom节点),mounted(渲染真实dom,可以拿到dom节点了),beforeDestory(销毁事件和方法),destoryed(递归销毁所有组件)。

数据更新钩子:beforeUpdata(数据更新时执行),updata(数据更新完时执行)

缓存keep-alive特有的钩子:beforeActived(缓存页面时执行),actived(渲染缓存页面时执行)

组件通信

父子通信:

父传子,首先在子组件的props中定义好数据名,父组件template的子组件标签中用v-bind绑定数据名=值,这个值就能在子组件中通过this获取到了,如果要做成实时触发的可以在子组件中用watch对props的值进行监控,并且实时赋值给本组件的变量。

子传父,在子组件的方法中用$emit方法通过事件名,事件值的方式传出,父组件在template的子组件标签中用@子组件中设置的事件名=方法,在这个方法的返回值中就可以拿到子组件传出来的值。

兄弟组件通信:

通常用vuex,首先在state中配置好数据名,再设置set方法和get方法,在获取或者修改值的时候,用get和set方法操作就行了。还有一种evenBus,是通过同时导入同一个js文件做中转的方式。

vue中computed和watch的区别

computed是计算属性,依赖其他属性计算值,并且computed的值有缓存,只有当计算值变化才会返回内容。

watch是只要监听到值的变化就会执行回调,在回调中可以进行一些逻辑操作。

一般来说需要依赖别的属性来动态获取值的时候可以使用computed,对于监听到值的变化需要做一些复杂业务逻辑的情况可以使用watch。

keep-alive的作用

如果你需要在组件切换的时候,保存一些组件的状态,防止多次渲染,就可以使用keep-alive包裹需要保存的组件,最常用的就是前进刷新,后退不刷新及保留滚动位置。

mixin和mixins

mixin用于全局混入,会影响到每个组件实例,可以用来做初始化,及封装全局的工具函数等。

mixins是我们最常用的扩展组件的方式,如果多个组件有相同的业务逻辑,就可以将这些逻辑抽离出来,通过mixins混入代码,比如上下拉加载数据这种逻辑。

另外需要注意的是mixins混入的钩子函数会先于组内的钩子函数执行,并且在遇到同名选项时也会有选择性的进行合并。

4、ES6常见知识点

变量提升

js中函数的声明及var变量的声明都存在提升的概念,既变量名及函数的声明会被提升到作用域最顶端。提升存在的根本原因是解决函数间相互调用的问题。es6新的的定义方式const和let不会被变量提升,并且不会挂在到windows中,不会被变量提升的原因是存在暂时性死区。let和const的作用基本上一致,只是let声明的是变量后面可以改,const声明的是常量,后面不能修改。

暂时性死区:简称TDZ,当程序的控制流程在新的作用域进行实例化时,在此作用域中用let或const声明的变量会先在作用域中创建出来,当此时因为还未进行词法绑定,也就是对声明语句进行求值运算,所以是不能访问的,访问就会报错,所以在运行流程一进入作用域创建变量,到变量开始可以被访问这一阶段时间称之为暂时性死区。

常用数组方法

map:作用是生成一个新数组,遍历原数组,将每个元素拿出来做一些变化然后放入到新的数组中

	var data = [1,2,3]
	var fn = data.map((res,i)=>{
		return res*res
	})
	console.log(fn)//1,4,9
复制代码

filter:作用也是生成一个新数组,在遍历数组的时候将返回值为true的元素放入到新数组,可以利用这个方法删除一些不需要的元素

	var data = [1,2,3]
	var fn = data.filter((res,i)=>{
		return res!=3
	})
	console.log(fn)//1,2
复制代码

reduce:作用是将数组中的元素通过回调函数最终转化为一个值。reduce接受两个参数,第一个是回调函数,第二个是初始值,首先初始值为0,该值会在执行第一次回调函数时作为第一个参数传入,回调函数接收四个参数,分别为累计值、当前元素、当前索引、原数组。在一个执行回调函数时,当前值和初始值相加得出的结果,会在第二次执行回调函数时作为第一个参数传入。

	const arr=[1,2,3]
	const sum = arr.reduce((acc,current)=>{
		acc+current
	},0)
	console.log(sum)//6
复制代码
promise

解决异步问题的一种方式,英文单词是承诺的意思,这个承诺在未来一定有一个确定的结果,要么完成、要么拒绝,加上执行的等待一共三种状态。

padding 等待中    resolve 完成      rejected 拒绝
复制代码

这个承诺一旦从等待状态变为其他状态就永远不能更改状态了。

当我们在构造promise方法prommise时,构造函数内部的代码是立即执行的,只有遇到resolve方法或者reject方法才会跳出构造函数。

	new Promise ((resolve,reject)=>{
		console.log("new proimse");
		resolve();
	})
复制代码

promise实现了链式调用,也就是说每次调用then之后返回的状态都是一个promise,并且是一个全新的promise,原因也是因为状态不可变。如果你在then中使用了return,那么return的值会被promise.resolve()包装。

	promise.resolve(1).then(res=>{
		console.log(res) //1
		retrun 2;//和 promise.resolve(2)作用一样
	}).then(res=>{
		console.log(res)//2
	})
复制代码

promise解决了回调地狱的问题,以链式调用的方式替换方法的回调嵌入方法回调的方式。缺点是无法取消promise,错误需要通过回调函数捕获。

原型继承和class继承
组合继承

在子类的函数体中通过parent.call(this)继承父类的属性,然后改变子类的原型child.prototype为new Parent()来继承父类的方法。这种方法的优点是构造函数可以传参,不会与父类引用的属性共享,可以服用父类的函数,缺点是在继承父类函数的时候调用了父类的构造函数,导致子类的原型上多了不需要的父类属性,存在内存上的浪费。

寄生组合继承

是对组合继承的优化,具体为在继承父类函数的时候,不要再直接改变子类原型child.prototype为new Parent(),而是将父类的原型赋值给了子类,并且将构造函数设置为子类。

class继承

class实现继承的核心在于使用extend是表明继承自那个父类,并且在子类构造函数中必须调用super

5、打包工具webpack

webpack4和3相比优化了那些地方

1、优化了打包速度,webpack4比3的打包时间要减少60%左右。

2、新增了一个mode配置,作用是为我们减少生产环境构建体积,以及节约开发环境构建时间提供的一种优化方案。

3、实现了零配置平台来扩展。

4、废弃了CommonsChunkPlugin,并且使用一些默认值以及更容易被复写的新API optiomize.SplitChunks来代替它。

5、webpack现默认支持在任何本地webAssembly模块中的import和export语句。

状态码及其含义

1xx:请求已被服务器接收到,正在处理中 2xx:请求已被服务器接收、理解并接受 3xx:请求需要进行重定向 4xx:请求失败,并妨碍了服务器进程 5xx:请求出现异常,服务器无法处理

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值