坐标广州,web前端中高级开发工程师面试题整理…(css,js,es6,vue,http等等…微信小程序问得比较少就不列举了,跨平台如uni-app,taro…),2020.04月,有空会再更新一下,需要的朋友可以看看哈…
1.css移动端1px问题
https://blog.csdn.net/duola8789/article/details/95456188
伪元素 + tranform: scaleY
0.5px边框
伪元素 + liner-gradient + sacle
2.css3新特性
选择器,旋转,位移,动画,阴影,渐变,弹性,滤镜…
3.HTML5新特性
section,article,header,nav,article…
canvas画布,draggable拖放,video/audio,input类型
localStorage
4. 有几种方式可以实现继承
https://www.cnblogs.com/humin/p/4556820.html
原型链继承(对象间的继承)
类式继承(构造函数间的继承)
实例继承
5.作用域、作用域链和闭包的理解
变量的作用域无非就是两种:全局变量和局部变量。
作用域链:根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问。(当代码执行的时候,会创建变量对象的一个作用域链…)
闭包:闭包是指有权访问另一函数作用域中的变量的函数。
闭包案例:
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i + " ");
}, 100);
}
输出结果为 5 5 5 5 5
修改:
for (var i = 0; i < 5;i++) {
(function(i) {
setTimeout(function() {
console.log(i + " ");
}, 100);
})(i);
}
输出结果为: 0 1 2 3 4
6. 对象深拷贝、浅拷贝
https://www.cnblogs.com/dabingqi/p/8502932.html
浅拷贝的意思就是只复制引用(指针),而未复制真正的值。
如果拷贝后的对象发生变化,原对象也会发生变化。
深拷贝就是对目标的完全拷贝,不像浅拷贝那样只是复制了一层引用,就连值也都复制了。
只要进行了深拷贝,它们老死不相往来,谁也不会影响谁。
方法:1.利用 JSON 对象中的 parse 和 stringify
2.利用递归来实现每一层都重新创建对象并赋值
7. this关键字
面向对象语言中 this 表示当前对象的一个引用。
在方法中,this 表示该方法所属的对象。
如果单独使用,this 表示全局对象。
在函数中,this 表示全局对象。
在函数中,在严格模式下,this 是未定义的(undefined)。
在事件中,this 表示接收事件的元素。
类似 call() 和 apply() 方法可以将 this 引用到任何对象。
8. 为什么会有同源策略
两个页面地址中的协议,域名,端口号一致,则表示同源;
同源策略的限制:不能通过ajax请求不同域的数据,不能通过脚本操作不同域下的DOM;
为什么要用同源策略:设置同源限制主要是为了安全,如果没有同源限制存在浏览器中的cookie等其他数据可以任意读取,不同域下DOM任意操作,ajax任意请求的话如果浏览了恶意网站那么就会泄漏这些隐私数据;
9.js中几种实用的跨域方法原理详解
1.通过jsonp跨域
2.跨域资源共享(CORS)
3.通过修改document.domain来跨子域
4.使用window.name来进行跨域
5.通过WebSocket进行跨域
10.浏览器是如何渲染页面的?
1.解析HTML文件,创建DOM树。
自上而下,遇到任何样式(link、style)与脚本(script)都会阻塞(外部样式不阻塞后续外部脚本的加载)。
2.解析CSS。优先级:浏览器默认设置<用户设置<外部样式<内联样式 3.将CSS与DOM合并,构建渲染树(Render Tree)。
4.布局和绘制,重绘(repaint)和重排(reflow)。
11.一次完整的http事务是怎样的一个过程
一.域名解析
二.发起TCP的3次握手
三.建立TCP连接后发起http请求
四.服务器端响应http请求,浏览器得到html代码
五. 浏览器解析html代码,并请求html代码中的资源
六.浏览器对页面进行渲染呈现给用户
12.双等号和三等号的区别
== 定义的比较宽松允许进行类型转换 在对比时把两个值转换为同一类型 然后比较两个值是否相等 ;
=== 定义严格, 如果类型不同,结果为false
例如 :
let string = ‘1’
let number = 1
number == string //true
number === string // false
而对象(Date,Array)及普通对象通过指针指向的内存中的地址来做比较
13.call和apply区别
call和apply方法都是使用一个指定的this值和对应的参数前提下调用某个函数或方法。区别则在于
call是通过传多个参数的方式,而apply则是传入一个数组。
var obj = {
name: 'jack'
}
function func(age, sex) {
console.log(this.name,age,sex);
}
func.call(obj,12,'女'); // jack 12 女
func.apply(obj, [18, '女']); //ljack 18 女
20.数组去重
方法1 var newArr = Array.from(new Set(arr))
方法2 function unique(arr) {
const res = new Map();
return arr.filter((a) => !res.has(a) && res.set(a, 1))
}
21.垃圾回收机制
JS的垃圾回收机制是为了以防内存泄漏,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。
原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。
方式:标记清除法,引用计数法
22.js中的基本数据类型
(Number,String,Boolean,Undefined,Null),和一种复杂数据类型(Object)。
23.get和post区别?
GET把参数包含在URL中,POST通过request body传递参数。
GET请求只能进行url编码,而POST支持多种编码方式。
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
24.请描述一下cookies,sessionStorage和localstorage区别
(1)存储大小
cookie数据大小不能超过4k。
sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或 更大。
(2)有效时间
localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
sessionStorage 数据在当前浏览器窗口关闭后自动删除;
cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
(3)数据与服务器之间的交互方式
cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端;
sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存;
25.dom节点操作
添加:appendChild()
移除:removeChild()
替换:replaceChild()
插入:insertBefore()
创建:createElement() createTextNode()
查找:getElementsById() getElementsByName()
26.var、let、const声明变量的区别
let和var声明变量的区别:
let所声明的变量只在let命令所在的代码块内有效。(块级作用域)
let命令不存在变量提升
let声明变量存在暂时性死区(即变量会绑定某个区域,不受外部影响)
const声明变量
const的作用域与let命令相同:只在声明所在的块级作用域内有效。
27.解构赋值
从数组和对象中提取值,对变量进行赋值
let [a, b, c] = [1, 2, 3]; a=1,b=1,c=3
let a=1, b=2;
[b, a] = [a, b]
console.log(a, b)
28.声明类与继承:class、extend
class Person {
// 构造函数
constructor(name) {
this.name = name;
}
// 等价于Person.prototype.sayName
sayName() {
console.log(this.name);
}
}
console.log(typeof Person); // function
console.log(typeof Person.prototype.sayName); // function
29.扩展运算符
https://www.jianshu.com/p/3578bfbe3b4d
30.Map的用法
https://www.cnblogs.com/kongxianghai/p/7309735.html
Map对象就是简单的键值对映射。其中的键和值可以使任意值。(ps : 对象的键只能是字符串 )
const map1 = new Map()
const objkey = {p1: ‘v1’}
map1.set(objkey, ‘hello’)
console.log(map1.get(objkey)) 输出hello
31.promise与async/await的区别
https://blog.csdn.net/weixin_42470791/article/details/82560734
async/await是写异步代码的新方式,以前的方法有回调函数和Promise。
async/await是基于Promise实现的,它不能用于普通的回调函数。
async/await与Promise一样,是非阻塞的。
async/await使得异步代码看起来像同步代码,这正是它的魔力所在。
Promise主要处理异步操作,确认异步操作完成再执行后面的语句。
const promise = new Promise(function(resolve, reject) {
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(function(res){
}).catch(function(err){
});
async/await是then/catch的完美版。作用与then/catch相同,只是用法上的区别。
async f1() {
try{
const res = await promise;
}catch(err){
console.log(err)
}
}
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
32.MVVM模式理解
MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自动传递给 View,即所谓的数据双向绑定。
33.vue虚拟dom原理
https://www.jianshu.com/p/af0b398602bc
Virual DOM是用JS对象记录一个dom节点的副本,当dom发生更改时候,先用
虚拟dom进行diff,算出最小差异,然后再修改真实dom。
vue的virtual dom的diff算法是基于snabbdom算法改造而来,与react的diff算法一样
仅在同级的vnode间做diff,递归的进行同级vnode的diff,最终实现整个DOM树的更新。
虚拟DOM的缺点:
34.数据双向绑定原理
https://segmentfault.com/a/1190000014616977
vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的.
原理:1.数据劫持,2.发布订阅模式
Object.defineProperty(obj, key, val)来劫持各个属性的的setter以及getter,在数据变动时发布消息给订阅者,从而触发相应的回调来更新视图。
35.watch computed区别
watch:属性监听 监听属性的变化
computed: 计算属性通过属性计算而得来的属性
使用场景
computed 当一个属性受多个属性影响的时候就需要用到computed
最典型的例子: 购物车商品结算的时候
watch 当一条数据影响多条数据的时候就需要用watch
搜索数据
37.vuex
state存储的全局的客户和供应商集合;
getters用来根据state计算各种属性值;
mutations一般是用来同步改变state中的数据,类似于setters;
actions则是异步接收数据(不一定必须是异步方法,如第一个方法,只是外界调用接口都是从这里调用的),然后调用mutations内部方法来改变state的值;
modules:store的子模块,为了开发大型项目,方便状态管理而使用的。
38.vue的生命周期
beforeCreate(创建前)、created(创建后)、beforeMount(载入前)、mounted(载入后)、beforeUpdate(更新前)、updated(更新后)、beforeDestroy(销毁前)、destroyed(销毁后)
39.created和mounted的区别
created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
40.Vue中路由守卫
https://www.cnblogs.com/minigrasshopper/p/7928311.html
导航守卫的作用:vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
全局守卫包括:router.beforeEach(是全局前置守卫)、router.beforeResolve(是全局解析守卫)、router.afterEach(是全局后置钩子)
每个导航守卫都接受3个参数 from 、to、next() ,参数的定义如下:
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
41.this.$router.push({})实现路由跳转
this.$router.push({
path:'/login',
name:'login',
//params传参 需要使用 name 否则取不到;对应路由配置的 name
// query: {
// id:this.id
// }
params: {
id:this.id
}
区别是query传参的参数会带在url后边展示在地址栏,params传参的参数不会展示到地址栏
42.axios的post
https://blog.csdn.net/qq_37121488/article/details/81192163
使用transformRequest,在请求发送前将请求数据进行转换
如果使用模块化开发,可以使用qs模块进行转换
new URLSearchParams()
推荐qs
var qs = require(‘qs’);
axios.post(’/demo’, qs.stringify({ ‘params’: 7758521 }, { indices: false }))
43.vue实例中data使用return包裹
因为不使用return包裹的数据会在项目的全局可见,会造成变量污染。
使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件。
44.vue替换数组对象的某个属性值
this.$set
由于 Vue 会在初始化实例时进行双向数据绑定,使用Object.defineProperty()对属性遍历添加getter/setter 方法,所以属性必须在 data 对象上存在时才能进行上述过程 ,这样才能让它是响应的。
例如:
data:[
{name: 'xxx', status: 0},
{name: 'xxx', status: 1},
]
data.forEach(item => {
if (item.status === 0) {
// 'status'为属性名,'非活动'为修改后的内容
this.$set(item, 'status', '非活动')
} else if (item.status === 1) {
this.$set(item, 'status', '活动')
}
})
44.说一说emit、 on 、off
1、vm.$emit( event, […args] )
触发当前实例上的事件。附加参数都会传给监听器回调,如果没有参数,形式为vm.$emit(event)。
2、vm.$on( event, callback )
监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数。
3、vm.$off( [event, callback] )
移除自定义事件监听器。
如果没有提供参数,则移除所有的事件监听器;
如果只提供了事件,则移除该事件所有的监听器;
如果同时提供了事件与回调,则只移除这个回调的监听器。
45.Vue 定义全局的公用的组件
import fotter from './components/fotter.vue'
Vue.component('fotter-view',fotter)
使用:<fotter-view></fotter-view>
46.Vue全局方法
import xx from './plugin/xx' // 引入
Vue.prototype.$xx = xx;
使用this.$xx()
47.组件通讯
父-子:props:['msg']
子-父:this.$emit this.$emit('receiveMsg','from child');
兄弟:this.$root.eventHub.$emit ;this.$root.eventHub.$on
爷-孙:属性 this.attrs['msg']; 方法 this.$listeners.test(123)
48.Vue生命周期的执行过程
1、创建vue实例,Vue();
2、在创建Vue实例的时候,执行了init(),在init过程中首先调用了beforeCreate钩子函数;
3、同时监听data数据,初始化vue内部事件,进行属性和方法的计算;
4、以上都干完了,调用Created钩子函数;
5、模板编译,把data对象里面的数据和vue语法写的模板编译成HTML。编译过程分三种情况:1)实例内部有template属性,直接调用,然后调用render函数去渲染;2)没有该属性调用外部html;3)都没有抛出错误;
6、编译模板完成,调用beforeMount钩子函数;
7、render函数执行之后,将渲染出来的内容挂载到DOM节点上;
8、挂在结束,调用Mounted钩子函数;
9、数据发生变化,调用beforeUpdate钩子函数,经历virtual Dom;
10、更新完成,调用Updated钩子函数;
11、beforeDestory销毁所有观察者、组件及事件监听;
12、Destoryed实例销毁;
49.vue.nextTick()方法的使用
nextTick(),this.$nextTick(() => {})是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数
50.单页面和多页面应用的区别
51.缓存组件keep-alive
https://blog.csdn.net/weixin_42211816/article/details/105254582
keepalive中文翻译的意思是:保持活着;
被包含在 keep-alive 中创建的组件,会多出两个生命周期的钩子: activated 与 deactivated
activated: 在 keep-alive 组件激活时调用,该钩子函数在服务器端渲染期间不被调用
deactivated:在 keep-alive 组件停用时调用,该钩子在服务器端渲染期间不被调用