『VUE』QL面试真题2025.02(详细图文注释)


欢迎关注 『VUE』 专栏,持续更新中
欢迎关注 『VUE』 专栏,持续更新中

CSS

  1. opacity: 0visibility: hiddendisplay: none 这三者有什么区别?

    • opacity: 0

      :

      • 设置元素的透明度为 0,元素仍然存在于页面中,占据空间,但完全透明,用户不可见,且仍可操作。
    • visibility: hidden

      :

      • 隐藏元素,但元素仍占据空间,无法看到,但可以接受 JavaScript 操作(如点击事件)。它不同于 display: none,不会影响页面布局。
    • display: none

      :

      • 完全移除元素,元素不再占据页面布局空间,也不可见。浏览器会将其完全忽略,任何与之相关的事件也不会被触发。

ES6

  1. 请简述 ES6 中 Symbol 类型的作用。

    • Symbol 是 ES6 新增的一种原始数据类型,表示独一无二的值。它常用于创建对象属性的唯一标识符,避免属性名冲突。Symbol 是不可变的、不可重复的。
    const symbol1 = Symbol('description');
    const symbol2 = Symbol('description');
    console.log(symbol1 === symbol2); // false
    
  2. ES6 中 WeakMap 的实际用途是什么? 和 Map 有什么不同?

    • WeakMapMap 类似,用于存储键值对,但它的键是 弱引用,即当键不再被使用时,垃圾回收器会自动清理相关的键值对,避免内存泄漏。

    • Map 的区别

      • WeakMap 的键必须是对象,且键值对会在对象被垃圾回收时自动删除。
      • Map 的键可以是任意类型。
    let obj = {};
    let weakmap = new WeakMap();
    weakmap.set(obj, 'value');
    obj = null;  // obj 被垃圾回收,weakmap 中的条目也会被清除
    
  3. Promise 有几种状态?

    • Pending(等待):Promise 处于初始状态,操作尚未完成。
    • Fulfilled(已完成):操作成功完成,并返回结果。
    • Rejected(已拒绝):操作失败,返回错误。
    let promise = new Promise((resolve, reject) => {
      // Some async operation
      resolve('Success');
    });
    
  4. 请使用解构赋值,实现两个变量值的交换。

    let a = 5;
    let b = 10;
    [a, b] = [b, a];
    console.log(a, b);  // 10 5
    

综合

  1. webpack 中 loader 和 plugin 的区别是什么?

    • Loader

      • 用于处理文件的转换,允许 Webpack 处理非 JavaScript 文件(如 .css, .scss, .html 等)。它会在 Webpack 构建过程中转换文件,通常是在模块编译阶段使用。
      • 示例:babel-loader(将 ES6 转换为 ES5)、style-loader(将 CSS 嵌入 JS 文件)。
    • Plugin

      • 用于扩展 Webpack 的功能,通常在构建完成之后运行,处理代码压缩、资源优化等。
      • 示例:HtmlWebpackPlugin(生成 HTML 文件并自动引入打包后的文件)、UglifyJsPlugin(压缩 JS 文件)。
  2. 简述下 SASS 和 LESS 的相似与不同点。

    • 相似点

      • SASS 和 LESS 都是 CSS 预处理器,允许使用变量、嵌套规则、混入(mixin)等功能,增强 CSS 的可维护性和可读性。
    • 不同点

      • 语法:SASS 支持两种语法:一种是带有大括号的语法(.scss),另一种是没有大括号和分号的语法(.sass)。LESS 只有一种语法。
      • 功能:SASS 提供了更多高级功能,如控制指令(如 @if, @for)等。
  3. 简述下常用的排序算法有哪几种,各自的原理是什么?

    • 冒泡排序(Bubble Sort):通过多次比较相邻元素,逐步将较大的元素“冒泡”到数组的末端。
    • 选择排序(Selection Sort):每次选择未排序部分中的最小值,与当前元素交换位置。
    • 插入排序(Insertion Sort):通过遍历数组,将每个元素插入到已排序的部分中。
    • 快速排序(Quick Sort):选择一个基准元素,将数组分成两部分,一部分小于基准,一部分大于基准,然后递归排序。
    • 归并排序(Merge Sort):通过分治法,将数组分成两部分,分别排序,然后合并。

