Javascript:圖形解釋如何實現“ 單繼承 、多繼承 、摻入 “


前提知識

Javascript:必須知道的Javascript知識點之“原型鏈”

Javascript:必須知道的Javascript知識點之“this指針”

Javascript:用 "腦圖軟件" 學習 “面向對象”

幾個內置核心方法學習

代碼示例

 1 var Base = function (name) {
 2     this.name = name;
 3 };
 4 
 5 var base = new Base();
 6 
 7 console.log((base instanceof Object));//true
 8 console.log((base instanceof Base));//true
 9 console.log(Base.prototype.isPrototypeOf(base));//true
10 console.log(Object.prototype.isPrototypeOf(base));//true
11 console.log(base.hasOwnProperty("name"));//true
12 console.log(base.hasOwnProperty("toString"));//false
13 console.log(("name" in base));//true
14 console.log(("toString" in base));//true

圖形示意

instanceof

obj instanceof T,判斷obj.__proto__指向的原型鏈是否包含T.prototype。

isPrototypeOf

objLeft.isPrototypeOf(objRight),判斷objLeft是否包含在objRight.__proto__指向的原型鏈中。

hasOwnProperty

obj.hasOwnProperty(propertyName),判斷obj(不包括原型鏈)是否包含屬性“propertyName”。

in

propertyName in obj,判斷屬性“propertyName”是否包含在對象obj及其原型鏈中。

單繼承實現

在javascript中實現單繼承的思路是:讓ChildType.prototype.__proto__指向ParentType.prototype。

代碼示例

 1 Function.prototype.extend = function (baseType) {
 2     var tempType = function () { };
 3     tempType.prototype = baseType.prototype;
 4 
 5     this.prototype = new tempType();
 6     this.prototype.constructor = this;
 7     this.super = function () {
 8         return baseType.prototype;
 9     };
10 };
11 
12 var Base = function (name) {
13     this.name = name;
14 };
15 
16 var Animal = function () {
17     Animal.super().constructor.apply(this, arguments);
18 };
19 Animal.extend(Base);
20 
21 var Dog = function () {
22     Dog.super().constructor.apply(this, arguments);
23 };
24 Dog.extend(Animal);
25 
26 var dog = new Dog('笨狗');
27 console.log(dog.name);//笨狗
28 console.log(dog instanceof Base);//true
29 console.log(dog instanceof Animal);//true
30 console.log(dog instanceof Dog);//true

圖形示意

常見問題

問題:為什么要引入“tempType”,而不是直接“this.prototype = new baseType()”?

答案:“new baseType()”會導致構造方法被調用兩次。

問題:為什么不直接“this.prototype = baseType.prototype”?

答案:這樣的話,父子類型就會同時指向一個prototype,不符合繼承的語義。

摻入實現

參考文章:設計原則:請重新審視“多重繼承”,找機會擁抱一下“摻入(Mixin)”

在javascript中實現摻入的思路是:拷貝MixinType.prototye包含的所有屬性到TargetType.prototype中。

代碼示例

 1 Function.prototype.extend = function (baseType) {
 2     var tempType = function () { };
 3     tempType.prototype = baseType.prototype;
 4 
 5     this.prototype = new tempType();
 6     this.prototype.constructor = this;
 7     this.super = function () {
 8         return baseType.prototype;
 9     };
10 };
11 
12 var Base = function (name) {
13     this.name = name;
14 };
15 
16 var Animal = function () {
17     Animal.super().constructor.apply(this, arguments);
18 };
19 Animal.extend(Base);
20 
21 var Dog = function () {
22     Dog.super().constructor.apply(this, arguments);
23 };
24 Dog.extend(Animal);
25 
26 var dog = new Dog('笨狗');
27 console.log(dog.name);//笨狗
28 console.log(dog instanceof Base);//true
29 console.log(dog instanceof Animal);//true
30 console.log(dog instanceof Dog);//true
31 
32 Function.prototype.mixin = function (name, mixinType) {
33     this.mixins = {};
34     this.mixins[name] = mixinType;
35 
36     for (var property in mixinType.prototype) {
37         if (property in this.prototype) {
38             continue;
39         }
40 
41         this.prototype[property] = mixinType.prototype[property];
42     }
43 };
44 
45 var Pet = function () {
46 };
47 Pet.prototype.aoao = function () {
48     console.log(this.name + ',嗷嗷!');
49 };
50 
51 Dog.mixin('pet', Pet);
52 dog.aoao();
53 console.log(dog instanceof Pet);//false

圖片示意

常見問題

問題:這種摻入實現是不是太簡單了?

答案:確實,但是能滿足80%的需求,摻入的主要目的就是代碼復用。

備注

由於“原型鏈”的限制,Javascript實現不了真正意義的“多重繼承”。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM