日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

js面向对象和继承的碎碎念

發布時間:2025/1/21 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js面向对象和继承的碎碎念 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

一、prototype屬性的特點

1、定義在prototype中的方法是"實例方法",必須是new出來的實例,才能調用prototype中的方法,相同的方法可以被不同的實例調用,互不干擾

function?Human?(name)?{this.name?=?name; } Human.prototype?=?{sayHi:function?()?{console.log('Hi!?I\'m?'+this.name+'.');} }var?tom?=?new?Human('Tom'); tom.sayHi();//??Hi!?I'm?Tom. var?perter?=?new?Human('Perter'); perter.sayHi();//?Hi!?I'm?Perter.

可以做個小調整,將打招呼的的方法sayHi()移到構造函數中,一實例化就執行,不必單獨調用:

function?Human?(name)?{this.name?=?name;this.sayHi() } Human.prototype?=?{sayHi:function?()?{console.log('Hi!?I\'m?'+this.name+'.');} }var?tom?=?new?Human('Tom');//??Hi!?I'm?Tom. var?perter?=?new?Human('Perter');//?Hi!?I'm?Perter.

自問:但是,這樣跟在window全局作用域寫個sayHi方法,傳不同值調用有何區別?:

function?sayHi?(name)?{console.log("Hi!?I'm?"+name+'.'); } sayHi('Tom');//??Hi!?I'm?Tom. sayHi('Perter');//?Hi!?I'm?Perter.

自答:全局的function對象適合封裝簡單的小塊邏輯,如果是較為復雜的邏輯,都寫在一個function對象中會使邏輯更趨復雜,難以維護,一般會拆分成多個function,以便于管理和維護:

function?Human?(name)?{this.name?=?name;this.sayHi() } Human.prototype?=?{sayHi:function?()?{console.log('Hi!?I\'m?'+this.name+'.');},work:function?()?{console.log("For?live,I?must?work.");},eat:function?()?{console.log("For?live,I?must?eat.");}sex:function?()?{console.log("Sex?is?an?instinct");} }

上例的Human類比開始多定義了3個方法,prototype實現的是,對已經拆分的邏輯模塊(sayHi,work,eat,sex),再封裝后的復用,這是一個簡單的function對象難以做到的。

2、其他屬性定義的方法都是"靜態方法",只能在統一不變的"類"的層級調用。

??3、??獨立的json對象也是封裝邏輯的很好容器,但因為是引用類型,在相同的文檔上下文中,復用會出現后者參數覆蓋前者的情況。




二、使用prototype的注意事項

1、如果使用xx.prototype={}的方式封裝邏輯,會影響"constructor"值,所以使用后注意重置"constructor"為當前的類。方便以后判斷一個實例的構造類是誰。

function?Human?(name)?{this.name?=?name; } var?a?=?new?Human('Peter'); console.log(a.constructor);

上面代碼的輸出結果是:

我們得到了實例a的構造類是Human!

但是使用xx.prototype={}的方式封裝邏輯后:

function?Human?(name)?{this.name?=?name; } Human.prototype?=?{sayHi:function?()?{console.log("Hi!?I'm?"+this.name+'.');} } var?a?=?new?Human('Peter'); console.log(a.constructor);

輸出結果是:

我們已經不再知道實例a的構造類是誰?所以,應該重置"constructor"為當前的類:

function?Human?(name)?{this.name?=?name; } Human.prototype?=?{sayHi:function?()?{console.log("Hi!?I'm?"+this.name+'.');} } Human.prototype.constructor?=?Human; var?a?=?new?Human('Peter'); console.log(a.constructor);

輸出結果又是:

2、在構建繼承父類的子類時子類會調用父類的構造函數,生成實例,再賦值給子類的prototype。也就是子類還沒調用,子類繼承自父類的構造方法已經執行了。

//?定義"人"類 function?Human?()?{alert("hello?world!"); } Human.prototype?=?{sayHi:function?()?{console.log("hello?world!");} } Human.prototype.constructor?=?Human;//?定義"女人"類 function?Woman?(name)?{} //?"女人"類繼承"人"類 Woman.prototype?=?new?Human(); //?定義"女人"類的特有方法 Woman.prototype.bear?=?function?()?{console.log("I?can?bear?baies."); } Woman.prototype.constructor?=?Woman;

上述代碼只是定義了一個Human類,然后Woman子類繼承Human父類,還沒有實例化,就執行了

alert("hello?world!");

不僅不合理,當父類構造函數含有破壞性代碼,或者要依賴特定狀態時,還會引發其他錯誤。

所以,通常我們需要單獨封裝一個實現繼承的方法,而不是僅僅把子類的prototype賦值為父類的實例。


三、繼承方法的封裝步驟

3.1.構造一個新類,該類具有一個空的構造函數,將該類的prototype賦值為父類的prototype,然后將該類的實例賦值給子類的prototype:

function?inheritance(){}; inheritance.prototype?=?superClass.prototype; subClass.prototype?=?new?inheritance();

構造函數為空了,子類再來繼承時,也就不會出現還沒實例化,代碼已經開始執行的情況了。

3.2.重置恢復子類的constructor:

subClass.prototype.constructor?=?subClass;

便于對實例追根溯源。

3.3.子類自定義屬性(baseConstructor)保存對父類的構造函數的引用:

subClass.baseConstructor?=?superClass;

構造函數只是在過度的“inheritance”類置空了,它的引用仍然會通過子類的自定義屬性(baseConstructor)保留,方便在需要的時候調用。

3.4.如果父類自定義屬性(__super__)包含對祖父類的引用,那么這個屬性要賦值給父類prototype下的同名屬性:

if(superClass.__super__){superClass.prototype.__super__?=?superClass.__super__; }

只要保存在prototype屬性中的方法才能被后代繼承,這樣做方便子類對祖先類的方法的重寫。

3.5.子類自定義屬性(__super__)保存對父類的prototype的引用:

subClass.__super__?=?superClass.prototype;

方便子類對父類的方法的重寫。


完整的代碼:

//?實現繼承的方法 function?extend?(subClass,superClass)?{//?創建一個新的類,該類具有一個空的構造函數,并具有父類的成員function?inheritance(){};inheritance.prototype?=?superClass.prototype;//?將子類的prototype屬性設置為不帶構造函數的父類新實例subClass.prototype?=?new?inheritance();subClass.prototype.constructor?=?subClass;//?重置恢復constructor屬性subClass.baseConstructor?=?superClass;//?用自定義屬性保存父級的構造函數//?允許多重繼承if(superClass.__super__){superClass.prototype.__super__?=?superClass.__super__;}subClass.__super__?=?superClass.prototype;//?保持對父類原型的引用,方便子類重寫 }



轉載于:https://my.oschina.net/710409599/blog/618884

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的js面向对象和继承的碎碎念的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。