记录几个第一次面试的问题

JS

0.1+0.2!=0.3 问题

一句话解释是浮点存储误差问题

IEEE754 标准 64 位双精度浮点数

img

0.1 与 0.2 的二进制:

image-20200702234224195

这里有一个问题,可以明显的看出来这两个数转换为二进制的时候死循环了。。。。。。

所以有误差是肯定的,当把这两个二进制数相加以后,转换为十进制就是以下的效果:

image-20200629192853406

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()
  • ShareArrayBufferAtomics对象,用于从共享内存位置读取和写入

ES9: ps:除了 finally 和 Rest/Spread 基本没用过哎

  • 异步迭代

    支持使用循环异步语法:

    1
    2
    3
    4
    5
    async 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
    11
    const 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
    2
    reLookbehind = /(?<=\D)\d+/; //肯定反向断言
    relookbehindNeg = /(?<!\D)\d+/;
  • 正则表达式 dotAll 模式

    正则表达式中点.匹配除回车外的任何单字符,标记s改变这种行为,允许行终止符的出现,例如:

    1
    2
    /hello.world/.test("hello\nworld"); // false
    /hello.world/s.test("hello\nworld"); // true

    ES10:

  • 更加友好的 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 刷新后页面重载,数据销毁,所以导致了这个问题

解决方法:

  1. loaclStorage 存储

将 this.$store.state.PV 存入到缓存里之后,然后监听页面重载事件,如果页面重新载入了,那就从缓存里读取数据,然后赋值

1
2
3
4
5
6
7
8
9
10
11
created(){
localStorage.getItem('msg') && this.$store.replaceState(
Object.assign(this.$store.state, JSON.parse( // 这里只要获取对象的引用即可
localStorage.getItem("msg")
)
)
)
window.addEventListener("beforeunload",()=>{
localStorage.setItem("msg",JSON.stringify(this.$store.state))
})
}
  1. 插件 vuex-persistedstate

    安装:

    yarn add vuex-persistedstate

    使用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import 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-directionflex-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-growflex-shrinkflex-basis的合集 默认 0 1 auto

  • order:值越小越靠前

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
    17
    const 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
    11
    window.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
    7
    const $ = 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');
    }

    总结几个问题:

  1. 最后的问面试官环节存在问题,应该准备万能问题,不能脑袋一抽瞎白活
  2. 准备一个开场白
  3. 复习以前总结的基础问题,很多已经开始忘记了
  4. 英语单词别瞎白活了,我就不适合说英语。。。。。。
查看评论