ES5构造函数与ES6 Class核心差异解析
本文对比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主要区别的梳理。如需了解更多相关内容,建议查阅本站往期文章或继续浏览后续资源,感谢支持。
JavaScript异步发送HTTP请求时怎么优雅地处理错误
2026-11-05 17:10:44
5款主流JS在线运行工具对比:CodePen、JSFiddle与StackBlitz怎么选
2026-11-05 17:04:04
JavaScript入门书籍避坑:这些书不适合初学者
2026-11-05 16:31:15
JS使用Math.round实现保留两位小数的原理与代码
2026-11-05 15:35:55
JavaScript 原生 Date 对象怎么实现日期加减
2026-11-05 14:30:00
