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

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,页面状态如下:

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

相关推荐
PandaCave2 分钟前
vue工程运行、构建、引用环境参数学习记录
javascript·vue.js·学习
软件小伟4 分钟前
Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
前端·javascript·vue.js
醉の虾26 分钟前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js
张小小大智慧34 分钟前
TypeScript 的发展与基本语法
前端·javascript·typescript
hummhumm44 分钟前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j
asleep7011 小时前
第8章利用CSS制作导航菜单
前端·css
hummhumm1 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架
幼儿园的小霸王2 小时前
通过socket设置版本更新提示
前端·vue.js·webpack·typescript·前端框架·anti-design-vue
疯狂的沙粒2 小时前
对 TypeScript 中高级类型的理解?应该在哪些方面可以更好的使用!
前端·javascript·typescript
gqkmiss2 小时前
Chrome 浏览器 131 版本开发者工具(DevTools)更新内容
前端·chrome·浏览器·chrome devtools