JS基础语法下篇:函数与对象核心要点深度解析

JavaScript 基础语法下篇:函数与对象核心要点深度解析
(2025–2026 面试/生产视角,最常被问、最容易混淆的部分)

一、函数部分(最核心、最常考)

1. 函数创建方式对比(面试必问)

创建方式语法示例函数提升(Hoisting)this 绑定时机arguments 对象推荐场景现代趋势(2025+)
函数声明function fn(){}整体提升调用时动态绑定普通函数、需要提升的场景较少单独使用
函数表达式(匿名)const fn = function(){}只提升变量声明调用时动态绑定回调函数、立即执行函数常见
命名函数表达式const fn = function abc(){}只提升变量声明调用时动态绑定调试栈追踪更有意义推荐(调试友好)
箭头函数const fn = () => {}无提升词法绑定(外层this)回调、简洁写法、React hooks最常用
Function 构造函数new Function('a','b','return a+b')无提升全局对象极少用(安全问题)几乎不用
IIFE(立即执行函数表达式)(function(){}()) / ( () => {} )()创建私有作用域(旧时代)现在少用(let/const+块级)

箭头函数 vs 普通函数(最常被问的 8 点区别)

  1. this 绑定:箭头函数没有自己的 this,捕获外层上下文
  2. 不能用作构造函数(没有 prototype,不能 new)
  3. 没有 arguments 对象
  4. 没有 super / new.target
  5. 不能用作 Generator 函数(不能 yield)
  6. 不能改变 this(call/apply/bind 无效)
  7. 语法更简洁(单行可省 return 和 {})
  8. 不适合:需要动态 this 的地方(如事件处理、对象方法)

2. this 指向规则(2025 年面试 Top 1 问题)

调用方式this 指向代码示例
普通函数调用非严格模式 → window/globalThis
严格模式 → undefined
fn()
对象方法调用调用该方法的对象obj.method() → this = obj
构造函数(new)新创建的实例对象new Person() → this = 新实例
显式绑定(call/apply/bind)第一个参数(若为 null/undefined → window/globalThis)fn.call(obj) → this = obj
箭头函数外层作用域的 this(词法作用域)永远不看调用方式,只看定义位置
事件监听器(addEventListener)绑定事件的 DOM 元素(除非用箭头函数)btn.onclick = fn → this = btn

经典面试题变形(按出现频率排序):

  1. setTimeout 回调里的 this 为什么是 window?
  2. 为什么 class 中的普通方法要 bind(this)?
  3. 箭头函数写在 class 里作为方法会有什么问题?
  4. obj.fn() 和 fn = obj.fn; fn() 的 this 区别?
  5. 连续调用 .call().call() 最终 this 指向谁?

3. 闭包(Closure)高频考点总结

  • 定义:函数 + 函数能访问到的词法环境(即使外层函数已销毁)
  • 三大经典用途(背下来):
  1. 数据私有化(模块模式)
  2. 记忆函数(memoize)
  3. 延迟执行 / 回调函数保存状态
  • 常见闭包写法(2025 年仍常用):
// 1. 经典计数器模块
function createCounter() {
  let count = 0;
  return {
    increment: () => ++count,
    getCount: () => count
  };
}

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

闭包最常被问的两个问题

  • 下面代码输出什么?为什么?
for (var i = 0; i < 5; i++) {
  setTimeout(() => console.log(i), 0);
}
// 输出 5 5 5 5 5

// 改成 let 就正常了(块级作用域)
// 或用闭包立即执行函数保存每次的 i
  • 闭包会造成内存泄漏吗?(现代 V8 垃圾回收很强,但仍需注意循环引用)

二、对象部分(核心特性深度)

1. 对象创建方式对比(2025 年视角)

方式语法示例prototype 链this 绑定枚举性(for…in)性能现代推荐度
对象字面量{ name: "张三" }Object.prototype可枚举★★★★★
Object.create()Object.create(proto, descriptors)自定义原型可控制★★★★
构造函数 + newnew Person()Person.prototype实例可枚举★★★
class 语法糖class Person {}Person.prototype实例可枚举★★★★★
Object.assign()浅拷贝浅拷贝工具
展开运算符 …{ ...obj, name: "李四" }最常用

2. 属性描述符(Property Descriptor)——面试高频

Object.defineProperty(obj, "key", {
  value: 42,           // 数据描述符
  writable: true,      // 是否可写
  enumerable: false,   // 是否 for...in 枚举
  configurable: false  // 是否可删除/重新定义
});

// 访问器描述符(最常用于 Vue2 响应式原理)
Object.defineProperty(obj, "fullName", {
  get() { return this.first + " " + this.last; },
  set(val) { /* 拆分赋值 */ },
  enumerable: true,
  configurable: true
});

高频问题

  • enumerable: false 的属性还能被访问吗?(能,只是 for…in / Object.keys 看不到)
  • configurable: false 之后还能改 writable 吗?(部分可以,严格模式更严格)
  • Object.freeze()Object.seal()Object.preventExtensions() 区别?

3. 原型链与继承(2025 年仍重要)

// 现代最推荐:组合寄生式继承(class + extends)
class Animal {
  constructor(name) { this.name = name; }
  speak() { console.log(`${this.name} makes a sound.`); }
}

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

经典面试题

  1. obj.__proto__Object.getPrototypeOf(obj) 区别?
  2. Function.__proto__ 是什么?(Function.prototype)
  3. 原型链终点是什么?(null)
  4. hasOwnProperty vs in 操作符区别?

三、2025–2026 高频面试题 Top 15(建议准备)

  1. 箭头函数和普通函数的 this 区别?举 3 个场景说明箭头函数不适合的情况。
  2. 实现一个简易的 call/apply/bind。
  3. 手写防抖/节流(考虑 this 和 参数透传)。
  4. 闭包在实际项目中的 3 个典型应用。
  5. class 中的 static、public、private、#private 区别(# 是真正私有)。
  6. Object.create(null) 有什么用?(纯字典对象)
  7. 浅拷贝 vs 深拷贝有哪些实现方式?(JSON.parse(JSON.stringify) 的局限性)
  8. for…in / for…of / Object.keys / Object.getOwnPropertyNames 区别?
  9. new 一个函数时发生了哪 4 件事?
  10. 为什么说 JS 是基于原型的语言而不是基于类的?

需要针对上面某个题目写详细代码解析、或者想看“this 指向终极口诀”、或者“现代 JS 对象新特性(Proxy、Reflect、Symbol)”的补充,都可以直接告诉我~

文章已创建 4791

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部