前端面试题JS-H5-VUE - Go语言中文社区

前端面试题JS-H5-VUE


前端面试题

总结

H5:Video.js、PDF.js 、canvas、localStorage、sessionStorage、localStorage跨页面通信、manifest、拖放
CSS3:哪些样式可继承,行内元素,非行内元素,动画等
DOM:节流,重排重绘,防抖
http协议:302、304、304的解决方法、403、404、500、
继承、原型链、数组API,字符串API、Object.difineProperty
UI设计图进行还原:像素还原,比例还原
不同屏幕适配:媒体查询:print、screen、speech、min-width

原型链原理

构造函数的原型分配的函数是所有对象共享的。
原型是什么:一个对象,我们也称prototype为原型对象
原型的作用:共享方法
img

对象原型 ——proto——

对象都有一个属性——proto——,指向它的构造函数的prototype
——proto——对象原型和原型对象prototype是等价的

原型链

js的成员查找机制
​ 1 当访问一个对象的属性和方法的时,首先查找这个对象自身有没有该属性
​ 2 如果没有就查找它的原型(——proto——指向prototype)
​ 3 如果还没有,就去找prototype的原型(object的原型对象)
​ 4 一直查找到Object为止(null)

JS中new和Object.create()区别

new
function Animal(){}
var animal = new Animal();
new运算符会在执行的时候将Animal.prototype赋值给animal.prototype

Object.create()
Object.create(proto, [ propertiesObject ])
//proto是原型对象
//propertiesObject是属性的配置
function Animal(name){
    this.name = name;
}
var animal = new Animal("test");

var createAnimal1 = Object.create(Animal.prototype);
var createAnimal2 = Object.create(animal);
var createAnimal3 = Object.create(null);

console.log(createAnimal1.name) // 输出为 undefined
console.log(createAnimal2.name) //输出为 test
console.log(createAnimal3) // 输出为 {}
//你可以任意指定对象的原型对象

new操作符会将那样构造函数的prototype指定的原型对象赋值给新对象的Prototype,Object.create将参数proto指定的原型对象赋值给新对象的Prototype

如果参数为null的话,Object.create则会创建空对象。

特别需要指出的是Object.create(null)和new Object()的区别:两者都是创建空对象,但是new创建出的空对象会绑定Object的prototype原型对象,但是Object.create(null)的空对象是没有任何属性的。

js的继承
原型链继承:子类的prototype指向父类的实例
构造函数继承:把父类当成普通函数在子类中使用, 并改变this指向
组合继承:把原型链继承和构造函数继承结合
寄生虫继承,使用组合继承的时候,采取立即调用函数来完成
class语法糖继承

JS的this理解,如何改变this的指向
this的理解:
this就是指函数在运行时,所在的环境(即调用的对象)
this的绑定:this实际上是在函数被调用时发生的绑定,它指向什么地方完全取决于函数在哪里被调用
this碰到return时,返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么this还是指向函数的实例
在严格版中的默认的this不再是window,而是undefined
改变this指向
通过call,apply,bind三种方法
call,apply,调用时修改this指向,区别,call传递参数时一个一个的传递,而apply传递参数时通过数组传递
bind是在创建函数的时候使用

intanceof和typeof区别
typeof用以获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果: number,boolean,string,function(函数),object(NULL,数组,对象),undefined
​typeof遇到null,数组,对象时都会返回object类型,所以当我们要判断一个对象是否是数组时或者判断某个变量是否是某个对象的实例则要选择使用另一个关键语法instanceof

什么情况下,——proto——和prototype指向是同一个
实例的——proto——和构造函数的prototype指向同一对象

重排

DOM的变化影响到了元素的宽高,导致浏览器要重新计算元素的宽高(影响到页面布局),甚至影响到渲染数中的某些部分就需要重新渲染,改变窗口大小、文字大小、内容变化、浏览器窗口大小、style属性的改变等会导致重排。

重绘

一个元素的外观发生了改变,但是没有改变元素的宽高,比如改变元素的背景色、outline、visibility等会导致重绘。

重排必定会引发重绘,但重绘不一定会引发重排。

JS宏观任务和微观任务

在这里插入图片描述
宏观任务:宿主发起的任务为宏观任务,如setTimeout、setInterval、setImmediate,I/O
微观任务:JavaScript引擎发起的任务为微观任务,

AJAX发送了请求,如何取消请求
abort 取消请求,XMLHTTPRequest.abort();

事件代理如何实现,事件属性:currenTarget,target

​ 在外部元素绑定事件,然后判断事件源来实现对应的业务,利用事件冒泡来捕获事件,target指触发的事件源,currentTarget指绑定的事件源

ES6的解构函数和展开运算符是怎么使用的,在你的项目中有哪些用了,举例说明

定义方法时,传递的参数很多,取参数的时候用对象结构函数接收;
展开运算符用来合并对象,合并方法

export 和 import使用来做生命周期,他们如何配合使用

​ export 使用来定义一个模块或方法、变量;import 导入export 定义的模块;
​ export 单独导出,import {} 接收;
​ export default 导出,import varValue 接收;

http中常见报错

304:返回状态码,自上次请求后, 请求页面未修改过,返回此响应时,不会返回网页内容
302302重定向又称之为302代表暂时性转移,客服端请求资源,但资源不存在,但是有这个资源的地址(服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求)
305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
400 服务器不理解请求的语法
403 服务器拒绝请求
404 服务器找不到请求的网页
500 (服务器内部错误) 服务器遇到错误,无法完成请求。
501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

Vue.nextTick()

定义:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
所以就衍生出了这个获取更新后的DOM的Vue方法。所以放在Vue.nextTick()回调函数中的执行的应该是会对DOM进行操作的 js代码;
理解:nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数

什么时候需要用的Vue.nextTick()1、Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中,原因是在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted钩子函数,因为该钩子函数执行时所有的DOM挂载已完成。
2、当项目中你想在改变DOM元素的数据后基于新的dom做点什么,对新DOM一系列的js操作都需要放进Vue.nextTick()的回调函数中;通俗的理解是:更改数据后当你想立即使用js操作新的视图的时候需要使用它
正确的用法是:vue改变dom元素结构后使用vue.$nextTick()方法来实现dom数据更新后延迟执行后续代码

Vue.nextTick(callback) 使用原理:
原因是,Vue是异步执行dom更新的,一旦观察到数据变化,Vue就会开启一个队列,然后把在同一个事件循环 (event loop) 当中观察到数据变化的 watcher 推送进这个队列。如果这个watcher被触发多次,只会被推送到队列一次。这种缓冲行为可以有效的去掉重复数据造成的不必要的计算和DOm操作。而在下一个事件循环时,Vue会清空队列,并进行必要的DOM更新。
当你设置 vm.someData = 'new value'DOM 并不会马上更新,而是在异步队列被清除,也就是下一个事件循环开始时执行更新时才会进行必要的DOM更新。如果此时你想要根据更新的 DOM 状态去做某些事情,就会出现问题。。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。

JS事件捕获的三个阶段是什么?

​ 父级元素进行事件捕获,会把事件传递到目标元素,然后再进行冒泡:捕获—目标—冒泡

是否所有的对象都有原型?

​ 如:新建一个对象,需要使用tostring(),这个方法,如果没有定义,则沿原型链进行查找并使用,原型链最终指向null,null是基础对象,没有原型

表达式:const value = eval(“10*10+20”); 输出值?

​ 输出值:20, eval把内容进行JS运算

slice和splice的区别

​ slice是从数据中截取一段数据,不会改变原来数据,接受两个参数,第一个参数为开始下标,第二个参数为结束下标,不会包括结束下标值

闭包:既能全局使用,又不污染环境

​ 闭包的定义其实很简单:函数 A 内部有一个函数 B,函数 B 可以访问到函数 A 中的变量,那么函数 B 就是闭包。

​ 在 JS 中,闭包存在的意义就是让我们可以间接访问函数内部的变量。

深浅拷贝

​ 浅拷贝:object.assign来解决这个问题,只会拷贝所有属性到新对象中去,如果属性值时对象,则拷贝的是一个地址。
​ 深拷贝:JSON.parse(JSON.stringify(object))
​ 缺点:会忽略undefined、symbol、不能序列化函数,不能解决循环引用问题

var、let 及 const 区别

