每日一题更新(贴近面试真题)

261 阅读12分钟

2022/05/25

20.vue-router hash 和 history 模式原理,abstract模式了解

  • hash通过监听hashchange进行路由切换
  • history通过监听popstate进行路由切换. 追问:pushState和replaceState会触发onpopState吗?
    只有当浏览器前进后退、调用history.back .forward .go的时候才会触发onpopState

2022/05/24

19.js监听事件回调函数参数event的target和currentTarget分别代表什么?

  • target返回的是触发事件的元素
  • currentTarget返回的是事件绑定的元素

2022/05/23

18.手写自测:手写bind方法

2022/05/19

17.通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片?

  1. 没有跨域问题,一般这种上报数据,代码要写通用的;(排除ajax)
  2. 不会阻塞页面加载,影响用户的体验,只要new Image对象就好了;(排除JS/CSS文件资源方式上报)
  3. GIF的最低合法体积最小(最小的BMP文件需要74个字节,PNG需要67个字节,而合法的GIF,只需要43个字节);(比较PNG/JPG)
  4. 能够完成整个 HTTP 请求+响应(尽管不需要响应内容),触发 GET 请求之后不需要获取和处理数据、服务器也不需要发送数据

2022/05/18

16.301(永久重定向)和302(临时重定向)对SEO有什么影响?

  1. 301重定向,主要是指从A完全跳转到B,在这个过程中,A页面的所有权限,都完全传递给B页面(旧网页中的流量及权重将会导向新网页),甚至是A页面的惩罚,使用不当也会传递。
  2. 302重定向,主要是只因为一些临时事件的发生(会保留旧网址的收录、排名、权重),我们短期内,从A页面,占时跳转到B页面展示,等到事情完结之后,我们仍然会采用A页面。

2022/05/17

15.PWA是什么?

Progressive Web App 渐进式网页应用 它是一种理念,使用多种技术增强 web app 功能,使网页应用可以呈现和原生应用相似的体验,不能包含 OS 原生代码

