记录几个第一次面试的问题
JS
0.1+0.2!=0.3 问题
一句话解释是浮点存储误差问题
IEEE754 标准 64 位双精度浮点数
0.1 与 0.2 的二进制:
这里有一个问题,可以明显的看出来这两个数转换为二进制的时候死循环了。。。。。。
所以有误差是肯定的,当把这两个二进制数相加以后,转换为十进制就是以下的效果:
JS 变量提升顺序
看以前的博客(认识 JavaScript 细节)
ES6+特性整理:
防忘,很多东西用的使用才能想起来,面试全忘了。。。。。。
ES6:
- let 与 const(块作用域)
- 类(class / extend)
- 模块化(ES6 Module)
- 箭头函数(this 绑定词法上下文)
- 函数参数默认值
- 模板字符串
- 解构赋值
- 延展操作符
- 对象属性简写
- Promise
ES7
- Array.prototype.includes()
**
操作符
ES8:
- async/await
Object.values()
:ps: 这个竟然是 ES8 新增的!!Object.entries()
padStart()
和padEnd()
,填充字符串达到当前长度- 函数参数列表结尾允许逗号
Object.getOwnPropertyDescriptors()
ShareArrayBuffer
和Atomics
对象,用于从共享内存位置读取和写入
ES9: ps:除了 finally 和 Rest/Spread 基本没用过哎
异步迭代
支持使用循环异步语法:
1
2
3
4
5async function process(array) {
for await (const i of array) {
syncDo(i);
}
}Promise.finally()
Rest/Spread 属性: ps:这个是 ES9 新增。。。
正则表达式命名捕获组(Regular Expression Named Capture Groups)
1
2
3
4
5
6
7
8
9
10
11const reDate = /([0-9]{4})-([0-9]{2})-([0-9]{2})/,
match = reDate.exec("2020-06-29"),
year = match[1], // 2020
month = match[2], // 06
day = match[3]; // 29
// 分组匹配
const reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
match = reDate.exec("2020-06-29"),
year = match.groups.year, // 2020
month = match.groups.month, // 06
day = match.groups.day; // 29正则表达式反向断言(lookbehind)
1
2reLookbehind = /(?<=\D)\d+/; //肯定反向断言
relookbehindNeg = /(?<!\D)\d+/;正则表达式 dotAll 模式
正则表达式中点
.
匹配除回车外的任何单字符,标记s
改变这种行为,允许行终止符的出现,例如:1
2/hello.world/.test("hello\nworld"); // false
/hello.world/s.test("hello\nworld"); // trueES10:
更加友好的 JSON.stringify
新增了 Array 的
flat()
方法和flatMap()
方法新增了 String 的
trimStart()
方法和trimEnd()
方法Object.fromEntries()
Symbol.prototype.description
String.prototype.matchAll
Function.prototype.toString()
现在返回精确字符,包括空格和注释简化
try {} catch {}
,修改catch
绑定新的基本数据类型
BigInt
globalThis
import()
Legacy RegEx
私有的实例方法和访问器
很多时候感觉被 babel 惯坏了,不管 ES 几随便写转换完都能用。。。。。。
Vue 常用指令
都用过为啥一问就想不起来。。。。。
v-bind
v-if
v-else
v-show
v-on
v-else-if
v-for
v-once
v-model
v-text
v-html
v-slot
v-clock
Vuex 刷新数据不保留问题:
找了这么篇文章:
https://www.cnblogs.com/zhongchao666/p/9567527.html
这个问题其实挺好理解的,就是 SPA 路由是无跳转路由(可以看我以前的一篇前端路由文章),使用了 Vuex 后用户的刷新会导致 Vuex 数据的重置。
所以我们需要本来有的数据 F5 刷新后页面重载,数据销毁,所以导致了这个问题
解决方法:
- loaclStorage 存储
将 this.$store.state.PV 存入到缓存里之后,然后监听页面重载事件,如果页面重新载入了,那就从缓存里读取数据,然后赋值
1 |
|
插件 vuex-persistedstate
安装:
yarn add vuex-persistedstate
使用:
1
2
3
4
5
6
7
8
9
10
11
12
13import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState(
storage: window.sessionStorage,
reducer(val) {
return {
// 只储存state中的user
user: val.user
}
}
)]
})再看 CSS:
CSS3 新增
过渡:transition
动画:animation
形变: transform
选择器:nth-xx
阴影:box-shadow
边框:border-image
背景:background-clip 背景绘制
反射:webkit-box-reflect:
颜色:rgba 支持
弹性布局:flex
栅格布局:grid
多列布局
盒模型:box-sizing:border-box
媒体查询 @media
Flex 布局
这个地方我真的是,,,,,
Flex 布局:弹性布局
Flex 布局特点:与方向无关
Flex 布局适合简单的线性布局
几个常用的属性:
flex-direction:决定主轴的方向
row: 水平 左->右
rot-reverse:水平 右->左
column:主轴垂直从上到下
column:主轴垂直从下到上
flex-wrap:是否换行
nowrap:默认不换行
wrap:换行,第一行在上
wrap-reverse:换行,第一行在下
flex-flow:
flex-direction
和flex-wrap
的组合justify-content:定义子元素在主轴的对齐方式
flex-start
flex-end
center
space-between
space-around
align-items:定义子元素在侧轴上的对齐方式,主要由 5 种取值:(单行,多行使用 align-content)
strech: 默认值,子元素的高度铺满父元素
flex-start: 子元素从侧轴起点对齐
flex-end: 子元素从侧轴终点对齐
center: 子元素根据侧轴居中对齐
baseline: 根据子元素第一行文字的基线对齐(当字体大小不一致时,突出效果
子元素属性:
flex-grow:当父元素空间有剩余时,将剩余空间分配给各子元素的比例
flex-shrink:各子元素压缩大小,默认为
1
flex-basis:当父元素有剩余空间时,可通过此属性扩充子元素的空间,设置子元素的空间默认为 auto
flex:
flex-grow
、flex-shrink
和flex-basis
的合集 默认 0 1 autoorder:值越小越靠前
HTML5
没问,但是感觉应该顺带整理一下 H5 新增:
语义化标签支持:
新增一些标签:
canvas
svg 支持
音视频(video, radio)
表单新元素(tel,email,range,search,url……)
表单新特性(placeholoder,autocomplete,autofocus,spellcheck)
Web Storage API(localStorage, sessionStorage)
Geolocation:可以请求用户共享他们的位置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17const getPosition = navigator.geolocation.getCurrentPosition;
getPosition(updateLocation, (error) => {
console.log(error);
});
function updateLocation(position) {
const latitude = position.coords.latitude; // 纬度
const longitude = position.coords.longitude; // 经度
const accuracy = position.coords.accuracy; // 准确度
const timestamp = position.coords.timestamp;
}
// 监听位置更新
const watchId = navigator.geolocation.watchPostion(
updateLocation,
handleLocationError
);
// 取消监视
navigator.geolocation.clearWatcher(watcheId);Communication:跨文档消息通信,可以确保 iframe、标签页、窗口间安全地进行跨源通信。*
1
2
3
4
5
6
7
8
9
10
11window.postMessage("hello,world", "http://www.example.com");
window.addEventListener("message", messageHandler, true);
function messageHandler(e) {
switch (e.origin) {
case "friend.example.com":
processMessage(e.data);
break;
default:
break;
}
}XMLHttpRequest Level2:改进 XMLHttpRequest
- 旧版:
- 仅支持文本的数据传输,无法读取和上传二进制
- 传送和接收数据时候,没有进度信息
- 收到同源策略影响
- 新版:
- 可以设置 HTTP 请求时限
- 课程是由 FormData 管理数据
- 支持文件上传
- 可以请求不同域名数据
- 可以获取服务端二进制数据
- 可以获取数据传输和进度信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38//设置超时时间为
xhr.timeout = 3000;
// 监听错误处理
xhr.ontimeout = function (e) {
handleTimeout(e);
};
// 模拟表单提交
const formData2 = new FormData($("#form")); // 初始化已有表单
xhr.open(formData2.method, formData2.action);
xhr.send(formDatat2); //表单提交
// 文件上传
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append("files[]", files[i]);
}
xhr.send(formData);
// 跨域需要浏览器与服务器同时同意这种请求,使用方法与原来方法相同
xhr.open("GET", "https://www.example.com/");
// 接受二进制图像
xhr.open("GET", "/path/to/image.png");
xhr.responseType = "blob";
const binaryData = new Blob([xhr.response], { type: "image/png" });
// 进度信息
// 五个事件
/*
* load事件:传输成功完成。
* abort事件:传输被用户取消。
* error事件:传输中出现错误。
* loadstart事件:传输开始。
* loadEnd事件:传输结束,但是不知道成功还是失败。
*/
xhr.progress = updateProgress;
xhr.upload.onprogress = updateProgress;
function updateProgress(event) {
if (event.lengthComputable) {
var percentComplete = event.loaded / event.total;
}
}- 旧版:
FormData 对象:模拟表单对象
1
2
3
4
5
6
7const $ = document.querySelector;
const formData = new FormData();
const formData2 = new FormData($("#form")); // 初始化已有表单
formData.append("username", "kilic");
formData2.append("passwd", "123");
xhr.open(formData2.method, formData2.action);
xhr.send(formDatat2); //表单提交WebSocket:复用 HTTP 线路的轻量级通信协议
1
2
3
4
5
6
7
8
9
10
11
12
13// 使用:
const socket = new WebSocket('ws://www.example.com');
socket.onopen = (e) => {
socket.send('send data');
}
socket.onmessage = (e) => {
parseData(e.data)
}
socket.onclose = (e) = {
socket.onmessage = null;
console.log('close');
}总结几个问题:
- 最后的问面试官环节存在问题,应该准备万能问题,不能脑袋一抽瞎白活
- 准备一个开场白
- 复习以前总结的基础问题,很多已经开始忘记了
- 英语单词别瞎白活了,我就不适合说英语。。。。。。
- 本文作者:herin
- 本文链接:https://kilicmu.github.io/2020/06/29/%E8%AE%B0%E5%BD%95%E5%87%A0%E4%B8%AA%E7%AC%AC%E4%B8%80%E6%AC%A1%E9%9D%A2%E8%AF%95%E7%9A%84%E9%97%AE%E9%A2%98/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!