​ 什么是提升?什么是暂时性死区?var、let 及 const 区别?
​ 首先在全局作用域下使用 letconst 声明变量,变量并不会被挂载到 window 上,这一点就和 var 声明有了区别,再者当我们在声明 a 之前如果使用了 a,就会出现报错的情况
​ 首先报错的原因是因为存在暂时性死区,我们不能在声明前就使用变量,这也是 letconst 优于 var 的一点

class继承

class 实现继承的核心在于使用 extends 表明继承自哪个父类,并且在子类构造函数中必须调用 super,因为这段代码可以看成 Parent.call(this, value)class 的本质就是函数

async 及 await 的特点,它们的优点和缺点分别是什么?await 原理是什么?

async 就是将函数返回值使用 Promise.resolve() 包裹了下,和 then 中处理返回值一样,并且 await 只能配套 async 使用

Event Loop

Event Loop 执行顺序如下所示:

  • 首先执行同步代码,这属于宏任务
  • 当执行完所有同步代码后,执行栈为空,查询是否有异步代码需要执行
  • 执行所有微任务
  • 当执行完所有微任务后,如有必要会渲染页面
  • 然后开始下一轮 Event Loop,执行宏任务中的异步代码,也就是 setTimeout 中的回调函数
    ​ 微任务包括 process.nextTickpromiseMutationObserver
    ​ 宏任务包括 scriptsetTimeoutsetIntervalsetImmediateI/OUI rendering
    Node 中的 process.nextTick,这个函数其实是独立于 Event Loop 之外的,它有一个自己的队列,当每个阶段完成后,如果存在 nextTick 队列,就会清空队列中的所有回调函数,并且优先于其他 microtask 执行

instanceof 的原理是什么?

instanceof 可以正确的判断对象的类型,因为内部机制是通过判断对象的原型链中是不是能找到类型的 prototype

  • 首先获取类型的原型
  • 然后获得对象的原型
  • 然后一直循环判断对象的原型是否等于类型的原型,直到对象原型为 null,因为原型链最终为 null

JS 分为哪两大类型?都有什么各自的特点?你该如何判断正确的类型?

  1. 对于原始类型来说,你可以指出 nullnumber 存在的一些问题。对于对象类型来说,你可以从垃圾回收的角度去切入,也可以说一下对象类型存在深浅拷贝的问题。
  2. 对于判断类型来说,你可以去对比一下 typeofinstanceof 之间的区别,也可以指出 instanceof 判断类型也不是完全准确的。

HTML5离线缓存怎么使用,工作原理能不能解释一下?

​ 用户在没有联网时,可以正常访问站点或应用,等用户联网时,更新用户的缓存文件。

​ 在联网情况下,html头部有manifest属性,会请求manifest文件,如果是第一次访问,浏览器会根据manifest的内容下载相应的资源并且进行离线缓存,如果不是第一个,会加载成为新的manifest文件,新旧manifest文件对比,如果一致,则不发生变化,如果不一致,那么会重新下载文件中的资源并进行离线缓存

页面导入样式时,使用link和@import有什么区别?

​ link属于XHTML标签,除了加载CSS之外,还能用于定义RSS,import是CSS提供的,只能用于加载CSS,

​ link是边加载结构,就加载样式,而import是先加载结构,在加载样式

​ import有兼容性问题

如何实现浏览器内多个标签页之间的通信?

​ LocalStorage实现浏览器多个标签页之间的通信,addEventListenren() 监听storage

img的title和alt有什么区别。

​ title是当鼠标划到图片元素时显示的图片描述,alt时当图片无法加载显示的时候,而展示的描述或图片

CANVAS和Svg有什么区别

​ Svg绘制出来的每一个图形的元素,都是独立的DOM节点,能够方便的绑定事件或用来修改。Canvas输出的时画布

​ Svg输出的图片的矢量图,放大缩小不会失帧,而canvas放大缩小会失帧

Vue的生命周期

