js常规基础题

46 阅读2分钟

无聊瞎练习的js基础题 ,基础不牢,地动山摇

预备快给我练起来.gif

#️⃣ 1. 变量提升:var vs let

console.log(a);
var a = 10;

console.log(b);
let b = 20;

输出:

undefined
ReferenceError: b is not defined

原因:

var 会变量提升(Hoisting)

声明提升,但值不会提升 → 所以打印为 undefined

let / const 也会提升,但存在“暂时性死区”(TDZ)

在 TDZ 内访问会直接报错 → b is not defined


#️⃣ 2. this 指向问题

const obj = {
  name: "alex",
  getName() {
    return this.name;
  }
};

const fn = obj.getName;
console.log(fn()); // undefined

原因:

✔ 独立调用函数时 this 指向全局

在浏览器中:this === window
window 上没有 name → undefined

解决:

const fn = obj.getName.bind(obj);
console.log(fn()); // alex

#️⃣ 3. JS 任务队列:同步、微任务、宏任务

console.log(1);

setTimeout(() => console.log(2));

Promise.resolve().then(() => console.log(3));

console.log(4);

输出:

1
4
3
2

执行顺序:

同步任务 → 微任务 → 宏任务

微任务:Promise.then
宏任务:setTimeout / setInterval


#️⃣ 4. 防抖 debounce

需求:调用多次,只执行最后一次。

function debounce(fn, delay) {
  let timer;

  return function (...args) {
    const context = this;

    clearTimeout(timer);

    timer = setTimeout(() => {
      fn.apply(context, args);
    }, delay);
  };
}

示例:

const handle = debounce((msg) => console.log(msg), 1000);

handle("A");
handle("B");
handle("C"); // 1秒后只输出 C

补充:箭头函数没有 arguments,只能用 ...args


#️⃣ 5. 深拷贝 deepClone

支持:基本类型、数组、对象、嵌套结构。

function deepClone(obj) {
  if (obj === null || typeof obj !== "object") return obj;

  const clone = Array.isArray(obj) ? [] : {};

  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key]);
    }
  }

  return clone;
}

解决循环应用问题:

map =new WeakMap()
if(map.has(obj)){
  return map.get(obj)
}

#️⃣ 6. 数组扁平化 flat

ES7 最简单写法:

const flat = (arr) => arr.flat(Infinity);

reduce + 递归写法

function flat(arr) {
  return arr.reduce((acc, val) => {
    return acc.concat(Array.isArray(val) ? flat(val) : val);
  }, []);
}

#️⃣ 7. 箭头函数 vs 普通函数

特性普通函数箭头函数
this动态绑定词法作用域(取定义位置的 this)
arguments✔ 有❌ 没有
构造函数 new✔ 可以❌ 不可
prototype✔ 有❌ undefined

本质:箭头函数更像「表达式」,而不是传统函数。


#️⃣ 8. 数组去重(3 种方法)

① Set

const uni = (arr) => [...new Set(arr)];

② filter + indexOf

function uni2(arr) {
  return arr.filter((item, index) => arr.indexOf(item) === index);
}

③ reduce + includes

function uni3(arr) {
  return arr.reduce((acc, val) => {
    if (!acc.includes(val)) acc.push(val);
    return acc;
  }, []);
}

#️⃣ 9. 字符串反转

function reverse(str) {
  return str.split("").reverse().join("");
}

#️⃣ 10. 冒泡排序 & 快速排序


✔ 冒泡排序 Bubble Sort

function bubbleSort(arr) {
  for (let j = 0; j < arr.length; j++) {
    for (let k = 0; k < arr.length - 1 - j; k++) {
      if (arr[k] > arr[k + 1]) {
        [arr[k], arr[k + 1]] = [arr[k + 1], arr[k]];
      }
    }
  }
  return arr;
}

✔ 快速排序 Quick Sort(递归 + 基准点)

function quickSort(arr) {
  if (arr.length <= 1) return arr;

  const pivot = arr[0];

  const left = arr.slice(1).filter(x => x < pivot);
  const right = arr.slice(1).filter(x => x >= pivot);

  return [...quickSort(left), pivot, ...quickSort(right)];
}

#️⃣ 11. 两数之和 Two Sum


① 暴力双层循环

function twoSum(arr, target) {
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] + arr[j] === target) return [i, j];
    }
  }
  return [];
}

② Map 解法(高效)

function twoSum(arr, target) {
  const map = new Map();

  for (let i = 0; i < arr.length; i++) {
    const diff = target - arr[i];

    if (map.has(diff)) {
      return [map.get(diff), i];
    }

    map.set(arr[i], i);
  }
}

核心:

Map 的方法

  • .set(key, value)
  • .get(key)
  • .has(key)

全文总结

这篇《JS 基础题》覆盖了:

  • 变量提升 & this
  • 事件循环
  • 防抖
  • 深拷贝
  • 数组扁平化
  • 箭头函数与普通函数
  • 数组去重
  • 字符串处理
  • 冒泡 & 快排
  • 两数之和(经典算法题)