ES5通过prototype和call手动模拟继承,需调用Parent.call(this)继承实例属性、Object.create(Parent.prototype)设置原型链并修复constructor;ES6用class/extends语法糖,强制super()调用且支持内置类继承。

ES5 用 prototype 和 call 模拟继承
ES5 没有原生类语法,必须手动操作原型链和构造函数。核心是两步:让子类实例能访问父类实例属性(用 Parent.call(this, ...)),同时让子类原型继承父类原型方法(用 Child.prototype = Object.create(Parent.prototype))。
常见错误包括:Child.prototype = new Parent()(会执行父类构造函数,可能引发副作用),或漏写 Child.prototype.constructor = Child(导致 instance.constructor 指向错误)。
- 必须显式调用
Parent.call(this, ...)来继承实例属性 -
Object.create(Parent.prototype)是安全设置原型的方式,避免调用父类构造器 - 务必重置
constructor,否则new Child().constructor === Parent
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(this.name + ' makes a sound');
};
function Dog(name, breed) {
Animal.call(this, name); // 继承实例属性
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog; // 修复 constructor
Dog.prototype.speak = function() {
console.log(this.name + ' barks');
};
ES6 用 class 和 extends 语法糖封装继承逻辑
ES6 的 class 不是新对象模型,而是对 ES5 原型继承的语法包装。关键区别在于:必须在子类 constructor 中第一行调用 super(),否则 this 不可用;super 同时负责初始化父类实例属性和建立原型链。
不调用 super() 会直接报错 ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor;而 ES5 中漏掉 Parent.call 只是静默失败(this 属性缺失)。
立即学习“Java免费学习笔记(深入)”;
动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包
-
super()必须在子类constructor首行调用,且不能在调用前访问this -
super在静态方法中指向父类,在实例方法中指向父类原型 - 类声明不会被提升(
ReferenceError),而函数声明会
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a sound');
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 必须调用,且第一行
this.breed = breed;
}
speak() {
console.log(this.name + ' barks');
}
}
子类方法中调用父类同名方法:ES5 用 Parent.prototype.method.call,ES6 用 super.method()
覆盖父类方法后想复用逻辑,两者写法差异明显。ES5 需手动指定原型和上下文,容易写错对象或漏传参数;ES6 的 super 是语法级支持,更简洁且语义明确。
注意:super 只能在派生类中使用,且仅限于类内部(不能在普通函数或箭头函数中用);ES5 中若忘记绑定 this,Parent.prototype.speak.call(this) 就会失效。
- ES5:必须显式用
Parent.prototype.speak.call(this),否则this指向错误 - ES6:直接
super.speak(),自动绑定当前实例 - ES6 中
super不能单独取值(如console.log(super)报语法错误)
// ES6 示例
class Dog extends Animal {
speak() {
super.speak(); // OK
console.log('...and then barks');
}
}
// ES5 等价写法(易错)
Dog.prototype.speak = function() {
Animal.prototype.speak.call(this); // 必须 call(this),否则 this 不对
console.log('...and then barks');
};
继承内置类(如 Array、Error):ES5 几乎不可靠,ES6 支持原生
ES5 无法真正继承 Array 或 Error,因为它们的内部槽(如 [[ArrayLength]])无法通过 Object.create 或 new 模拟;返回的对象不是真正的数组(Array.isArray() 返回 false),instanceof Array 也失败。
ES6 的 class SubArray extends Array 能正确继承内置类行为:构造出的对象具备数组方法、长度自动更新、Array.isArray 返回 true,甚至能被 JSON.stringify 正确序列化。
- ES5 中试图继承
Array只能得到“类数组对象”,缺乏关键能力 - ES6 继承内置类依赖引擎对
[[Create]]内部方法的支持,现代浏览器均已实现 - Node.js 4+、Chrome 42+、Firefox 45+、Safari 10.1+ 支持该特性
class MyArray extends Array {
first() {
return this[0];
}
}
const arr = new MyArray(1, 2, 3);
console.log(arr.length); // 3
console.log(arr.first()); // 1
console.log(Array.isArray(arr)); // true
console.log(arr instanceof Array); // true
原型链细节、super 的词法绑定机制、以及内置类继承的底层限制,这些地方最容易被忽略——尤其是当代码在旧环境运行或需要兼容 IE 时,ES6 继承的便利性会立刻变成兼容性陷阱。