beforeCreate:页面定义的数据以及页面节点无法获取
created:页面定义的数据可以获取(已经被实例),页面节点无法获取
在这个生命周期之间,进行初始化事件,进行数据的观测,可以看到在 created 的时候数据已经和 data 属性进行绑定。但此时尚未挂载,el 还不可用。
beforeMount:页面定义的数据可以获取(已经被实例),页面节点无法获取,开始挂载DOM,
mounted: 页面定义的数据可以获取(已经被实例),页面节点已经获取
页面节点已被挂载,可以使用DOM节点进行业务操作(ECharts)
beforeUpdate:初始化不会被触发,当数据发生变化后,会被触发,且被VNode绑定或使用才能触发此生命钩子
update: 初始化不会被触发,当数据发生变化后,会被触发,且被VNode绑定或使用才能触发此生命钩子
可以用来监听页面数据是否发生变化,提示用于是否保存或放弃修改这样的业务
beforeDestroy
当组件被销毁才会被触发,隐藏不会触发此生命周期,VNode 可以查询到,因此可以做一个查询操作,例如:echarts 实例的销毁就应该在这个生命周期完成,取消事件监听也可以在此生命周期完成
destroyed
当组件被销毁才会被触发,隐藏不会触发此生命周期,VNode 已被销毁

Vue的响应原理
Object.defineProperty
Vue在数据改变时,通过劫持Obj.defineProperty的setter、getter方法

Vue的传值方式

1、 通过路由带参数进行传值(触发事件可以是点击事件、钩子函数等)
2、 通过sessionStorage进行缓存形式传值
3、父子组件之间传值
	父组件向子组件传值props:通过属性传递值
	子组件往父组件传值是通过$emit事件传递,
4、不同组件之间传值,EventBus或vuex
	传值方:enventBus.$emit('事件名',data)
	接收方:eventBus.$on('事件名', data => {})
Vuex主要用于做数据之间的交互,state定义数据类型,getters,设置返回的数据,可以调用获取,actions,用于设置数据,可以传递数据,并通过commit来调用mutation数据扭转
state:{userinfo:{}}
getters:{getuserinfo:() state => state.userInfo}
actions:{setUserInfo({commit},data){
	commit('mutationUser',data)
}}
mutation:{mutationUser(state,data){
	state.userInfo = data
}}

Vuex功能

vuex-persistedstate:可以把Vuex状态管理库中的数据存储到本地展示
vuex是专门用来管理vue.js应用程序中状态的一个插件,作用:将应用中的所有状态都放在一起,集中式来管理。需要声明的是,这里所说的状态指的是vue组件中data里面的属性
Vuex规则:只能在mutaions里修改state,actions不能直接修改state,mutations即变化,修改state的数据,而且只能是同步的,不能存在异步的操作
vuex 中最关键的是store对象,这是vuex的核心。可以说,vuex这个插件其实就是一个store对象,每个vue应用仅且仅有一个store对象,store是Vuex.Store这个构造函数new出来的实例
	1、store 中存储的状态是响应式的,当组件从store中读取状态时,如果store中的状态发生了改变,那么相应的组件也会得到更新
	2、不能直接改变store中的状态。改变store中的状态的唯一途径是提交(commit)mutations。这样使得我们可以方便地跟踪每一个状态的变化
mapState,当一个组件获取多种状态的时候,则在计算属性中要写多个函数。为了方便,可以使用mapState辅助函数来帮我们生成计算属性。
import { mapState } from  'vuex';
...mapState({
	userInfo: 'common/getUserInfo'
})
this.$store.getters['common/getUserInfo']
只用来读取的状态集中放在store中; 改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中
应用场景:单页应用中,组件之间的状态、音乐播放、登录状态、加入购物车

如何提高页面加载速度

优化网页图片文件
图片使用height和width属性
CSS文件压缩瘦身
目录地址后加上斜杠(/)
整合CSSJS文件减少HTTP请求次数(精灵图)
使用外部的JavaScript和CSS
尝试CDN加速
离线缓存

HTML5的缓存有哪些
cookie、Session、SessionStorage、LocalStorage
Cookie和Session都是会话技术,Cookie是运行在客户端,Session是运行在服务器端。
Cookie有大小限制以及浏览器在存cookie的个数也有限制,Session是没有大小限制和服务器的内存大小有关。
cookie存储:存储数据小,会话级别过期
sessionStorage,H5新增的本地存储,会话级别,它只是可以将一部分数据在当前会话中保存下来,刷新页面数据依旧存在,
LocalStorage,本地存储,只要不删除,理论永远有效

