中文字幕在线一区二区在线,久久久精品免费观看国产,无码日日模日日碰夜夜爽,天堂av在线最新版在线,日韩美精品无码一本二本三本,麻豆精品三级国产国语,精品无码AⅤ片,国产区在线观看视频

      面向?qū)ο缶幊痰膉avascript基礎(chǔ)

      時(shí)間:2024-08-22 05:49:25 JavaScript 我要投稿
      • 相關(guān)推薦

      面向?qū)ο缶幊痰膉avascript基礎(chǔ)

        我們看到這里繼承的概念是多么的直白,“拷貝一個(gè)類(lèi)的prototype 到另外一個(gè)類(lèi)”,好,Code is cheap,看代碼:

        function class1() { }

        function class2() { }

        class2.prototype = class1.prototype;

        class2.moreProperty1 = " class 2 additional string " ;

        class2.moreMethod1 = function () { alert( " class 2 additional method " ); }

        /*

        這樣,首先是class2具有了和class1 一樣的prototype,不考慮構(gòu)造函數(shù),兩個(gè)類(lèi)是等價(jià)的。

        隨后,又通過(guò)prototype給class2賦予了兩個(gè)額外的方法。所以class2是在class1的基礎(chǔ)上

        增加了屬性和方法,這就實(shí)現(xiàn)了類(lèi)的繼承。

        */

        function test() {

        var obj = new class2();

        // JavaScript提供了instanceof 操作符來(lái)判斷一個(gè)對(duì)象是否是某個(gè)類(lèi)的實(shí)例

        alert(obj instanceof class2); // true

        alert(obj instanceof class1); // ?

        }

        運(yùn)行代碼,結(jié)果是不是在我們的意料之中?表面上看,上面的實(shí)現(xiàn)完全可行,js也可以正確的理解和實(shí)現(xiàn)這種繼承關(guān)系,obj同時(shí)是class1和 class2的實(shí)例,但實(shí)質(zhì)上則不然(我們學(xué)習(xí)的目的是要知其然更要知其所以然)。js的這種理解實(shí)際上是基于一種很簡(jiǎn)單的策略,看下面的代碼,先使用 prototype讓class2 繼承于class1,再在class2 中重復(fù)定義method 方法:

        // 定義class1

        function class1() {

        // 構(gòu)造函數(shù)

        }

        // 定義class1 的成員

        class1.prototype = {

        m1: function () { // 方法1

        alert( " class1 method1 " );

        }

        }

        // 定義class2

        function class2() {

        // 構(gòu)造函數(shù)

        }

        // 讓class2 繼承于class1

        class2.prototype = class1.prototype;

        // 給class2 重復(fù)定義方法method

        class2.prototype.method = function () {

        alert( " whose method2? class1 or class2 " );

        }

        // 創(chuàng)建兩個(gè)類(lèi)的實(shí)例

        var obj1 = new class1();

        var obj2 = new class2();

        function test() {

        // 分別調(diào)用兩個(gè)對(duì)象的method 方法

        obj1.method();

        obj2.method();

        }

        從代碼執(zhí)行結(jié)果看,method方法在class1,2中運(yùn)行的結(jié)果是相同的。

        由此可見(jiàn),當(dāng)對(duì)class2 進(jìn)行prototype 的改變時(shí),class1的prototype也隨之改變,即使對(duì)class2 的prototype 增減一些成員,class1的成員也隨之改變。所以class1 和class2 僅僅是構(gòu)造函數(shù)不同的兩個(gè)類(lèi),它們保持著相同的成員定義。說(shuō)到這里,相信讀者已經(jīng)發(fā)現(xiàn)了其中的奧妙:class1 和class2 的prototype 是完全相同的,是對(duì)同一個(gè)對(duì)象的引用。其實(shí)從這條賦值語(yǔ)句就可以看出來(lái):

        //讓class2 繼承于class1

        class2.prototype=class1.prototype;

        在js中,除了基本的數(shù)據(jù)類(lèi)型(數(shù)字、字符串、布爾類(lèi)型等),所有的賦值以及函數(shù)參數(shù)都是引用傳遞,而不是值傳遞。所以上面的語(yǔ)句僅僅是讓class2 的prototype 對(duì)象引用class1 的prototype,造成了類(lèi)成員定義始終保持一致的效果。從這里也看到了instanceof 操作符的執(zhí)行機(jī)制,它就是判斷一個(gè)對(duì)象是否是一個(gè)prototype 的實(shí)例,因?yàn)檫@里的obj1 和obj2 都是對(duì)應(yīng)于同一個(gè)prototype,所以它們instanceof 的結(jié)果都是相同的。由此可見(jiàn),使用prototype 引用拷貝實(shí)現(xiàn)繼承不是一種正確的辦法。但在要求不嚴(yán)格的情況下,卻也是一種合理的方法,唯一的約束是不允許類(lèi)成員的覆蓋定義(這里其實(shí)也是js的靈活性的體現(xiàn))。其實(shí),我們完全可以利用反射機(jī)制和prototype 來(lái)實(shí)現(xiàn)js正確的類(lèi)繼承:

        function class1() {

        // 構(gòu)造函數(shù)

        }

        class1.prototype = {

        method: function () {

        alert( " method1 " );

        },

        method2: function () {

        alert( " method2 " );

        }

        }

        function class2() {

        // 構(gòu)造函數(shù)

        }

        // 讓class2 繼承于class1

        for ( var p in class1.prototype) {

        class2.prototype[p] = class1.prototype[p]; // 利用反射機(jī)制和prototype實(shí)現(xiàn)繼承

        }

        // 覆蓋定義class1中的method 方法

        class2.prototype.method = function () {

        alert( " class2 new method1 " );

        }

        // 創(chuàng)建兩個(gè)類(lèi)的實(shí)例

        var obj1 = new class1();

        var obj2 = new class2();

        function test() {

        // 分別調(diào)用兩個(gè)對(duì)象的method 方法

        obj1.method();

        obj2.method();

        // 分別調(diào)用兩個(gè)對(duì)象的method2 方法

        obj1.method2();

        obj2.method2();

        }

        從運(yùn)行結(jié)果可見(jiàn),obj2中重復(fù)定義的method 已經(jīng)覆蓋了繼承的method方法,同時(shí)method2 方法未受影響。而且obj1中的method 方法仍然保持了原有的定義。這樣,就實(shí)現(xiàn)了正確意義的類(lèi)的繼承。為了方便開(kāi)發(fā),可以為每個(gè)類(lèi)添加一個(gè)共有的方法,用以實(shí)現(xiàn)類(lèi)的繼承:

        // 為類(lèi)添加靜態(tài)方法inherit表示繼承于某類(lèi)

        Function.prototype.inherit = function (baseClass) {

        for ( var p in baseClass.prototype) {

        this .prototype[p] = baseClass.prototype[p];

        }

        }

        function class1() {

        // 構(gòu)造函數(shù)

        }

        class1.prototype = {

        method: function () {

        alert( " method1 " );

        },

        method2: function () {

        alert( " method2 " );

        }

        }

        function class2() {

        // 構(gòu)造函數(shù)

        }

        // 讓class2 繼承于class1

        // for (var p in class1.prototype) {

        // class2.prototype[p] = class1.prototype[p]; // 利用反射機(jī)制和prototype實(shí)現(xiàn)繼承

        // }

        class2.inherit(class1); // 等價(jià)于上面注釋掉的那一個(gè)for循環(huán)

        // 覆蓋定義class1中的method 方法

        class2.prototype.method = function () {

        alert( " class2 new method1 " );

        }

        // 創(chuàng)建兩個(gè)類(lèi)的實(shí)例

        var obj1 = new class1();

        var obj2 = new class2();

        function test() {

        // 分別調(diào)用兩個(gè)對(duì)象的method 方法

        obj1.method();

        obj2.method();

        // 分別調(diào)用兩個(gè)對(duì)象的method2 方法

        obj1.method2();

        obj2.method2();

        }

        上面的代碼使邏輯變的更加清楚,也更容易理解。通過(guò)這種方法實(shí)現(xiàn)的繼承,有一個(gè)缺點(diǎn),就是在class2 中添加類(lèi)成員定義時(shí),不能給prototype 直接賦值,而只能對(duì)其屬性進(jìn)行賦值,例如不能為:

        class2.prototype={

        //成員定義

        }

        而只能為:

        class2.prototype.propertyName=someValue;

        class2.prototype.methodName=function(){

        //語(yǔ)句

        }

        由此可見(jiàn),這樣實(shí)現(xiàn)繼承仍然要以犧牲一定的代碼可讀性為代價(jià)。有沒(méi)有“不僅基類(lèi)可以用對(duì)象直接賦值給property,而且在派生類(lèi)中也可以同樣實(shí)現(xiàn),使代碼邏輯更加清晰,也更能體現(xiàn)面向?qū)ο蟮恼Z(yǔ)言特點(diǎn)”的js繼承方式?引號(hào)里的說(shuō)法是多么的誘人啊,繼續(xù)學(xué)習(xí)去了。

      【面向?qū)ο缶幊痰膉avascript基礎(chǔ)】相關(guān)文章:

      javascript面向?qū)ο笾械膶?duì)象怎么理解09-02

      2016年java面向?qū)ο缶幊填}庫(kù)及答案10-24

      JavaScript 基礎(chǔ)教學(xué)09-29

      javascript編程異常處理的方法08-04

      javascript克隆對(duì)象深度介紹07-25

      JavaScript中的三種對(duì)象10-24

      使用ajax操作JavaScript對(duì)象的方法09-28

      關(guān)于javascript的基礎(chǔ)知識(shí)06-13

      javascript基礎(chǔ)知識(shí)大全08-22

      s("download_bottom");

      主站蜘蛛池模板: 久久国产精品免费一区六九堂 | 日本女优在线观看一区二区三区| 亚洲嫩草影院久久精品| 国产成人无精品久久久| 美女视频永久黄网站免费观看国产| 中国精品久久久久国产| 又色又爽又黄的视频网站| 九九在线精品视频xxx| 高台县| 日韩人妻少妇中文字幕av| 国产一区二区三区观看视频| 91蜜桃臀免费在线观看| 插进去内射视频免费观看| 肃宁县| 嘉黎县| 亚洲精选视频一区二区三区| 日韩最新在线不卡av| 亚洲熟女国产熟女二区三区| 久久人妻少妇精品系列| 国产成人精品自拍视频| 德钦县| 大姚县| AV中文码一区二区三区| 久久99久久99精品免观看不卡| 久久国产A∨一二三| 久久99精品久久久久久国产人妖| av网站影片在线观看| 青青青草国产熟女大香蕉| 国产一精品一aⅴ一免费| www.久久av.com| 中文字幕日本人妻一区| 一本久久精品久久综合桃色| 永清县| 国产啪精品视频网站免| 国产一区二区内射最近人| 红桥区| 国产无卡视频在线免费观看| 国产成人自拍视频在线免费| 国产日产久久福利精品一区| 国产精品一区二区三区蜜臀| 欧美综合区自拍亚洲综合 |