90%前端面试必问的12个JS核心,搞懂这些直接起飞!

你是不是也遇到过这样的场景?面试官抛出一个闭包问题,你支支吾吾答不上来;团队代码review时,看到同事用的Promise链一脸懵逼;明明功能实现了,性能却总是差那么一点...

别慌!今天我整理了12个JavaScript核心概念,这些都是2024年各大厂面试的高频考点,也是日常开发中真正实用的硬核知识。搞懂它们,不仅能轻松应对面试,更能让你的代码质量提升一个档次!

变量与作用域

先来看个最常见的面试题:

// 经典面试题:猜猜输出什么?
for (var i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i); // 输出:3 3 3
  }, 100);
}

为什么会这样?因为var声明的变量存在变量提升,而且没有块级作用域。换成let就正常了:

// 使用let的正确写法
for (let i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i); // 输出:0 1 2
  }, 100);
}

这里涉及到两个关键概念:变量提升和块级作用域。let和const是ES6引入的,它们有块级作用域,不会出现var的那些奇怪问题。

闭包与内存管理

闭包可能是最让人头疼的概念了,但其实理解起来并不难:

// 闭包的实际应用:计数器
function createCounter() {
  let count = 0; // 这个变量被"封闭"在函数内部
  
  return {
    increment: () => ++count,
    decrement: () => --count,
    getValue: () => count
  };
}

const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2

闭包就是函数能够记住并访问其词法作用域中的变量,即使函数在其作用域外执行。但要注意内存泄漏问题:

// 潜在的内存泄漏
function createHeavyObject() {
  const largeObject = new Array(1000000); // 大对象
  
  return () => {
    // 即使外部不再需要,largeObject仍然被引用
    console.log('对象还在内存中');
  };
}

机-会

技术大厂,前端-后端-测试,全国均有机-会,感兴趣可以试试。待遇和稳定性都还不错~

原型与继承

JavaScript的继承是基于原型的,这和传统的类继承很不一样:

// 原型链示例
function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function() {
  console.log(`${this.name} makes a noise.`);
};

function Dog(name) {
  Animal.call(this, name); // 调用父类构造函数
}

// 设置原型链
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.speak = function() {
  console.log(`${this.name} barks.`);
};

const dog = new Dog('Rex');
dog.speak(); // Rex barks.

ES6的class语法让这变得更简单:

class Animal {
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} barks.`);
  }
}

异步编程演进

从回调地狱到async/await,异步编程经历了很大变化:

// 1. 回调地狱
function oldWay(callback) {
  readFile('file1.txt', (err, data1) => {
    if (err) return callback(err);
    processData(data1, (err, result1) => {
      if (err) return callback(err);
      // 更多嵌套...
    });
  });
}

// 2. Promise链
function promiseWay() {
  return readFilePromise('file1.txt')
    .then(processDataPromise)
    .then(data => {
      // 更清晰的流程
    })
    .catch(error => {
      // 统一错误处理
    });
}

// 3. async/await(推荐)
async function modernWay() {
  try {
    const data = await readFilePromise('file1.txt');
    const result = await processDataPromise(data);
    return result;
  } catch (error) {
    console.error('处理失败:', error);
  }
}

Promise深度解析

Promise是现代JavaScript异步编程的基石:

// 手写一个简易Promise
class MyPromise {
  constructor(executor) {
    this.state = 'pending';
    this.value = undefined;
    this.onFulfilledCallbacks = [];
    
    const resolve = (value) => {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        this.onFulfilledCallbacks.forEach(cb => cb(value));
      }
    };
    
    executor(resolve);
  }
  
  then(onFulfilled) {
    return new MyPromise((resolve) => {
      if (this.state === 'fulfilled') {
        const result = onFulfilled(this.value);
        resolve(result);
      } else {
        this.onFulfilledCallbacks.push((value) => {
          const result = onFulfilled(value);
          resolve(result);
        });
      }
    });
  }
}

事件循环机制

这是JavaScript并发模型的核心:

// 理解事件循环的执行顺序
console.log('1. 同步任务开始');

setTimeout(() => {
  console.log('6. 宏任务执行');
}, 0);

Promise.resolve().then(() => {
  console.log('4. 微任务执行');
});

console.log('2. 同步任务继续');

Promise.resolve().then(() => {
  console.log('5. 另一个微任务');
});

console.log('3. 同步任务结束');

// 输出顺序:1 2 3 4 5 6

ES6+新特性实战

现代JavaScript提供了很多好用特性:

// 解构赋值
const user = { name: '小明', age: 25, city: '北京' };
const { name, age } = user;

// 扩展运算符
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]

// 可选链操作符
const street = user?.address?.street; // 不会报错

// 空值合并
const displayName = user.nickname ?? '匿名用户'; // 只有null/undefined时使用默认值

函数式编程概念

JavaScript很适合函数式编程风格:

// 高阶函数
const users = [
  { name: '小明', age: 25 },
  { name: '小红', age: 30 },
  { name: '小刚', age: 28 }
];

// 函数组合
const getAdultNames = users
  .filter(user => user.age >= 18)
  .map(user => user.name)
  .sort();

// 柯里化
const multiply = a => b => a * b;
const double = multiply(2);
console.log(double(5)); // 10

模块化系统

从IIFE到ES Modules的演进:

// 现代ES Modules
// math.js
export const add = (a, b) => a + b;
export const PI = 3.14159;

// app.js
import { add, PI } from './math.js';
console.log(add(PI, 2)); // 5.14159

// 动态导入
const loadModule = async () => {
  const module = await import('./math.js');
  console.log(module.add(1, 2));
};

类型系统与TypeScript

虽然JavaScript是动态类型,但类型检查很重要:

// 类型检查工具函数
const typeCheck = {
  isString: value => typeof value === 'string',
  isFunction: value => typeof value === 'function',
  isObject: value => value !== null && typeof value === 'object'
};

// TypeScript带来的类型安全
interface User {
  name: string;
  age: number;
  email?: string;
}

function createUser(user: User): User {
  // TypeScript会在编译时检查类型
  return { ...user };
}

性能优化技巧

写出高性能的JavaScript代码:

// 防抖函数:避免频繁调用
function debounce(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

// 使用Web Worker处理密集型任务
const worker = new Worker('heavy-task.js');
worker.postMessage({ data: largeData });
worker.onmessage = (event) => {
  console.log('计算结果:', event.data);
};

现代开发工具链

2024年的前端开发离不开这些工具:

// Vite配置示例
// vite.config.js
export default {
  plugins: [vue(), eslint()],
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['vue', 'vue-router']
        }
      }
    }
  }
};

// 现代测试工具
import { describe, it, expect } from 'vitest';

describe('工具函数测试', () => {
  it('应该正确计算加法', () => {
    expect(add(1, 2)).toBe(3);
  });
});

这12个核心概念就像JavaScript的基石,理解它们不仅能让你在面试中游刃有余,更能写出更健壮、更易维护的代码。

——转载自:Razy

#面试时最害怕被问到的问题##我发现了面试通关密码#
全部评论

相关推荐

每一次科技革命,都预示着生产力的大幅提高,而自2022年开始的AI元时代,或许就是第四次科技革命。从2022年GPT问世之后,我们的工作范式就已经开始发生翻天覆地的变化,同时也让工作效率有了质的提高。1.&nbsp;文本工作:首当其冲的就是文字领域,从文案编写、知识收集等,原本可能绞尽脑汁两三天才能写出一片文章,现在有了AI,几十秒就输出一篇文章,即便内容不符合你得期望,也能在极短时间内给你完成写作大纲和素材收集等辅助工作,而像以前文科天才才能写出的诗歌,现在借助AI每个人都能写出优美而又符合自己当前预期的应景佳作。2.&nbsp;代码:现在的AI基本已经取代了原来各种论坛。原来的程序员,工作时大部分时间可能都花在各种论坛(如CSDN、Stack&nbsp;Overflow)上,查找资料和代码然后cv,而现在的基本都是面向AI编程了。还记得之前看的一篇文章,爆料stack&nbsp;overflow现在的日活正处于直线下降的一个趋势,已经回到了刚成立时期的日活量了,或许过不了多久就真的会成为历史了。3.&nbsp;艺术创作:原来的艺术创作,需要你会各种东西,比如PS、剪辑、绘画等,基本都需要大量的学习时间,而现在的只要你学点儿提示词技巧,再描述一下自己的想法,就能在几十秒的时间里生成一副绝佳的艺术作品,哪怕像音乐、视频等艺术创作现在也有相当成熟的AI应用了。AI的出现,不仅减少了工具的学习成本,更是让普通人都能高效的进行艺术创作。4.&nbsp;各行各业:若说此前的应用尚限于日常场景,那么各行各业全面拥抱AI,才真正标志着AI时代生产力的跨越式提升。从医疗的智能分诊与辅助诊疗,到芯片的大模型调优,再到制造业的智能预测分析、能源的电网智能调度、金融的自动化投研等,AI不再是“锦上添花”的技术点缀,而是重构各行业核心生产函数的关键要素——它通过自动化认知劳动、优化决策、连接物理与数字世界,实现了从“人力密集”向“智能密集”的跃迁。每次变革都会淘汰掉一部分旧的、跟不上生产力的职业和事物,但同样也会带来全新的机遇。我觉得,相较于焦虑是否会被取代,不如主动拥抱AI,主动重构自己的思维和技术栈,迈向未来新世界!
AI时代的工作 VS 传...
点赞 评论 收藏
分享
02-07 12:06
已编辑
华侨大学 测试开发
最近看到很多&nbsp;92&nbsp;的,甚至是硕士,开始往测开赛道卷,说实话有点看不懂。先把话说清楚,大厂里的测开,绝大多数时间干的还是测试的活,只是写点自动化脚本、维护测试平台、接接流水线,真正像开发一样做系统、做架构、做核心平台的测开少得可怜,基本都集中在核心提效组,而且人很少,外面进去的大概率轮不到你,我想真正干过人都清楚。很多人被洗脑了,以为测开也是开,和后端差不多,只是更简单、更轻松、还高薪。现实情况是,测开和开发的职业路径完全不一样。开发的核心是业务和系统能力,测开的核心是稳定性和覆盖率,前者是往上走,后者天花板非常明显。你可以见到很多开发转测开,但你很少见到干了几年测开还能顺利转回开发的。更现实一点说,92&nbsp;的高学历如果拿来做测开,大部分时间就是在做重复性很强的杂活,这种工作对个人能力的放大效应非常弱。三年下来,你和一个双非的,甚至本科的测开差距不会太大,但你和同龄的后端、平台开发差距会非常明显。这不是努不努力的问题,是赛道问题。所谓测开简单高薪,本质上是把极少数核心测开的上限,当成了整个岗位的常态来宣传。那些工资高、技术强的测开,本身就是开发水平,只是挂了个测开的名。普通人进去,99%&nbsp;做的都是项目兜底型工作,而不是你想象中的平台开发。测开不是不能做,但它绝对不是开发的平替,也不是性价比最优解。如果你是真的不想做开发,追求稳定,那测开没问题。但如果你只是觉得测开比后端容易,还能进大厂,那我劝你冷静一点,这只是在用短期安全感换长期天花板。有92的学历,如果你连测开这些重复性工作都能心甘情愿接受,那你把时间精力用在真正的开发、系统、业务深度上,回报大概率比卷测开要高得多。想清楚再下场,别被岗位名和话术带偏了,就算去个前端客户端也是随便占坑的,测开是一个坑位很少赛道,反而大面积学历下放,不用想也能知道会是什么结果,我想各位在JAVA那里已经看到了
小浪_Coding:工作只是谋生的手段 而不是相互比较和歧视
点赞 评论 收藏
分享
评论
3
9
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务