这里写目录标题
⼏种常⻅的CSS布局
JS继承的实现方式
自我介绍
面试官您好,我叫。。。,19年毕业于。。。。大学。。。专业,毕业后就从事了前端开发相关的工作,并且今年在工作之余拿到了国际PMP证书,成绩是5A。我平常吃苦耐劳、善于总结、拥有自主学习新知识的能力,热爱钻研技术上的问题。并且看好互联网行业,并打算长期在 IT 行业发展。
9.vue父子组件生命周期执行顺序
加载渲染过程
父beforeCreate —> 父created —> 父beforeMount —> 子beforeCreate —> 子created —> 子beforeMount —> 子mounted —> 父mounted
子组件更新过程
父beforeUpdate —> 子beforeUpdate —> 子updated —> 父updated
父组件更新过程
父beforeUpdate —> 父updated
销毁过程
父beforeDestroy —> 子beforeDestroy —> 子destroyed —> 父destroyed
26.vue中常见的性能优化
一、编码优化:
1.不要将所有的数据都放在data中,data中的数据都会增加getter和setter,会收集对应的 watcher,这样就会降低性能。
-
vue 在 v-for 时给每项元素绑定事件需要用事件代理,节约性能。
-
单页面采用keep-alive缓存组件。
4.尽可能拆分组件,来提高复用性、增加代码的可维护性,减少不必要的渲染。因为组件粒度最细,改组件的数组,它只会渲染当前的组件。
-
v-if 当值为false时内部指令不会执行,具有阻断功能,很多情况下使用v-if替代v-show,合理使用if和show。
-
key 保证唯一性,不要使用索引 ( vue 中diff算法会采用就地复用策略)。
-
data中的所以数据都会被劫持,所以将数据尽可能扁平化,如果数据只是用来渲染可以使用Object.freeze,可以将数据冻结起来,这样就不会增加getter和setter。
8.合理使用路由懒加载、异步组件。
9.尽量采用runtime运行时版本。
10.数据持久化的问题,使用防抖、节流进行优化,尽可能的少执行和不执行。
二、加载性能:
1.使用第三方插件实现按需加载( babel-plugin-component )
2.滚动到可视区域动态加载 ( https://tangbc.github.io/vue-virtual-scroll-list )
3.图片懒加载 (https://github.com/hilongjw/vue-lazyload.git)
三、用户体验:
1.app-skeleton 骨架屏
2.app-shell app壳
3.pwa 可以实现H5的离线缓存,使用servicewor
四、SEO 优化:
1.预渲染插件 prerender-spa-plugin,可以把我们代码提前运行起来,最后将代码保存下来,缺陷就是不实时。
2.服务端渲染 ssr
五、.打包优化:
1.使用 cdn 的方式加载第三方模块
2.多线程打包 happypack
3.抽离公共文件 splitChunks
4.sourceMap 生成
六、缓存和压缩:
1.客户端缓存、服务端缓存
2.服务端 gzip 压缩
30.实现hash路由和history路由
onhashchange
history.pushState
- hash 模式:在浏览器中符号 “#” ,#以及#后⾯的字符称之为 hash ,⽤ window.location.hash 读取。特点: hash 虽然在 URL 中,但不被包括在 HTTP 请求中;⽤来指导浏览器动作,对服务端安全⽆⽤, hash 不会重加载⻚⾯。
- history 模式:h istory 采⽤ HTML5 的新特性;且提供了两个新⽅法:pushState() , replaceState() 可以对浏览器历史记录栈进⾏修改,以及 popState 事件的监听到状态变更
34.Vue3.0你知道有哪些改进
- 压缩包体积更小(
20Kb => 10Kb
) - 数据劫持的方式修改(
Object.defineProperty => Proxy
) Virtual DOM
重构,提供diff
算法效率- 组件定义方式变更(
Options API => Function_Based API
)
25.常见的HTTP状态码
1xx:指示信息–表示请求已接收,继续处理
2xx:成功–表示请求已被成功接收、理解、接受
3xx:重定向–要完成请求必须进行更进一步的操作
4xx:客户端错误–请求有语法错误或请求无法实现
5xx:服务器端错误–服务器未能实现合法的请求
200:请求被正常处理
400:**请求报文语法有误,服务器无法识别
**401:**请求需要认证
**403:**禁止被访问
**404:**服务器无法找到对应资源
**500:服务器内部错误
503:服务器正忙
38.JavaScript原型,原型链 ? 有什么特点
每个对象都有一个内部属性 prototype,我们通常称之为原型.
原型的值可以是一个对象,也可以是null.
如果它的值是一个对象,则这个对象也一定有自己的原型.
这样就形成了一条线性的链,我们称之为原型链.
访问一个对象的原型可以使用Object.getPrototypeOf方法,或者__proto__属性.
原型向上查找的过程属于原型链;
特点
- 可以向上查找,不能向下查找
- 我们没有办法遍历到所有以某个对象为原型的对象,但我们可以向上遍历,获取到一个对象所有的上层原型,这个原型链必定是线性的,尽头是null;
- 原型链的作用是用来实现继承的;
- 原型链的作用是用来实现继承,比如我们新建一个数组,数组的方法就是从数组的原型上继承而来的.
- 虽然我们都说原型链,但实际上,在不考虑网页中frame的情况,js引擎在执行期间的某一时刻,所有存在的对象组成的是一棵原型树.默认情况下,只有一棵树.根节点可以说是Object.prototype,也可以说是null.
39.Promise,async和await
什么是 Promise
Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。
promise有几种状态
promise有三种状态,分别为pending(等待中)、fulfilled(已成功)、rejected(已失败)
三个状态之间的变化,通过resolve将promise的状态从pending变成fulfilled,调用reject将promise的状态从pending变成rejected。
async、await
将异步强行转换为同步处理。
async/await是寄生于Promise,Generater的语法糖。
规则:
1 async和await是配对使用的,await存在于async的内部。否则会报错
2 await表示在这里等待一个promise返回,再接下来执行
3 await后面跟着的应该是一个promise对象,(也可以不是,如果不是接下来也没什么意义了…)
40.宏任务微任务
宏任务
宏任务指执行栈中待执行的任务,计时器,事件回调,http回调都是宏任务。
微任务
微任务指执行栈清空后立即执行的任务(VIP通道,贵族就是不一样~),Promise 和 MutationObserver都是微任务。
微任务的优先级高于宏任务
3、使用箭头函数应注意什么?
(1)用了箭头函数,this就不是指向window,而是父级(指向是可变的)
【普通函数this指向直接调用者】
(2)不能够使用arguments对象
(3)不能用作构造函数,这就是说不能够使用new命令,否则会抛出一个错误
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数
二十四.数组常用方法
变异方法
方法名 | 用法 | 返回值 |
---|---|---|
sort() | 默认按字符串编码的顺序排列,非string会自动转换成string | 排序后的数组 |
reverse() | 将数组元素倒序排列 | 倒序的数组 |
push() | (入栈)向数组末尾添加一个或多个元素 | 新数组的长度 |
pop() | (出栈)删除数组的最后一个元素 | 删除的元素 |
unshift() | 向数组开头添加一个或多个元素 | 新数组的长度 |
shift() | 删除数组的第一个元素 | 删除的元素 |
splice() | 从数组中删除项目(start,howmany) | 删除的项目 |
非变异方法
方法名 | 用法 | 返回值 |
---|---|---|
join() | 将数组拼接为字符串(括号内可自定义分隔符,默认为逗号) | 字符串 |
concat() | 将多个数组拼接成一个数组 | 拼接后的数组 |
slice() | 从已有数组中返回选定的元素[start,end) | 选中的元素数组 |
toString() | 将数组转换为字符串 | 字符串 |
valueOf() | 返回数组对象本身 | 数组对象本身 |
二十七.String常用方法
方法名 | 用法 |
---|---|
charAt(index) | 返回指定索引位置的字符 |
charCodeAt(index) | 返回指定索引位置的字符编码 |
indexOf(str,index) | 返回index后,首次出现的位置 |
lastIndexOf(str,index) | 返回index前,末次出现的位置 |
toLowerCase()/toUpperCase | 转为大写/转为小写 |
substr(start,howmany) | 从已有字符串中截取字符串 |
substring/slice(start,stop)[stop可省略,直接到最后一位] | 从已有字符串中截取字符串 |
split(分隔符,限制数组长度) | 将字符串根据分隔符分割为字符串数组 |
十.原生实现Ajax
- readyState
0:请求未初始化
1:服务器连接已建立
2:请求已接收
3:请求处理中
4:请求已完成,且响应已就绪
- HTTP状态码
200 请求成功
301 资源(网页等)被永久转移到其他URL
404 请求的资源(网页等)不存在
500 服务器内部错误
(1)发起get请求
const xhr=new XMLHttpRequest();
xhr.open('get','/users',true); //传参 xhr.open('get','/users?name=jack&age=19',true)
xhr.onreadystatechange=function(){
if(xhr.readyState===4){
if(xhr.status===200){
return xhr.responseText;
}else{
return 'error';
}
}
};
xhr.send();
(2)发起post请求
const xhr=new XMLHttpRequest();
xhr.open('post','/users',true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.onreadystatechange=function(){
if(xhr.readyState===4){
if(xhr.status===200){
return (JSON.parse(xhr.responseText));
}else{
return 'error';
}
}
};
xhr.send('name=jack&age=19');
postMessage
postMsg() {
let iframe = document.getElementById("map");//获取到iframe
iframe.contentWindow.postMessage( //使用postMessage进行跨域传输
{ //所需传输的数据(具体参数见下表)
data: {
cmd: "calcPath",
data: {}
}
},
"*"
);
}
window.addEventListener("message", function(e) {
if (e.origin === "https://fljs.jchc.cn:8888") {
console.log(e.data.message);//如有数据不正确会在此处报错
}
});