ES6之类的方式完成继承
2018-09-05 本文已影响0人
锋享前端
继承
在ES6之前要完成继承,需要写很多的代码。看下面的继承的例子:
<script type="text/javascript">
function Father(name) {
this.name = name;
}
Father.prototype.sayName = function () {
console.log(this.name);
}
function Son(name,age) {
Father.call(this, name);
this.age = age;
}
Son.prototype = new Father();
Son.prototype.constructor = Son;
Son.prototype.sayAge = function () {
console.log(this.age);
}
var son1 = new Son("儿子", 20);
son1.sayAge(); //20
son1.sayName(); //儿子
</script>
1 继承的基本写法
如果在ES6通过类的方式完成继承就简单了很多。
需要用到一个新的关键字:extends
<script type="text/javascript">
class Father{
constructor(name){
this.name = name;
}
sayName(){
console.log(this.name);
}
}
class Son extends Father{ //extents后面跟表示要继承的类型
constructor(name, age){
super(name); //相当于以前的:Father.call(this, name);
this.age = age;
}
//子类独有的方法
sayAge(){
console.log(this.age);
}
}
var son1 = new Son("李四", 30);
son1.sayAge();
son1.sayName();
console.log(son1 instanceof Son); // true
console.log(son1 instanceof Father); //true
</script>
这种继承方法,和我们前面提到的构造函数+原型的继承方式本质是一样的。但是写起来更简单,可读性也更好。
关于super的使用,有几点需要注意:
- 你只能在派生类中使用 super(),否则(没有使用 extends 的类或函数中使用)一个错误会被抛出。
- 你必须在构造函数的起始位置调用 super(),因为它会初始化 this。任何在 super() 之前访问 this 的行为都会造成错误。也即是说super()必须放在构造函数的首行。
- 在类构造函数中,唯一能避免调用 super() 的办法是返回一个对象。
2在子类中屏蔽父类的方法(重写)
如果在子类中声明与父类中的同名的方法,则会覆盖父类的方法。(这种情况在其他语言中称之为 方法的覆写、重写 )
<script type="text/javascript">
class Father{
constructor(name){
this.name = name;
}
sayName(){
console.log(this.name);
}
}
class Son extends Father{ //extents后面跟表示要继承的类型
constructor(name, age){
super(name); //相当于以前的:Father.call(this, name);
this.age = age;
}
//子类独有的方法
sayAge(){
console.log(this.age);
}
//子类中的方法会屏蔽到父类中的同名方法。
sayName(){
super.syaName(); //调用被覆盖的父类中的方法。
console.log("我是子类的方法,我屏蔽了父类:" + name);
}
}
var son1 = new Son("李四", 30);
son1.sayAge();
son1.sayName();
</script>
如果在子类中又确实需要调用父类中被覆盖的方法,可以通过super.方法()来完成。
注意:
- 如果是调用构造方法,则super不要加点,而且必须是在子类构造方法的第一行调用父类的构造方法
- 普通方法调用需要使用super.父类的方法() 来调用。
3 静态方法也可以继承
<script type="text/javascript">
class Father{
static foo(){
console.log("我是父类的静态方法");
}
}
class Son extends Father{
}
Son.foo(); //子类也继承了父类的静态方法。 这种方式调用和直接通过父类名调用时一样的。
</script>