面试官:vue中data为啥是一个函数?而new vue实例中又是个对象

180期题目

1. vue中data为啥是一个函数?而new vue实例中又是个对象
2. es6新特性有哪些
3.for循环和map循环有什么区别

上面问题的答案会在第二天的公众号(程序员每日三问)推文中公布

也可以小程序刷题,已收录500+面试题及答案cb27ac5ac7bdc8cff5eb4f337cfbe692.jpeg

179期问题及答案

1. JS是单线程的,为啥JS有异步任务?

JS 是一门单线程的语言,这意味着它一次只能执行一个任务。然而,JS 中引入了异步任务的概念,这是为了解决在执行耗时任务时不阻塞其他代码执行的问题。让我详细解释一下为什么 JS 中有异步任务。

1. 阻塞与非阻塞

在同步编程中,代码按顺序执行,如果有一个耗时的任务,整个程序会被阻塞,直到这个任务完成。这会导致用户体验下降,特别是在前端浏览器环境中。

异步编程的目的是允许程序在执行长时间运行的任务时,能够继续执行其他任务而不阻塞。这种方式称为非阻塞。

2. 事件循环

在 JS 中,异步任务的实现依赖于事件循环机制。JS 运行时环境维护一个主线程,该线程负责执行代码和处理事件。事件循环会不断地检查消息队列,如果有消息(即异步任务完成),则会将消息添加到调用栈中执行。

3. 异步任务的例子

a. 定时器
console.log('Start');

setTimeout(() => {
  console.log('Timeout callback');
}, 1000);

console.log('End');

在这个例子中,setTimeout 是一个异步任务,它会在指定的时间后将回调函数放入消息队列。在这个过程中,主线程可以继续执行其他任务。

b. AJAX 请求
console.log('Start');

fetch('https://api.example.com/data')
  .then(response => response.json())
  .then(data => console.log(data));

console.log('End');

在这个例子中,fetch 发起了一个异步的网络请求,它不会阻塞主线程的执行,而是在请求完成后将回调函数添加到消息队列。

4. 回调函数与 Promise

最初,异步任务主要通过回调函数来实现,但这容易导致回调地狱(callback hell)。为了更好地处理异步操作,ES6 引入了 Promise。

console.log('Start');

const fetchData = () => {
  return new Promise((resolve, reject) => {
    // 异步操作
    setTimeout(() => {
      resolve('Data fetched successfully');
    }, 1000);
  });
};

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error(error));

console.log('End');

Promise 提供了更清晰的异步流程控制,避免了回调地狱,同时使错误处理更为灵活。

总结

虽然 JS 是单线程的,但通过引入异步任务,它能够在执行耗时任务时不阻塞其他代码的执行,从而提高程序的性能和用户体验。异步任务通过事件循环和回调函数的方式实现,而现代 JS 还引入了 Promise 和 async/await 等机制,使异步编程更加便利和可读。

2. vue-router有哪几种路由卫士?

Vue Router 提供了多种路由卫士(Route Guards)来允许开发者在导航过程中执行代码。这些路由卫士可以帮助你控制导航的行为。以下是 Vue Router 中常用的路由卫士:

  1. 全局前置守卫 (beforeEach):

  • 使用方式:router.beforeEach((to, from, next) => {})

  • 在路由切换开始时调用,常用于进行全局的身份验证、权限控制等。

全局解析守卫 (beforeResolve):

  • 使用方式:router.beforeResolve((to, from, next) => {})

  • 在导航被确认之前调用,用于异步路由组件解析完成之后执行一些操作。

全局后置守卫 (afterEach):

  • 使用方式:router.afterEach((to, from) => {})

  • 在导航完成之后调用,常用于记录页面浏览历史、埋点统计等。

路由独享守卫 (beforeEnter):

  • 使用方式:在路由配置中直接添加 beforeEnter 属性

  • 仅对单个路由生效,用于在进入某个路由前执行一些特定的逻辑。

组件内的守卫:

  • beforeRouteEnter: 在路由进入的时候调用,此时组件还未创建。

  • beforeRouteUpdate: 在路由更新时调用,可以在当前路由被复用的时候调用。

  • beforeRouteLeave: 在离开路由时调用,常用于在用户关闭页面或者切换到其他页面前执行一些逻辑。

这些路由卫士可以组合使用,以满足不同场景下的需求。使用路由卫士可以对导航过程中的不同阶段进行控制和定制,从而更好地管理路由。在实际项目中,合理利用这些卫士可以增强应用的稳定性和用户体验。

3. http缓存有哪些?

HTTP 缓存是一种通过在客户端和服务器之间存储资源的副本,以减少数据传输和提高性能的机制。HTTP 协议定义了多种缓存机制,以下是常见的 HTTP 缓存策略:

  1. 强缓存(Freshness)

  • Expires 头: 服务器返回资源时,在响应头中设置一个过期时间,浏览器会在过期时间前使用缓存。例如:

    Expires: Wed, 21 Oct 2022 07:28:00 GMT
  • Cache-Control 头: 提供更灵活的缓存机制,可以设置相对时间、绝对时间或者禁止缓存等,优先级高于 Expires

    Cache-Control: max-age=3600  // 缓存时间为 3600 秒

协商缓存(Validation)

  • Last-Modified 和 If-Modified-Since 头: 当客户端首次请求资源时,服务器会返回资源的最后修改时间(Last-Modified),客户端再次请求时,通过 If-Modified-Since 头将该时间发送给服务器,服务器根据时间判断资源是否有更新。

    Last-Modified: Mon, 18 Jan 2022 12:00:00 GMT
  • ETag 和 If-None-Match 头: 类似于 Last-Modified,但是使用一个唯一的标识符(ETag)代替最后修改时间,如果资源有更新,服务器返回新的 ETag,客户端再次请求时通过 If-None-Match 判断。

    ETag: "abcd1234"

Cache-Control 扩展:

  • no-store: 禁止缓存,每次请求都要向服务器重新获取资源。

    Cache-Control: no-store
  • no-cache: 强制确认缓存,客户端每次请求都要向服务器验证资源是否过期。

    Cache-Control: no-cache
  • must-revalidate: 在过期之后,强制向服务器进行验证,如果无法验证则不能使用缓存。

    Cache-Control: must-revalidate

这些缓存策略可以单独使用或者结合使用,根据具体的场景和需求选择合适的策略,以优化资源加载和提高应用性能。在开发中,合理利用 HTTP 缓存可以减少不必要的网络请求,提升用户体验。

因为微信公众号修改规则,如果标星或点在看,你可能会收不到我公众号文章的推送,原创不易,请大家将本公众号星标,看完文章后记得点下赞或者在看,谢谢各位!

学习不打烊,充电加油只为遇到更好的自己,每天早上9点纯手工发布面试题,每天坚持花20分钟来学习与思考,在千变万化,类库层出不穷的今天,不要等到找工作时才狂刷题,提倡每日学习。

  • 16
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值