图片如何实现懒加载
定义:图片懒加载是一种网页优化技术。图片作为一种网络资源,在被请求时也与普通静态资源一样,将占用网络资源,而一次性将整个页面的所有图片加载完,将大大增加页面的首屏加载时间。为了解决这种问题,通过前后端配合,使图片仅在浏览器当前视窗内出现时才加载该图片,达到减少首屏图片请求数的技术就被称为“图片懒加载”。

XSS攻击
跨站脚本攻击(XSS)
原理:HTML是一种超文本标记语言,通过将一些字符特殊地对待来区别文本和标记,例如,小于符号(<)被看作是HTML标签的开始,

之间的字符是页面的标题等等。当动态页面中插入的内容含有这些特殊字符(如<)时,用户浏览器会将其误认为是插入了HTML标签,当这些HTML标签引入了一段JavaScript脚本时,这些脚本程序就将会在用户浏览器中执行。所以,当这些特殊字符不能被动态页面检查或检查出现失误时,就将会产生XSS漏洞。

sql注入
在进行数据保存的时候,需要对数据进行过滤,特殊字符转义

=> ⁢div>

MVC,MVVM的原理和区别

MVC模式
M:model,负责对数据的处理,并返回目标数据
V:View负责对目标数据的渲染和处理用户的响应
C:control协调model和view,主要用于处理委托和数据的
MVVMM:模型,V:视图,VM:视图模型

在 MVC 中,Model 和 View 之间耦合,视图的更新需要 Model 去直接通知。Model 内因为有 View 的引用才能让视图更新
在 MVVM 中,View 和 Model 的变化似乎不大。为了在数据变化后能够自动更新视图,ViewModel 进行了所谓的数据绑定。ViewModel 将 目标数据 和视图进行了绑定,在最终生成目标数据时,会触发视图的更新。

知道的网页制作会用到的图片格式有哪些?
png,jpg,jpeg,gif,svg,webp,Apng
webp:谷歌开发的一种旨在加快图片加载素的的图片格式

从用户刷新网页开始,一次js请求一般情况下有哪些地方会有缓存处理?
dns缓存,cdn缓存,浏览器缓存,服务器缓存。

什么是闭包
闭包就是能够读取其他函数内部变量的函数。
目的:既能全局使用,又不污染环境
本质:闭包其实就是JavaScript函数作用域的副作用产品

VUe系列

