ES5 和 ES6 继承的区别与比较
2023-10-30 13:58:11
ES5 和 ES6 继承的区别
1. 原型链和类
1.1 原型链
在 ES5 中,继承是通过原型链来实现的。每个对象都有一个内部的属性 __proto__
,指向其原型对象。原型对象包含了该对象继承的属性和方法。例如,如果我们定义了一个 Human
类,它具有 name
和 age
两个属性,我们可以使用 new Human("John", 25)
创建一个新的人类对象 john
。该对象 john
的 __proto__
属性指向 Human.prototype
,而 Human.prototype
的 __proto__
属性指向 Object.prototype
。
1.2 类
在 ES6 中,继承是通过 class
来实现的。类是一个语法糖,它使我们能够以更清晰和直观的方式定义对象。例如,我们可以定义一个 Human
类如下:
class Human {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
然后,我们可以使用 new Human("John", 25)
创建一个新的人类对象 john
。该对象 john
的 __proto__
属性指向 Human.prototype
。
2. 继承语法
2.1 ES5
在 ES5 中,我们可以使用 Object.create()
方法来创建一个新对象,并指定其原型对象。例如,我们可以使用以下代码创建一个新的人类对象 john
,其原型对象是 Human.prototype
:
var john = Object.create(Human.prototype);
john.name = "John";
john.age = 25;
2.2 ES6
在 ES6 中,我们可以使用 extends
关键字来继承另一个类。例如,我们可以定义一个 Student
类,它继承了 Human
类:
class Student extends Human {
constructor(name, age, school) {
super(name, age);
this.school = school;
}
}
然后,我们可以使用 new Student("John", 25, "Harvard")
创建一个新学生对象 john
。该对象 john
的 __proto__
属性指向 Student.prototype
,而 Student.prototype
的 __proto__
属性指向 Human.prototype
。
3. 方法重写
3.1 ES5
在 ES5 中,我们可以通过覆盖原型对象的方法来实现方法重写。例如,我们可以覆盖 Human.prototype.sayHello()
方法,为 Student
类定义一个新的 sayHello()
方法:
Human.prototype.sayHello = function() {
console.log("Hello, I am a human!");
};
Student.prototype.sayHello = function() {
console.log("Hello, I am a student!");
};
var john = new Student("John", 25, "Harvard");
john.sayHello(); // 输出:Hello, I am a student!
3.2 ES6
在 ES6 中,我们可以通过使用 super
关键字来实现方法重写。例如,我们可以覆盖 Human.prototype.sayHello()
方法,为 Student
类定义一个新的 sayHello()
方法:
class Human {
sayHello() {
console.log("Hello, I am a human!");
}
}
class Student extends Human {
sayHello() {
super.sayHello(); // 调用父类的方法
console.log("I am also a student!");
}
}
var john = new Student("John", 25, "Harvard");
john.sayHello(); // 输出:Hello, I am a human! I am also a student!
4. 多态
4.1 ES5
在 ES5 中,我们可以通过覆盖原型对象的方法来实现多态。例如,我们可以覆盖 Human.prototype.sayHello()
方法,为 Student
类定义一个新的 sayHello()
方法:
Human.prototype.sayHello = function() {
console.log("Hello, I am a human!");
};
Student.prototype.sayHello = function() {
console.log("Hello, I am a student!");
};
var john = new Human("John", 25);
var mary = new Student("Mary", 22, "Harvard");
john.sayHello(); // 输出:Hello, I am a human!
mary.sayHello(); // 输出:Hello, I am a student!
4.2 ES6
在 ES6 中,我们可以通过使用 super
关键字来实现多态。例如,我们可以覆盖 Human.prototype.sayHello()
方法,为 Student
类定义一个新的 sayHello()
方法:
class Human {
sayHello() {
console.log("Hello, I am a human!");
}
}
class Student extends Human {
sayHello() {
super.sayHello(); // 调用父类的方法
console.log("I am also a student!");
}
}
var john = new Human("John", 25);
var mary = new Student("Mary", 22, "Harvard");
john.sayHello(); // 输出:Hello, I am a human!
mary.sayHello(); // 输出:Hello, I am a human! I am also a student!
5. 总结
ES5 和 ES6 中的继承机制都有各自的优点和缺点。ES5 中的继承机制更灵活,但代码结构也更复杂。ES6 中的继承机制更清晰和直观,但它对类和方法的访问权限控制较严格。