特性
  1. 安全可靠:通过 Service Worker 技术实现实时下载,可以进行离线缓存
  2. 访问快:首屏可以部署在浏览器,有平滑的动态效果和快速的页面响应
  3. 响应式界面
  4. 可以直接将 Web 应用添加到主屏幕,提供全屏幕体验(支持 PWA 的浏览器和手机应用
功能
  1. 手机应用配置:mainfest.json
  2. 离线缓存:Web Worker + HTTPS + Cache Api + indexedDB
  3. 实时消息推送
  4. 数据及时更新
优势
  1. 不需要第三方迭代,服务器部署即可
  2. 渐进式升级,用到的技术点可以逐步升级
劣势
  1. 浏览器支持率还不够高
  2. 底层硬件的调用依赖第三方库,如打开摄像头
  3. 国内某些手机厂商在 Android 系统上屏蔽了 PWA
支持情况
  1. 谷歌:web.dev 宣传推广 PWA,介绍关键性技术为主 Squoosh.app 图片压缩工具
  2. 微软
  3. IOS
  4. Twitter Flipboard
  5. 微博 淘宝 豆瓣 饿了么 (PWA拓展)

2022/05/16

14.跨域请求为什么要options请求?什么是复杂请求?

options 请求作用

去嗅探某个请求在对应的服务器中都支持哪种请求方法,形式是在前端中我们一般不会主动发起这个请求,但是往往你可以看到浏览器中相同的请求发起了 2 次,跨域共享标准规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求

复杂请求

2022/05/13

13.vue2 computed是怎么做的缓存?

2022/05/12

13.vue2中 全局,对象,组件 的同名mixin在组件中的执行顺序是什么?最终的结果是什么?

2022/05/11

12.浏览器进程有哪些?线程有哪些?怎么通信的?

2022/05/10

11.你的vue项目中用到装饰器的场景和用到自定义指令的场景有哪些?

2022/05/09

10.什么是函数式编程?

2022/05/07

9.rollup和webpack相比较都有什么特点?为什么推荐库的打包用rollup,而实际开发的项目更青睐webpack呢?

webpack:拆分代码,按需加载
Rollup:所有资源放在同一个地方,一次性加载
webpack需要自己配置并且打包出来的代码非常臃肿,所以对于库文件和UI组件,rollup更加适合

2022/05/06

8.vue2具名插槽和作用域插槽的实现原理

具名插槽
1.父组件在要分发的标签里添加 slot="xxx" 属性
2.子组件在对应分发的位置的 slot标签 里,添加 name="xxx" 属性
3.然后就会将对应的标签放在对应的位置了。
作用域插槽(用作一个 (能被传递数据的) 可重用模板,来代替已经渲染好的元素):
1.在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样。
2.在父组件中,通过 slot-scope="scoped" 的形式,获取子组件传递过来的数据,该数据对象的别名为 scoped

2022/05/05

7.link标签上的preload、prefetch、dns-prefetch、preconnect属性分别都是干嘛的?有什么应用场景?

  • preload 容易和prefetch混淆, 这里解释一下
  1. prefetch 是预加载,是对用户接下来很可能会使用到的资源的预先下载。
  2. preload 本质上是影响资源的加载顺序,把可能后置下载的资源前置下载。
使用场景举例
当资源没有直接体现在html中,而是隐藏在css或是js里,
preload可以提前告知浏览器隐藏资源的存在,
以便浏览器做出最优的安排。
  • prefetch 预加载。在浏览器空闲时下载资源。这就是真正的资源下载了,比dns-prefetch多走了好几步。href 请写上具体的资源名称。

    使用场景举例 在用户阅读当前页时,提前准备“下一页”内容。

  • dns-prefetch 提前解析域名。只解析域名,不会下载任何资源,因此 href 通常写入第三方域名

    使用场景举例 用户很可能点击某个链接,下载跨域图片。如果当前页面引入了 dns-prefetch,当用户真正点链接时,dns的解析早已完成,省去了一些时间。在复杂网络场景下,会有较好的效果。

  • preconnect 提前建立连接。比dns-prefetch多走了两步,除了完成dns解析之外,还完成了TCP握手,TLS握手(https情况下)

    使用场景举例 同dns-prefetch

2022/04/29

6.for…in,for…of ,for await … of,forEach的区别

645a8e83b1e35ba70fe5494b0c2a312.png

commonjs代码怎么变成esm?

babel transform rollup/plugin-commonjs script-loader imports-loader

2022/4/28

5.vuex中的mutaion里能写异步吗?为什么?

可以,但不推荐。mutation是用来做同步操作的。每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。

官方文档说明:“在 mutation 中混合异步调用会导致你的程序很难调试。例如,当你能调用了两个包含异步
回调的 mutation 来改变状态,你怎么知道什么时候回调和哪个先回调呢?这就是为什么我们要区分这两个概念。
在 Vuex 中,我们将全部的改变都用同步方式实现。我们将全部的异步操作都放在Actions中。”

2022/4/27

4.123['toString'].length + 123 的输出值是多少?

function的length,就是第一个具有默认值之前的参数个数。 在函数的形参中,还有剩余参数这个东西,那如果具有剩余参数,会是怎么算呢?

function fn1(name, ...args) {}

console.log(fn1.length) // 1 可以看出,剩余参数是不算进length的计算之中的。

所以,123['toString'].length + 123 = ?的答案是124

总结:length 是函数对象的一个属性值,指该函数有多少个必须要传入的参数,即形参的个数。形参的数量不包括剩余参数个数,仅包括第一个具有默认值之前的参数个数

5.bind() 连续调用多次,this的绑定值是什么呢?

var bar = function(){
    console.log(this.x);
}
var foo = {
    x:3
}
var sed = {
    x:4
}
var func = bar.bind(foo).bind(sed);
func(); //?
  
var fiv = {
    x:5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func(); //?

两次都仍将输出 3 ,而非期待中的 4 和 5 。 原因是,在Javascript中,多次 bind() 是无效的。 更深层次的原因, bind() 的实现,相当于使用函数在内部包了一个 call / apply ,第二次 bind() 相当于再包住第一次 bind() ,故第二次以后的 bind 是无法生效的。

2022/4/26

3.请说出/画出浏览器每一帧都做了什么?

前提知识:一般浏览器的刷新率为60HZ,即1秒钟刷新60次。1000ms / 60hz = 16.6 ,大概每过16.6ms浏览器会渲染一帧画面

  • 渲染流程
    • 浏览器进程:负责控制界面展示、用户交互、子进程管理等功能
    • 渲染器进程:负责将 HTML\CSS\JS 转化为用户可以与之交互的网页。渲染引擎如 webkit、blink 和 JS 引擎 V8 都是在该进程之中
    • GPU 进程:GPU 进程原本是为了实现 3D CSS 效果,但是随后页面、Chrome 的 UI 都采用 GPU 来绘制,是 GPU 成为了重要需求,于是增加了 GPU 进程
    • 网络进程:负责页面的网络资源加载
    • 插件进程:负责插件的运行,由于插件可能崩溃,需要插件进程其他进程隔离。注意,插件并不是我们常用的浏览器拓展,plugin 和 extension 是不同的。
    • 缓存进程:负责处理页面资源缓存和清理。
参考:

2022/4/25

2.package.json中dependencies、devDependencies、peerDependencies、optionalDependencies 、bundledDependencies / bundleDependencies的区别是什么?

  • dependencies:依赖是会被最终构建到部署环境的
npm install lodash 
yarn add lodash
  • devDependencies:开发过程中的依赖包
npm install -production
npm install sass-loader --save-dev 
yarn add sass-loader --dev
  • peerDependencies:同等依赖,或者叫同伴依赖,用于指定当前包(也就是你写的包)兼容的宿主版本(当别人使用我们的插件时,peerDependencies就会告诉明确告诉使用方,你需要安装该插件哪个宿主版本)
    • 注意:npm 1 与 npm 2 会自动安装同等依赖,npm 3 不再自动安装,会产生警告!手动在package.json文件中添加依赖项可以解决。
  • optionalDependencies:可选依赖,如果有一些依赖包即使安装失败,项目仍然能够运行或者希望npm继续运行,就可以使用optionalDependencies。另外optionalDependencies会覆盖dependencies中的同名依赖包,所以不要在两个地方都写
  • bundledDependencies / bundleDependencies:打包依赖,bundledDependencies是一个包含依赖包名的数组对象,在发布时会将这个对象中的包打包到最终的发布包里(必须先在devDependencies或dependencies声明过,否则打包会报错)
npm pack

2022/4/24

1.什么是长任务?长任务一般由什么原因引起?怎样解决?(面试相关问:页面卡顿怎么定位?)

长任务:超过 50ms(用户就能感知到渲染卡顿和交互的卡顿) 的任务就会被认为是 long task

引起长任务的原因:js是单线程,执行顺序是依靠任务队列的任务来执行的。当某个任务执行需要耗费大量的时间时,就会引起长任务。需要异步任务帮助来处理这个问题。

查看页面是否存在长任务的方法

打开控制多台的 performance的左上角的点----->刷新页面----->stop------->任务里右上角有小红标签的就是长任务

解决方式:定时器,时间分片,Web Worker

定时器

原理:把长任务推入任务队列,等到同步代码执行完毕后再处理;

注意:setTimeout不能处理过长任务,否则用户仍会搞到卡顿

示例:无较好,能一看就明白的,示例待补充

时间分片

原理:将长任务分割成若干小任务执行,并在执行小任务的间隔中把主线程的控制权让出来,这样就不会导致UI卡顿

应用:React 的 Fiber 技术核心思想也是时间分片,Vue 2.x 也用了时间分片,只不过是以组件为单位来实施分片操作,由于收益不高 Vue 3 把时间分片移除了。

示例: 存在长任务:

// style
@keyframes move {
    from {
        left: 0;
    }
    to {
        left: 100%;
    }
}
.move {
    position: absolute;
    animation: move 5s linear infinite;
}

// dom
<div class="move">123123123</div>

// script
function fnc () {
    let i = 0
    const start = performance.now()
    while (performance.now() - start <= 5000) {
        i++
    }

    return i
}

setTimeout(() => {
    fnc()
}, 1000)

去除长任务:

// 精准时间分片
function timeSlice_ (fnc, time = 25, cb = setTimeout) {
    if(fnc.constructor.name !== 'GeneratorFunction') return fnc()

    return function (...args) {
        const fnc_ = fnc(...args)
        let data

        return new Promise(async function go (resolve, reject) {
            try {
                const start = performance.now()

                do {
                    data = fnc_.next(await data?.value)
                } while (!data.done && performance.now() - start < time)

                if (data.done) return resolve(data.value)

                cb(() => go(resolve, reject))
            } catch(e) {
                reject(e)
            }
        })
    }
}

setTimeout(async () => {
    const fnc1 = timeSlice_(fnc_)
    let start = performance.now()

    console.log('开始')
    const num = await fnc1()
    console.log('结束', `${(performance.now() - start)/ 1000}s`)
    console.log(num)
}, 1000);

Web Worker

原理:在后台创建独立于主线程的其他线程,把一些费时费力的长任务交给 Web Worker。 缺点:不能操作dom

参考: