You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建类时class语法与函数表示法的差异、行为区别及适用场景

JavaScript 两种类写法的差异、行为对比与选择建议

你给出的两种写法,本质是ES5构造函数+原型模式,和ES6 class语法糖的区别。下面具体拆解它们的行为差异,以及各自的适用场景:

一、核心行为差异

1. 变量提升规则不同

  • 第一种写法(函数表达式+原型):变量Greeter会被提升,但初始值为undefined,如果在声明前调用new Greeter()会直接报错;要是换成function Greeter(...)这种函数声明形式,才会被完整提升,可在声明前实例化。
  • 第二种写法(class):class声明不存在变量提升,提前调用new Greeter()会抛出「无法在初始化前访问Greeter」的错误,必须在声明后才能实例化。

2. 严格模式默认开启

  • 第一种写法:除非手动在代码顶部加'use strict',否则内部运行在非严格模式下,比如给未声明的变量赋值时,会自动挂载到全局对象,不会报错。
  • 第二种写法:class内部代码默认开启严格模式,上述操作会直接抛出ReferenceError,避免非严格模式下的意外行为。

3. 方法可枚举性(针对class内部定义的方法)

如果把greet方法直接写在class内部(比如修改第二种写法为:

class Greeter {
    greeting;
    constructor(greeting) {
        this.greeting = greeting;
    }
    greet() {
        console.log(this.greeting);
    }
}

),此时Greeter.prototype.greet是不可枚举的,用Object.keys(Greeter.prototype)拿不到这个方法;而第一种写法里直接挂载到原型的方法是可枚举的,能被遍历到。

你给出的第二种写法是在外部修改Greeter.prototype.greet,这种情况下和第一种的可枚举性一致。

4. 调用方式强制限制

  • 第一种写法:不用new直接调用Greeter("hello"),非严格模式下this会绑定到全局对象,严格模式下this是undefined,不会直接抛出错误(除非内部用到this的属性)。
  • 第二种写法:必须用new关键字实例化,直接调用Greeter("hello")会抛出「类构造函数不能不用new调用」的TypeError。

5. 私有特性原生支持

  • 第一种写法:无法原生实现私有属性/方法,只能通过闭包等方式模拟,模拟的私有属性仍能被特殊手段访问到。
  • 第二种写法:可以用#定义真正的私有字段(比如#greeting;),这类字段只能在class内部访问,外部无法读取或修改,是语法层面的私有支持。

二、选择哪种写法的原因

选第一种(构造函数+原型)

  • 需要兼容不支持ES6的旧环境(比如IE11及更早版本);
  • 追求极致灵活性,比如动态修改构造函数逻辑、在原型上做复杂的动态扩展;
  • 想深入理解JavaScript原型链的底层实现,避免依赖语法糖。

选第二种(class语法糖)

  • 代码结构更清晰、语义化更强,和Java、Python等面向对象语言的类写法更接近,可读性更高;
  • 原生开启严格模式,减少非严格模式下的潜在bug;
  • 继承实现更简洁(用extends关键字,比ES5的原型继承代码量少很多);
  • 支持私有字段、静态方法、静态字段等现代面向对象特性,代码更规范易维护。

你的两种写法示例:

第一种写法(ES5函数表达式+原型)

var Greeter = function(greeting) {
    this.greeting = greeting;
};

Greeter.prototype.greet = function() {
    console.log(this.greeting);
}

var hello = new Greeter("hello");
hello.greet();

第二种写法(ES6 class+原型扩展)

class Greeter {
    greeting;

    constructor(greeting) {
        this.greeting = greeting;
    }
};

Greeter.prototype.greet = function() {
    console.log(this.greeting);
}

var hello = new Greeter("hello");
hello.greet();

内容的提问来源于stack exchange,提问作者user3006927

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 03:35:22