MVVMMODEL VIEW VIEWMODELM数据模型,V视图模型(UI)组件,VMVM的桥梁,也就是数据会绑定到VM层,并自动讲数据渲染到页面中,数据变化的时候会自动更新视图
VUE2.x 的响应式原理:Object.defineProperty重新定义data中的所有属性,Vue在数据改变时,通过劫持Obj.defineProperty的set方法。当页面使用对应的属性,会进行依赖的收集,如果数据发送变化会通知相关依赖进行更新操作
VUE3.x的响应式原理:改用proxy替代Object.defineProperty,proxy可以直接监听到对象和数组的变化,并且又很多拦截方法。
对于Proxy只会代理对象的第一层,Vue3怎么做的处理:通过reflect.get的返回值是否是Obejct,如果是再通过reactive方法做代理
检测数组的时候,可能触发多个get/set方法,如何防止多次触发:我们可以判断key是否为当前被代理的target自身属性,也可以判断旧值和新值是否相等,满足其一,菜去执行trigger
Vue2中如何检测数组的变化:使用函数劫持的方式,重写数组的方法,Vue将data中的数据进行了原型链的重写,指向自己定义的数组原型方法,这样调用数组api时,可以通知依赖更新,如果数组中包含引用类型,会对数组中的引用类型再次递归遍历。这样就实现了检测数组变化。
nextTick知道吗,实现原理是什么:在下次Dom更新循环结束之后执行延迟回调,nextTick主要使用宏任务和微任务,根据执行环境分别尝试采用:promise,mutationObserver,setImmediate,setTimeout,如果是一个异步方法:多次调用nextTick会将方法存入队列中,通过这个异步方法可以清空当前队列。
Vue的生命周期:
beforeCreate,是vue触发的第一个钩子,页面在挂载数据,节点没有渲染,无法在当前阶段对data,methods,computer,watch上的数据进行访问。
created,进行页面数据的初始化,也就是对使用数据,更改数据,在此阶段更改数不会触发updated函数,在此阶段无法与dom界面进行交互,如果要交互,可以使用vm.nextTick来访问dom
beforeMount,dom挂载,可以拿到数据,但是无法对dom进行操作
mounted:dom挂载完成,数据完成双向绑定,可以对dom进行操作
beforeUpdate,发生更新之前,也就是响应式数据发送变化的时候,虚拟dom重写渲染之前触发,可以进行更改数据,不会造成重写渲染
updated,更新完成之后,避免在此期间更改数据,可能会导致无限循环更新
beforeDestory:实例销毁之前,在当前阶段实例还能被使用。在此阶段一般是进行,监听的移除,定时器的清理
接口请求一般放在那个生命周期:created
Computed和Watch
computed本质具备缓存watcher,依赖的属性发送变化就会更新视图。适用于计算比较消耗性能的计算场景。当表达式过于复杂,在模板放入太多逻辑会让模板难以维护,可以讲复杂的逻辑放入计算属性中处理
watch没有缓存性:更多是观察的作用,可以监听某些数据执行回调。当我们需要深度监听时,可以打开deep:true,这样可以对对象中的每一项进行监听。
v-if和v-show,v-if不会渲染dom节点,v-show时通过display来控制dom节点的显示和隐藏
组件中data为什么是一个函数:一个组件被复用多次的化,就会创建多个实例,本质上,这些实例用的都是同一个构造函数,如果data是对象的化,对象属于引用类型,会影响到所有的实例,为了保证组件不同的实例之间data不冲突,data必须是一个函数
v-model的原理:v-model本质就是语法糖,可以看成value+input的方法,可以通过model属性的prop和event属性来进行自定义
vue事件的绑定原理:原生事件是通过addEventListener绑定给真实元素,组件事件绑定通过vue自定义$on实现
Vue的模板编译原理:Vue的编译过程就是将template转化为render函数的过程
虚拟的dom,在浏览器中操作DOM是很昂贵的,频繁的操作Dom,会产生一定的性能问题,这就是虚拟DOM产生的原因,Virtual DOM本质就是用一个原生的JS对象去描述一个DOM节点。是对真实DOM的一层抽象
key属性的作用:尽可能的复用DOM元素,key也是children中节点的唯一标识符
Vue中组件的生命周期调用顺序是:
组件的调用顺序都是先父后子,渲染完成的顺序是先子后父。
组件的销毁操作是先父后子,销毁完成的顺序是先子后父。
Vue组件通信有哪些方法:
父子通信:父->子:props,子->父:$on,$emit
获取父子组件实例:$parent,$children
ref获取实例的方式调用组件的属性和方法
兄弟组件通信:EventBus实现跨组件通信,vuex
Vue性能优化:
尽量减少data中的数据
v-if和v-for不能连用
如果需要使用v-for给每项元素绑定事件时使用事件代理
在更多的情况下,使用v-if替代v-show
使用路由懒加载、异步组件
key保证唯一
防抖、节流
第三方模块按需导入
长列表滚动到可视区域动态加载
图片懒加载

JS常见的笔试题

节流:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效
常用场景:scroll滚动事件
防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时
常用场景:浏览器窗口大小resize避免次数过于频繁,登录发短信验证码等按钮发送多次请求
数组去重:
1、 Set方法:Array.form(new Set(arr)) / ler arr = arr => [...new Set(arr)]
2、 fillter方法:
function unique(arr) {
	var res = arr.filter((item,index,arr) => {
        return arr.indexof(item) === index
    })
    return res
}
reduce方法
unique = arr => {
    return arr.reduce((pre,cur) => {
        return pre.includes(cur) ? pre : [...pre,cur] 
    },[]);
}
Object键值对
var obj = {}
var arr1 = []
for(var i=0; i<arr.length; i++) {
    if(obj[arr[i]] === undefine) {
        arr1.push(arr[i])
    }
    console.log(arr1)
}
将多维数组将为一维
let flat = arr => {
    return arr.reduce((res,cur) => {
        if (Array.isArray(cur)) {
            return [...res,...flat(cur)]
        } else {
            return [...res,cur]
        }
    },[])
}
深拷贝:JSON.parse(JSON.stringify())
手写Ajax
var xhr = new XMLHttpRequest()
xhr.open()
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status ===200) {
        .....
    }
}
xhr.send()
实现Object.create方法
function create(proto) {
    function Fn() {};
    Fn.prototype = proto;
    Fn.prototype.constructor = Fn;
    return new Fn()
}
数字转字符串千分位
function thousandth(str) {
  return str.replace(/d(?=(?:d{3})+(?:.d+|$))/g, '$&,');
}

