ES5构造函数与ES6 Class核心差异解析

作者:代码拾荒

时间:2026-10-23

浏览:650

本文对比ES5构造函数与ES6 Class的核心差异。ES5类可直接执行且支持变量提升,而ES6 Class必须通过new调用,不存在变量提升,且实例原型链上的方法无法通过for-in遍历。此外,ES6引入了new.target属性用于检测调用方式,并支持static静态方法,其this指向类本身而非实例。

文章目录

前言

在ES5环境中,定义类通常依赖于构造函数结合原型链的方式;而在ES6标准中,引入了class关键字来定义类。本文将重点梳理这两者在实现机制与行为上的具体差异。

关于ES5中类的定义方式,可参考相关JavaScript类机制的文章,此处仅聚焦于ES5类与ES6 Class之间的对比分析。

调用方式与变量提升差异

第一点差异在于调用方式:ES6的class必须通过new关键字实例化,严禁直接作为普通函数执行。

调用方式与变量提升差异

若直接执行class定义,JavaScript引擎会抛出错误;相比之下,ES5中的类本质上仍是函数,直接执行不会报错,这是两者在调用机制上的本质区别。

第二点差异涉及变量提升:ES6的class不存在变量提升机制。

调用方式与变量提升差异

调用方式与变量提升差异

图2报错,说明class方式没有把类的定义提升到顶部。

原型链遍历与new.target机制

第三点差异体现在遍历行为上:无法通过常规遍历方法获取class实例原型链上的属性和方法。


function Foo (color) {
 this.color = color
}
Foo.prototype.like = function () {
 console.log(`like${this.color}`)
}
let foo = new Foo()

for (let key in foo) {
 // 原型上的like也被打印出来了
 console.log(key) // color、like
}

class Foo {
 constructor (color) {
  this.color = color
 }
 like () {
  console.log(`like${this.color}`)
 }
}
let foo = new Foo('red')

for (let key in foo) {
 // 只打印一个color,没有打印原型链上的like
 console.log(key) // color
}

第四点差异是new.target元属性的引入。

ES6为new命令新增了new.target属性,该属性返回被new命令作用的目标构造函数。若调用方式非new或Reflect.construct(),new.target的值将为undefined。


function Person(name) {
 if (new.target === Person) {
 this.name = name;
 } else {
 throw new Error('必须使用 new 命令生成实例');
 }
}

let obj = {}
Person.call(obj, 'red') // 此时使用非new的调用方式就会报错

静态方法特性

第五点差异在于静态方法的支持:ES6 class支持static定义的静态方法。

静态方法只能通过类本身调用,不会出现在实例对象上。当静态方法内部包含this关键字时,该this指向类本身而非实例。通过static声明的静态属性和方法均支持被子类继承。


class Foo {
 static bar() {
 this.baz(); // 此处的this指向类
 }
 static baz() {
 console.log('hello'); // 不会出现在实例中
 }
 baz() {
 console.log('world');
 }
}

Foo.bar() // hello

总结

以上即为ES5类与ES6 Class主要区别的梳理。如需了解更多相关内容,建议查阅本站往期文章或继续浏览后续资源,感谢支持。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章