定義: bash
若是一個類可以重用另外一個類的屬性和或方法,就稱之爲繼承。閉包
面向對象的語言多數都支持繼承。
app
特色: 函數
子類可使用父類的全部功能,而且對這些功能進行拓展。學習
繼承最重要的優勢就是代碼複用,從而構建大型軟件系統。ui
缺點: this
過多的繼承了沒用的屬性spa
Grand.prototype.lastName = 'chen'
function Grand() {}
var grand = new Grand();
Father.prototype = grand;
function Father() {
this.name = 'hehe';
}
var father = new Father();
Son.prototype = father;
function Son() {}
var son = new Son();
複製代碼
優勢:prototype
缺點: code
每次構造函數都要多走一個函數
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
function Student(name, age, sex, grade) {
Person.call(this, name, age, sex);
this.grade = grade;
}
var student = new Student('hehe', 40, 'male', 18);複製代碼
優勢:
缺點:
Father.prototype.getfaName = function() {
console.log(this.faName);
}
function Father(name) {
this.faName = 'father';
}
Child.prototype = new Father();
Child.prototype.constructor = Child;
function Child(args) {
this.chName = 'child';
Father.apply(this, args);
}
var child = new Child(); 複製代碼
缺點:
不能隨便改動本身的原型
function create(o){
function F(){};
F.prototype = o;
return new F();
}
var Person = {
name:'me',
hobbies:['riding', 'swimming']
}
var anotherPerson = create(Person);
var anotherPerson2 = create(Person);
anotherPerson.name = 'her';
anotherPerson.hobbies.push('dancing');
console.log(anotherPerson2.name, anotherPerson2.hobbies); // her ["riding", "swimming", "dancing"]複製代碼
缺點:
function createObj(o){
let clone = Object.create(o);
clone.sayName = function(){
console.log('hi');
}
return clone
}
let person = {
name:"JoseyDong",
hobbies:["sing","dance","rap"]
}
let anotherPerson = createObj(person);
anotherPerson.sayName(); // => hi複製代碼
// 第一種寫法
function inherit(Target, Origin) {
// 使用F空函數當子類和父類的媒介 是爲了防止修改子類的原型對象影響到父類的原型對象
function F() {}
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constructor = Target; // 防止new的時候 返回實例的構造函數指向混亂
Target.prototype.uber = Origin.prototype; // 尋找繼承的原型是誰
}
// 第二種寫法 採用當即執行函數和閉包的形式
var inherit = (function() {
function F() {}
return function(Target, Origin) {
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.contructor = Target;
Target.prototype.uber = Origin.prototype;
}
})()複製代碼
缺點:
但對象冒充有個問題,當父類的屬性相同時,後面定義的會覆蓋前面定義的屬性,所以,對象冒充的方式支持父類的屬性不一樣時的狀況下比較合理。
每次構造函數都要多走一個函數
function Father(color) {
this.color = color;
this.showColor = function () {
alert(this.color);
}
}
function Father1(color) {
this.color1 = color;
this.showColor1 = function () {
alert(this.color1);
}
}
function Child(color, color1) {
this.Method = Father;
this.Method(color);
delete this.Method;
this.Method = Father1;
this.Method(color1);
delete this.Method;
}
var child = new Child("wu", "zhao");
child.showColor();複製代碼
class Plane {
// 靜態方法 不被子集繼承
static alive() {
return true;
}
constructor(name) {
this.name = name || '普通飛機';
this.blood = 100;
}
fly() {
console.log('fly');
}
};
class AttackPlane extends Plane{
constructor(name) {
super(name);
this.logo = 'duyi';
x }
dan() {
console.log('bububu');
}
}
var oAp = new AttackPlane('攻擊機');
console.log(oAp);複製代碼
注意:
子類必須在constructor方法中調用super方法,不然新建實例時會報錯。這是由於子類沒有本身的this對象,而是繼承父類的this對象,而後對其進行加工,若是不調用super方法,子類就得不到this對象。所以,只有調用super以後,纔可使用this關鍵字。
ES5的繼承機制實質是先創造子類的實例對象this,而後再將父類的方法添加到this上面(Parent.call(this))。
ES6的繼承機制實質是先創造父類的實例對象this (因此必須先調用 super() 方法),而後再用子類的構造函數修改this。
你的點贊是我持續輸出的動力 但願能幫助到你們 互相學習 有任何問題下面留言 必定回覆