前言
??這個(gè)概念是在js小黃書(shū)《你不知道的js》中了解到的商膊,面向?qū)ο笾心7隆邦悺钡臑E用導(dǎo)致代碼苦澀難懂饶囚,所以可以通過(guò)
關(guān)聯(lián)委托
的方式讓代碼更清晰易懂帕翻。
??es6的class
類出現(xiàn)后,真正規(guī)范了類的使用萝风,而且簡(jiǎn)單易懂嘀掸。所以本文的意義在于了解一種好的設(shè)計(jì)理念,也可讓自身也具有創(chuàng)新能力规惰,寫(xiě)出更優(yōu)雅的代碼睬塌。
面向?qū)ο缶幊?/h1>
其根本在于模仿類,我們這里寫(xiě)一個(gè)寄生組合繼承
歇万,也是es6的class
的設(shè)計(jì)思想異曲同工揩晴。
function Parent(name, age) {
this.name = name;
this.age = age;
}
Parent.prototype.myName = function() {
return this.name;
};
Parent.prototype.myAge = function() {
return this.age;
};
function Child(name, age, sex) {
Parent.call(this, name, age);
this.sex = sex;
}
// 將Child.prototype關(guān)聯(lián)到Parent.prototype上
Child.prototype = Object.create(Parent.prototype);
// var F = function() {};
// F.prototype = Parent.prototype;
// Child.prototype = new F();
// 如果此時(shí)要使用到Child.constructor, 手動(dòng)重置一下此屬性,使其指到Bar上贪磺。
Child.prototype.contructor = Child;
Child.prototype.mySex = function() {
return this.sex;
};
var c = new Child('tony', '16', '男');
console.log(c.myName()); // tony
console.log(c.mySex()); // 男
其根本在于模仿類,我們這里寫(xiě)一個(gè)寄生組合繼承
歇万,也是es6的class
的設(shè)計(jì)思想異曲同工揩晴。
function Parent(name, age) {
this.name = name;
this.age = age;
}
Parent.prototype.myName = function() {
return this.name;
};
Parent.prototype.myAge = function() {
return this.age;
};
function Child(name, age, sex) {
Parent.call(this, name, age);
this.sex = sex;
}
// 將Child.prototype關(guān)聯(lián)到Parent.prototype上
Child.prototype = Object.create(Parent.prototype);
// var F = function() {};
// F.prototype = Parent.prototype;
// Child.prototype = new F();
// 如果此時(shí)要使用到Child.constructor, 手動(dòng)重置一下此屬性,使其指到Bar上贪磺。
Child.prototype.contructor = Child;
Child.prototype.mySex = function() {
return this.sex;
};
var c = new Child('tony', '16', '男');
console.log(c.myName()); // tony
console.log(c.mySex()); // 男
這里有兩個(gè)硫兰,我需要強(qiáng)調(diào)一下:
Object.create原理
function objectCreate (obj) {
var F = function() {};
F.prototype = obj;
return new F();
}
在上述寄生組合繼承中,就是下面注釋掉的代碼寒锚。
-
contructor丟失問(wèn)題
當(dāng)你這么使用Child.prototype = ...
劫映,直接等于就會(huì)讓contructor
丟失违孝。原因是Child.prototype.contructor === Child
,也就是說(shuō)contructor是函數(shù)自帶的。所以需要重新指向泳赋。
面向委托設(shè)計(jì)
這里呢雌桑,我們將prototype去掉,直接通過(guò)Object.create方法摹蘑,構(gòu)建對(duì)象之間的關(guān)系筹燕。
var Parent = {
initParent: function(name, age) {
this.name = name;
this.age = age;
},
myName: function() {
return this.name;
},
};
// 創(chuàng)建Child轧飞,并委托Parent的屬性
var Child = Object.create(Parent);
Child.initChild = function(name, age, sex) {
this.initParent(name, age);
this.sex = sex;
};
Child.mySex = function() {
return this.sex;
};
var c = Object.create(Child);
c.initChild('tony', '16', '男');
console.log(c.myName()); // tony
console.log(c.mySex()); // 男
通過(guò)Object.create繼承父類的屬性和方法衅鹿,但這里還是有幾點(diǎn)不優(yōu)雅的問(wèn)題。
-
Parent
對(duì)象寫(xiě)法比較優(yōu)雅过咬,可是Child
的方法不能直接用對(duì)象方法大渤,只能Child.initChild
的方法,不然會(huì)丟失父類方法掸绞。(原因就是Child={}
這種寫(xiě)法本身就是重新賦值了) - 還是有煩人的
Object.create
進(jìn)行繼承泵三。
為了足夠優(yōu)雅和使用,es6推出class類的概念衔掸。
es6的class編程
class Parent {
constructor(name, age) { // 初始化屬性
this.name = name;
this.age = age;
}
myName() {
return this.name;
}
}
class Child extends Parent {
constructor(name, age, sex) {
super(name, age); // 用super調(diào)用父類的構(gòu)造方法! 類似Parent.call(this, name, age)烫幕,但是this指的是子類的實(shí)例
this.sex = sex;
}
mySex() {
return this.sex;
}
}
var c = new Child('tony', '16', '男');
console.log(c.myName()); // tony
console.log(c.mySex()); // 男
父子類完全可以用同樣的優(yōu)雅方法了;constructor
里面設(shè)置初始化值敞映,與constructor
同級(jí)的是方法较曼,取代了prototype
;super
方法就是類似Parent.cal
l調(diào)用父類構(gòu)造方法振愿,但是this
指的是子類的實(shí)例(es5
中this
指的是父類的實(shí)例)捷犹,不過(guò)es6
做的更好,想繼承必須調(diào)用不然報(bào)錯(cuò)冕末,避免我們忘記萍歉。
??Class作為構(gòu)造函數(shù)的語(yǔ)法糖,同時(shí)有
prototype
屬性和__proto__
屬性档桃,因此同時(shí)存在兩條繼承鏈枪孩。(有點(diǎn)難理解,想清晰了解prototype
和__proto__
的區(qū)別藻肄,請(qǐng)看https://blog.csdn.net/lc237423551/article/details/80010100)
??簡(jiǎn)單來(lái)說(shuō)呢蔑舞,你只能看到__proto__
,但是這個(gè)__proto__
分兩種仅炊,一種是你繼承的
斗幼,一種是你prototype創(chuàng)建的
。第一種表示類的繼承
抚垄,指向父類
蜕窿;第二種表示類的實(shí)例繼承
谋逻,指向類的prototype
。
- 子類
__proto__
屬性桐经,表示類的繼承
毁兆,總是指向父類。- 子類
prototype
屬性阴挣,表示類的實(shí)例的繼承
臼寄,類的實(shí)例的__proto__
屬性指向類的prototype
屬性。
特性和寄生組合繼承特性一致薄霜,所以類的繼承可以看做是寄生組合繼承的語(yǔ)法糖
牧牢,但是實(shí)現(xiàn)方式完全不同,思想是一致的誓沸。