易忘,但常问的面试题(九)

56、说一下 v-if 与 v-show 的区别

1、手段

  • v-if 是动态的向 DOM 树内添加或者删除 DOM 元素
  • v-show 是通过设置 DOM 元素的 display 样式属性控制显隐

2、编译过程

  • v-if 切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件
  • v-show 只是简单的基于 css 切换

3、编译条件

  • v-if 是惰性的,如果初始条件为假,则什么也不做。只有在条件第一次变为真时才开始局部编译
  • v-show 是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且 DOM 元素保留

4、性能消耗

  • v-if 有更高的切换消耗
  • v-show 有更高的初始渲染消耗

5、使用场景

  • v-if 适合运营条件不大可能改变
  • v-show 适合频繁切换

57、 如何让 CSS 值在当前的组件中起作用

在 vue 文件中的 style 标签上,有一个特殊的属性:scoped。当一个 style 标签拥有 scoped 属性时,它的 CSS 样式就只能作用于当前的组件,也就是说,该样式只能适用于当前组件元素。通过该属性,可以使得组件之间的样式不互相污染。如果一个项目中的所有 style 标签全部加上了 scoped,相当于实现了样式的模块化。

scoped 的实现原理

vue 中的 scoped 属性的效果主要通过 PostCSS 转译实现的。PostCSS 给一个组件中的所有 DOM 添加了一个独一无二的动态属性,然后,给 CSS 选择器额外添加一个对应的属性选择器来选择该组件中 DOM,这种做法使得样式只作用于含有该属性的 DOM,即组件内部 DOM。

例如:

转译前

xml 复制代码
<template>

  <div class="example">hi</div>

</template>



<style scoped>

.example {

  color: red;

}

</style>

转译后:

xml 复制代码
<template>

  <div class="example" data-v-5558831a>hi</div>

</template>



<style>

.example[data-v-5558831a] {

  color: red;

}

</style>

58、 0.1 + 0.2 === 0.3 嘛?为什么?

运算时发生了什么?

首先,计算机无法直接对十进制的数字进行运算,这是硬件物理特性已经决定的。这样运算就分成了两个部分:先按照IEEE 754转成相应的二进制,然后对阶运算.

1.进制转换

0.1和0.2转换成二进制后会无限循环

js 复制代码
0.1 -> 0.0001100110011001...(无限循环)
0.2 -> 0.0011001100110011...(无限循环)

