信息发布→ 登录 注册 退出

javascript如何实现继承_ES5和ES6的方式有何不同?

发布时间:2026-01-12

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

ES5 用 prototypecall 模拟继承

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 用 classextends 语法糖封装继承逻辑

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免费学习笔记(深入)”;

  • 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 中若忘记绑定 thisParent.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');
};

继承内置类(如 ArrayError):ES5 几乎不可靠,ES6 支持原生

ES5 无法真正继承 ArrayError,因为它们的内部槽(如 [[ArrayLength]])无法通过 Object.createnew 模拟;返回的对象不是真正的数组(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 继承的便利性会立刻变成兼容性陷阱。
标签:# javascript  # es6  # java  # js  # node.js  # json  # node  # 浏览器  # access  # safari  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!