概述
1. JS实现继承的方式
构造函数继承
构造函数继承的关键:在Child构造函数中执行Parent.call(this)。
function Patent(name){
this.name = name;
this.hobby = [];
this.speak = function(){
console.log("Parent speak")
}
}
// 缺点:new多个Child时,
// Parent构造函数中的方法会在每个Child中拷贝一份
// 浪费内存
Parent.prototype.say = function(){
console.log("Parent say")
}
// 缺点:Parent原型对象上的方法不会被Child继承
function Child(name, type){
Parent.call(this, name);
this.type = type;
}
原型继承
原型继承的关键:设置Child原型指向Parent,Child.prototype = new Parent();
function Parent(name){
this.name = name;
this.hobby = [];
// 缺点:Parent的引用属性会被所有Child实例共享,相互干扰
}
Parent.prototype.say = function(){
console.log("Parent say");
}
function Child(type){
this.type = type;
}
Child.prototype = new Parent()
// 原型继承的关键
组合继承
组合继承的关键:
1.属性使用构造函数继承 - 避免了原型继承中Parent引用属性被所有Child实例共享的缺陷。
2.方法使用过原型继承 - 避免了构造函数继承中方法重复拷贝、浪费内存的缺陷
function Parent(){
this.name = name;
this.hobby = [];
// 属性放在构造函数中
}
Parent.prototype.say = function(){
// 方法放在原型中
console.log("Parent say")
}
function Child(name, type){
Parent.call(this, name);
this.type = type;
}
Child.prototype = Object.creat(Parent.prototype);
// Child继承Parent方法(原型继承)
Child.prototype.speak = function(){
console.log("Child speak")
}
Child.prototype.constructor = Child;
// 修复Child的constructor指向,
// 否则Child的constructor会指向Parent
补充:
1. obj2 = Object.create(obj1);
Object.create()方法创建一个新对象,使用现有对象(obj1)来提供新创建对象(obj2)的__proto__.
2. 对于组合继承代码中的Child.Prototype = Object.create(Parent.prototype),还有两种常见的类似写法是Child.prototype = Parent.prototype 和 Child.prototype = new Parent(),但有缺陷需要避免:
Class继承
class继承用extends实现继承
class Person{
constructor(skin,language){
this.skin = skin;
this.language = languagge;
}
say(){
console.log("I am a Person")
}
}
1.子类没有constructor时
class American extend Person{
aboutMe(){
console.log(this.skin +' '+ this.language)
}
}
子类没有定义constructor,则默认添加一个,并在constructor中调用super函数。调用super函数是为了在子类中获得父类的this,调用之后this指向子类。
2.子类有constructor
class Chinese extend Person{
constructor(skin, language, position){
super(skin, language);
this.position = position;
}
aboutMe(){
console.log(this.x+ ' ' + this.y+' ' + this.position);
}
}
子类必须在constructor方法中调用super方法,否则new实例时会报错。因为子类没有自己的this对象,而是继承父类的this对象。如果不调用super函数,子类就得不到this对象。super()作为父类的构造函数,只能出现在子类的constructor()中。
参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create
https://segmentfault.com/a/1190000016525951
当我们不再需要外在的认可来证明自己时
才能获得真正的自由