无聊瞎练习的js基础题 ,基础不牢,地动山摇
#️⃣ 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
- 事件循环
- 防抖
- 深拷贝
- 数组扁平化
- 箭头函数与普通函数
- 数组去重
- 字符串处理
- 冒泡 & 快排
- 两数之和(经典算法题)