TypeScript

  1. TS 中如何在从子类调用到父类的构造函数?

    • 使用 super() 来调用父类的构造函数。
    class Animal {
      constructor(public name: string) {}
    }
    
    class Dog extends Animal {
      constructor(name: string) {
        super(name); // 调用父类的构造函数
      }
    }
    
  2. 简述下 Omit 类型。

    • Omit<T, K> 用于从类型 T 中排除掉键 K,生成一个新类型。
    type Person = {
      name: string;
      age: number;
      gender: string;
    };
    
    type PersonWithoutAge = Omit<Person, 'age'>; // { name: string, gender: string }
    
  3. 什么是装饰器,它有什么用,如何使用?

    • 装饰器是 ES7 提案中的一个特性,用于对类、方法、属性等进行修改和扩展。它允许你通过注解的方式对代码进行增强。
    • 装饰器可以用于:
      • 类装饰器:修改类的行为。
      • 方法装饰器:修改方法的行为。
      • 属性装饰器:修改属性的行为。
    • 使用方法:
    function log(target: any, propertyName: string) {
      console.log(`${propertyName} is called`);
    }
    
    class Person {
      @log
      sayHello() {
        console.log('Hello');
      }
    }
    
  4. anyunknown 类型有什么区别?

    • any:表示任意类型,可以赋值给任何类型的变量,且编译时不会报错。
    • unknown:也表示任意类型,但在使用 unknown 类型之前,必须进行类型检查。
    let a: any = 5;
    let b: unknown = 5;
    
    a = "string"; // 正常
    b = "string"; // 正常
    // b.toUpperCase(); // 编译报错,需要类型检查
    
  5. type 关键字的作用是什么?

    • type 用于定义类型别名,允许你为一种类型创建一个别名,可以是基本类型、联合类型、交叉类型、函数类型等。
    type StringOrNumber = string | number;
    type Person = { name: string, age: number };
    

Vue

  1. Vue 组件间如何通信?

    • 父子组件通信:父组件通过 props 向子组件传递数据,子组件通过 $emit 向父组件传递事件。
    • 兄弟组件通信:通过一个公共的父组件或使用 Vuex。
    • 跨组件通信:使用 Vuex 或事件总线(bus)来实现。
    • 自定义事件:子组件通过 $emit 向父组件发送事件,父组件通过监听事件处理数据。
    <child-component @change="handleChange" />
    

2. Vue 中 key 值的作用是什么?

  • key 是 Vue 在虚拟 DOM 中用于 唯一标识 每个节点的属性,可以帮助 Vue 高效更新 DOM
  • v-for 列表渲染中,key 主要用于优化 Diff 算法,避免不必要的重新渲染,提高性能。
  • 如果不设置 key,Vue 可能会复用元素,导致意想不到的 UI 问题。

示例

<li v-for="item in list" :key="item.id">{{ item.name }}</li>
  • 这里 key="item.id" 确保 Vue 在更新列表时能正确识别每个 li
3. Vue 组件中的 data 为什么是一个函数?
  • 在 Vue 组件中,data 必须是 返回对象的函数,而不是直接写一个对象。
  • 这样可以保证每个组件实例都有自己独立的数据,防止数据共享导致的意外修改。

示例

export default {
  data() {
    return {
      message: "Hello Vue",
    };
  },
};

如果 data 是一个对象,而不是函数,则所有组件实例共享同一个 data,导致数据互相影响。


JavaScript

1. 什么是防抖和节流?有什么区别?
  • 防抖(Debounce):如果在 n 毫秒内再次触发事件,则重新计时,只有当 n 毫秒内没有触发事件,才执行。
  • 节流(Throttle):规定 n 毫秒内最多执行一次事件处理函数。

示例

// 防抖
function debounce(fn, delay) {
  let timer;
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
}

// 节流
function throttle(fn, delay) {
  let lastTime = 0;
  return function (...args) {
    let now = Date.now();
    if (now - lastTime > delay) {
      fn.apply(this, args);
      lastTime = now;
    }
  };
}
2. callapply 的区别是什么?
  • callapply 作用相同,都是用于修改函数的 this 指向,并立即执行。

  • 区别

    • call(thisArg, arg1, arg2, ...) 传递参数时,参数列表 形式。
    • apply(thisArg, [arg1, arg2, ...]) 传递参数时,数组 形式。

示例

function greet(name, age) {
  console.log(`Hello ${name}, you are ${age} years old`);
}

greet.call(null, "Alice", 25);
greet.apply(null, ["Alice", 25]);
3. for...inObject.keys() 的区别是什么?
  • for...in

    • 遍历对象的 可枚举属性(包括原型链上的可枚举属性)。
  • Object.keys()

    • 返回对象自身的 可枚举属性(不包括原型链上的属性)。

示例

const obj = { a: 1, b: 2 };
Object.prototype.c = 3;

for (let key in obj) {
  console.log(key); // a, b, c
}

console.log(Object.keys(obj)); // ["a", "b"]
4. ===== 的区别
  • ==(宽松相等):会进行 类型转换,然后比较值是否相等。
  • ===(严格相等):不会进行类型转换,必须值和类型都相等。

示例

console.log(1 == "1");  // true  (类型转换)
console.log(1 === "1"); // false (不同类型)
5. 如何判断一个对象是否为数组?

方法 1:Array.isArray()(推荐)

console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false

方法 2:instanceof

console.log([] instanceof Array); // true
6. 代码输出结果
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}

输出:

0
1
2

解析

  • let 具有块级作用域,每次循环 i 都是一个新的变量,不会影响下一个循环。