HTML5–CSS3

拖放:draggable="true"
ondragstart 属性调用了一个函数,drag(event),它规定了被拖动的数据dataTransfer.setData()
localStorage跨页面通信
localStorage的增删改,都会触发其storage事件,通过监听这个事件,控制它的值进行页面通讯
使用场景:用户在网站 A页面 中登录,在B页面退出,A页面与B页面的登录状态保持一致
Video.js、PDF.js 、canvas、localStorage、sessionStorage、localStorage跨页面通信、manifest、拖放
CSS3属性哪些可以继承:
visibility,cursor,内联可继承:white-space,letter-spacing,line-height,color,font,font-size,text-decoration,direction
CSS:圆角,opacity,旋转,animation、transition、box-shadow、gradient、media、边框可以设置图片(border-image)
CSS3动画:
transform(转换动画、直接动画):rotate(旋转)translate(平移)skew(变形)scale(伸缩比例)transform-orgin:2d,3d转换中心的设置
transform-style:preserve-3d;2d转化为3d动画
transition(过渡动画)
animation(帧动画)

JS面试题

1、如何判断变量的类型
typeof对于原始类型(除了Null)是可以检测到的,但是引用类型就统一返回object
instance of 用于检测构造函数的原型是否出现在某个实例函数的原型链上
最好的方法是使用 Object.prototype.toString方法,它可以检测到任何类型,返回的结果是[object Type]的形式,基本可以实现所有类型的检测,我们用下面的代码来演示一下
function detectType(type) {
    return function(obj) {
        return {}.toString.call(obj) === `[object ${type}]`
    }
}
2、解释一下原型链
每一个函数有一个prototype的属性,当他作为构造函数的时候,它实例化出来的函数会有一个_proto_的属性,它执行构造函数的prototype
函数通过prototype来访问其父元素的属性和方法,依此迭代访问,构成原型链,直到Object的原型为止,它位于原型链的顶端。
访问某个属性或方法的时候,会先从当前对象中查找,没有的话就顺着原型链开始寻找,直到找到最顶端,也就是Object的原型(null)为止。另外每一个原型上都有一个constructor属性,指向相关联的构造函数
3new操作符都做了些什么
创建一个空对象、将空对象的proto属性指向构造函数的原型、将this指向这个对象、返回这个对象
4、异步编程 promise,async/await
promise是es6对异步编程的一个方案,它有三种状态,pending(挂起),fullfilled(成功),rejected(拒绝),状态一旦改变就不可逆,通过then这个方法来实现异步调用之后的逻辑,另外还支持链式调用。

async将任何函数转换为promise,这时异步函数的特征之一。 await 可以使用在任何返回Promise函数的函数之前,并且会暂停在这里,直到promise返回结果才往下进行。
5、javascript的typeof返回哪些数据类型
Number、string、undefin、function、object、Boolea
6、例举3种强制类型转换和2种隐式类型转换?
强制(parseInt、parseFloat、bumber)
7、split和join的区别
前者将字符串切割成数组,后者将数组切割成字符串,可以自定义切割符合
8、阻止事件冒泡
IE:e.cancelBubble = true,IE:e.stopPropagetion();
9、阻止默认事件
return false || e.preventDefault();
10、解释jsonp的原理,以及为什么不是真正的ajax
利用src的跨域开源政策、动态创建script,服务端返回一个方法名.
Ajax是页面无刷新请求数据的操作
11、 document load 和document ready的区别
onload是结构和样式,外部JS及图片加载完才执行JS
ready是dom树创建完成就执行的方法,原生没有,jq有
12var a = null console.log(typeof a) --- object
null表示空指针对象,所以返回object
13、 innerHTML和outerHTML的区别
innerHTML(元素内包含的内容)、outerHTML(
                        
                        
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/Samar_319/article/details/110806059
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