IEEE 754标准,通过64位来表示一个数字,会将多余的位数截取掉(进制之间的转换中精度已经损失

  • 第0位:符号位,0表示正数,1表示负数(s)
  • 第1位到第11位:储存指数部分(e)
  • 第12位到第63位:储存小数部分(即有效数字)f

2.对阶运算

对两个二进制数做加法

js 复制代码
  0 01111111100  0.1100110011001100110011001100110011001100110011001101
+ 0 01111111100  1.1001100110011001100110011001100110011001100110011010
= 0 01111111100  10.0110011001100110011001100110011001100110011001100111

对阶后发现,最后一个 1 放不下了,需要舍弃,根据标准当要舍弃一位数时,需要进行0舍1入。如果被舍弃的是 0 什么都不用做,如果被舍弃的是1,则需要补回来。

js 复制代码
0 01111111101 0011001100110011001100110011001100110011001100110011 1(1 多出,需要舍弃)
0 01111111101 0011001100110011001100110011001100110011001100110100  (补 1)

造成不一样的原因:浮点数运算过程中的误差问题

小数在计算机的存储过程中本身就存在精度丢失的问题,然后尾数的位数总共只有 52 位,放不下时会被丢弃,并按照 舍0补1 来弥补导致最终运算结果不相等。

59、 new 一个函数发生了什么

通过 new 去调用一个函数时,这个函数就是一个构造函数

  1. 在内存中创建一个新的空对象;
  2. 构造函数的 prototype 的值会被赋给第 1 步创建的对象的 [[Prototype]] 属性;
  3. 构造函数内部的 this,也会指向第 1 步创建的对象;
  4. 执行函数的内部代码(函数体);
  5. 如果构造函数没有返回非空对象,则返回第 1 步创建的对象(其实也就是 this)。

以下是使用 new 关键字创建对象的基本原理

  1. 创建一个空对象:首先,JavaScript 会创建一个空对象,这个对象将成为新创建对象的实例。

  2. 执行构造函数:接下来,JavaScript 会调用传递给 new 关键字的函数,并将新创建的空对象作为 this 参数传递给该函数。这个函数通常被称为构造函数。

  3. 设置原型:在构造函数内部,可以为新对象设置属性和方法。构造函数的返回值通常是被忽略的,但如果构造函数返回一个对象,那么这个对象将被用作新创建对象的原型。

  4. 原型链:新创建的对象具有一个指向构造函数的原型对象的内部链接,这个链接被称为原型链。通过原型链,新对象可以访问从原型对象继承的属性和方法。

js 复制代码
function Person(name, age) {
  this.name = name;
  this.age = age;
}

// 为原型对象添加方法
Person.prototype.sayHello = function() {
  console.log('Hello, my name is ' + this.name);
}

var person1 = new Person('John', 30);
person1.sayHello(); 

60、 你知道 301、302 状态码是什么嘛?

301 状态码

301 Moved Permanently,永久性重定向。当服务器收到请求后,会告诉浏览器,此资源被分配到了一个新的URL下,此时的浏览器会自动将请求重定向到新的URL下,以后所有的请求都会去请求新的URL。

包含了 第一次请求第二次请求 的情况

  1. 第一次访问原始URL,浏览器向服务器发送请求。
  2. 服务器响应请求,将301状态码最新的资源地址(位于响应头里的location字段) 返回给浏览器。
  3. 浏览器收到301状态码后,向最新的地址发送请求,此时浏览器地址栏里的地址也将变为最新的资源地址。
  4. 浏览器将最新的资源缓存到本地。
  5. 当以后再访问老的URL时,浏览器就不去请求老的URL,而是去请求新的URL。

例如:

js 复制代码
// 老路由
router.get('/301oldLogin', function(req, res, next) {
    // 301永久重定向
    res.redirect(301, '/login/301newLogin');
});

// 新路由
router.get('/301newLogin', function(req, res, next) {
    res.send(`
      <!DOCTYPE html>
      <html>
          <head>
          <meta charset="utf-8" />
          <title>301访问新登录页</title>
          <style>
            * {
                margin: 0;
                padding: 0;
            }
            html, body {
                width: 100%;
                height: 100%;
            }
            div {
                width: 100%;
                height: 100%;
                display: flex;
                justify-content: center;
                align-items: center;
            }
          </style>
          </head>
          <body>
          <div>欢迎登陆新的页面-301</div>
          </body>
      </html>
    `);
});

第一次访问老路由(浏览器里输入:http://localhost:3000/login/301oldLogin),此时的页面状态如下:

第二次访问老路由

  • 第一次访问老url,先请求老的url的资源,再去请求新的url的资源,此时地址栏里的地址将会自动变为新的url。
  • 浏览器将最新的资源地址 与 资源内容缓存到本地。
  • 当再次访问老的url的时候,浏览器直接去请求新的资源地址。

302 状态码

302 Found(临时重定向)。表示资源临时被移动到新的url。浏览器在遇到这个状态码后,同样会将地址栏里的老url替换为新的url,但后续请求依旧会去请求老的url。

  • 浏览器访问老的url,服务端返回302状态码 以及 最新的资源地址。
  • 浏览器得到302状态码,将地址栏变为最新的资源地址,然后去访问最新的地址。
  • 当浏览器再次访问老的url,开始重复第一步。

包含了 第一次请求第二次请求 的状况

例如:

js 复制代码
router.get('/302oldLogin', function(req, res, next) {
    res.redirect(302, '/login/302newLogin');
});

router.get('/302newLogin', function(req, res, next) {
    res.send(`
      <!DOCTYPE html>
      <html>
          <head>
          <meta charset="utf-8" />
          <title>302访问新登录页</title>
          <style>
            * {
                margin: 0;
                padding: 0;
            }
            html, body {
                width: 100%;
                height: 100%;
            }
            div {
                width: 100%;
                height: 100%;
                display: flex;
                justify-content: center;
                align-items: center;
            }
          </style>
          </head>
          <body>
          <div>欢迎登陆新的页面-302</div>
          </body>
      </html>
    `);
});

第一次请求老路由,地址栏输入: http://localhost:3000/login/302oldLogin,页面状态如下:

第二次请求老路由也是一样的结果.

相关推荐
恋猫de小郭4 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅10 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606111 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了11 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅11 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅11 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅12 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment12 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅12 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端