7. 代码输出结果
console.log(+true);

输出

1

解析

  • +true 等价于 Number(true)true 转换为 1
8. 代码输出结果
const promise = new Promise((resolve, reject) => {
  console.log(1);
  resolve();
  console.log(2);
});

promise.then(() => {
  console.log(3);
  console.log(4);
});

输出

1
2
3
4

解析

  1. console.log(1) 立即执行。
  2. resolve() 不会阻止 后面的 console.log(2)
  3. promise.then()微任务,等同步代码执行完后再执行 console.log(3)console.log(4)

总结

  • Vue 的 key 用于优化 DOM 更新,data 需返回对象以保证实例独立性。
  • 防抖 延迟执行,节流 限制频率。
  • callapply 作用相同,参数传递方式不同。
  • === 不进行类型转换,== 进行类型转换。
  • setTimeout 结合 let 形成块级作用域,按顺序输出 0, 1, 2
  • +true 的结果是 1,因为 true 转换为 Number
  • Promise.then() 是微任务,先执行同步代码再执行微任务。

希望这些答案对你有所帮助!🚀

问题解析与解答


9. 代码输出的结果

const promise = new Promise((resolve, reject) => (
  resolve("success1");
  reject("error");
  resolve("success2");
));

promise
  .then((res) => {
    console.log("then:", res);
  })
  .catch((err) => {
    console.log("catch:", err);
  });
错误
  1. new Praise 这个类不存在,应该是 new Promise
  2. reject('error") 双引号错误,应该是 reject("error")
  3. resolve("success1") 之后 reject("error")resolve("success2") 不会执行,因为 Promise 状态只会改变一次。
最终执行
const promise = new Promise((resolve, reject) => {
  resolve("success1"); // 先执行 resolve
  reject("error");     // 不会执行
  resolve("success2"); // 不会执行
});

promise
  .then((res) => {
    console.log("then:", res);
  })
  .catch((err) => {
    console.log("catch:", err);
  });
输出
then: success1
  • 原因:Promise 状态一旦改变就不会再变resolve("success1") 使 Promise 进入 fulfilled 状态,后续的 reject("error")resolve("success2") 都不会执行。

10. 用 Promise 实现红绿黄灯交替亮灯

需求:

  • 红灯 亮 3 秒
  • 绿灯 亮 1 秒
  • 黄灯 亮 2 秒
  • 循环执行
代码实现
function red() {
  console.log("red");
}
function green() {
  console.log("green");
}
function yellow() {
  console.log("yellow");
}

function delay(time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

function light() {
  Promise.resolve()
    .then(() => {
      red();
      return delay(3000);
    })
    .then(() => {
      green();
      return delay(1000);
    })
    .then(() => {
      yellow();
      return delay(2000);
    })
    .then(light); // 递归调用,形成循环
}

light();
输出
red
(3秒后)
green
(1秒后)
yellow
(2秒后)
(red 3s → green 1s → yellow 2s 循环)

解释

  1. delay(time) 返回一个 Promise,在 time 毫秒后 resolve
  2. light() 依次执行 red()green()yellow(),并递归调用自身,使灯不断循环亮起。

11. 实现一个数组去重的方法

方法 1:使用 Set(推荐)
function uniqueArray(arr) {
  return [...new Set(arr)];
}

console.log(uniqueArray([1, 2, 3, 3, 2, 1])); // [1, 2, 3]
  • Set 是 ES6 提供的无重复值集合,利用 Set 直接去重。
方法 2:使用 filter()
function uniqueArray(arr) {
  return arr.filter((item, index) => arr.indexOf(item) === index);
}

console.log(uniqueArray([1, 2, 3, 3, 2, 1])); // [1, 2, 3]
  • indexOf(item) 返回第一次出现的位置,如果当前位置 indexindexOf(item) 相等,说明是第一次出现,保留该值。
方法 3:使用 reduce()
function uniqueArray(arr) {
  return arr.reduce((acc, cur) => {
    if (!acc.includes(cur)) acc.push(cur);
    return acc;
  }, []);
}

console.log(uniqueArray([1, 2, 3, 3, 2, 1])); // [1, 2, 3]
  • reduce 逐步累加非重复元素。

总结

题目关键点代码示例
Promise 状态问题Promise 状态一旦改变,不会再次变化只执行第一个 resolve("success1")
灯光交替亮起Promise + 递归调用 实现循环then(light) 递归执行
数组去重Set 最简洁,filter()reduce() 可替代new Set(arr)

总结

大家喜欢的话,给个👍,点个关注!给大家分享更多计算机专业学生的求学之路!

版权声明:

发现你走远了@mzh原创作品,转载必须标注原文链接

Copyright 2024 mzh

Crated:2024-3-1

欢迎关注 『VUE』 专栏,持续更新中
欢迎关注 『VUE』 专栏,持续更新中
『未完待续』


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发现你走远了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值