• <sub id="h4knl"><ol id="h4knl"></ol></sub>
    <sup id="h4knl"></sup>
      <sub id="h4knl"></sub>

      <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
      1. <strong id="h4knl"></strong>

      2. 面向對象編程的javascript基礎

        時間:2024-08-22 05:49:25 JavaScript 我要投稿
        • 相關推薦

        面向對象編程的javascript基礎

          我們看到這里繼承的概念是多么的直白,“拷貝一個類的prototype 到另外一個類”,好,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,不考慮構造函數,兩個類是等價的。

          隨后,又通過prototype給class2賦予了兩個額外的方法。所以class2是在class1的基礎上

          增加了屬性和方法,這就實現了類的繼承。

          */

          function test() {

          var obj = new class2();

          // JavaScript提供了instanceof 操作符來判斷一個對象是否是某個類的實例

          alert(obj instanceof class2); // true

          alert(obj instanceof class1); // ?

          }

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

          // 定義class1

          function class1() {

          // 構造函數

          }

          // 定義class1 的成員

          class1.prototype = {

          m1: function () { // 方法1

          alert( " class1 method1 " );

          }

          }

          // 定義class2

          function class2() {

          // 構造函數

          }

          // 讓class2 繼承于class1

          class2.prototype = class1.prototype;

          // 給class2 重復定義方法method

          class2.prototype.method = function () {

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

          }

          // 創建兩個類的實例

          var obj1 = new class1();

          var obj2 = new class2();

          function test() {

          // 分別調用兩個對象的method 方法

          obj1.method();

          obj2.method();

          }

          從代碼執行結果看,method方法在class1,2中運行的結果是相同的。

          由此可見,當對class2 進行prototype 的改變時,class1的prototype也隨之改變,即使對class2 的prototype 增減一些成員,class1的成員也隨之改變。所以class1 和class2 僅僅是構造函數不同的兩個類,它們保持著相同的成員定義。說到這里,相信讀者已經發現了其中的奧妙:class1 和class2 的prototype 是完全相同的,是對同一個對象的引用。其實從這條賦值語句就可以看出來:

          //讓class2 繼承于class1

          class2.prototype=class1.prototype;

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

          function class1() {

          // 構造函數

          }

          class1.prototype = {

          method: function () {

          alert( " method1 " );

          },

          method2: function () {

          alert( " method2 " );

          }

          }

          function class2() {

          // 構造函數

          }

          // 讓class2 繼承于class1

          for ( var p in class1.prototype) {

          class2.prototype[p] = class1.prototype[p]; // 利用反射機制和prototype實現繼承

          }

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

          class2.prototype.method = function () {

          alert( " class2 new method1 " );

          }

          // 創建兩個類的實例

          var obj1 = new class1();

          var obj2 = new class2();

          function test() {

          // 分別調用兩個對象的method 方法

          obj1.method();

          obj2.method();

          // 分別調用兩個對象的method2 方法

          obj1.method2();

          obj2.method2();

          }

          從運行結果可見,obj2中重復定義的method 已經覆蓋了繼承的method方法,同時method2 方法未受影響。而且obj1中的method 方法仍然保持了原有的定義。這樣,就實現了正確意義的類的繼承。為了方便開發,可以為每個類添加一個共有的方法,用以實現類的繼承:

          // 為類添加靜態方法inherit表示繼承于某類

          Function.prototype.inherit = function (baseClass) {

          for ( var p in baseClass.prototype) {

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

          }

          }

          function class1() {

          // 構造函數

          }

          class1.prototype = {

          method: function () {

          alert( " method1 " );

          },

          method2: function () {

          alert( " method2 " );

          }

          }

          function class2() {

          // 構造函數

          }

          // 讓class2 繼承于class1

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

          // class2.prototype[p] = class1.prototype[p]; // 利用反射機制和prototype實現繼承

          // }

          class2.inherit(class1); // 等價于上面注釋掉的那一個for循環

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

          class2.prototype.method = function () {

          alert( " class2 new method1 " );

          }

          // 創建兩個類的實例

          var obj1 = new class1();

          var obj2 = new class2();

          function test() {

          // 分別調用兩個對象的method 方法

          obj1.method();

          obj2.method();

          // 分別調用兩個對象的method2 方法

          obj1.method2();

          obj2.method2();

          }

          上面的代碼使邏輯變的更加清楚,也更容易理解。通過這種方法實現的繼承,有一個缺點,就是在class2 中添加類成員定義時,不能給prototype 直接賦值,而只能對其屬性進行賦值,例如不能為:

          class2.prototype={

          //成員定義

          }

          而只能為:

          class2.prototype.propertyName=someValue;

          class2.prototype.methodName=function(){

          //語句

          }

          由此可見,這樣實現繼承仍然要以犧牲一定的代碼可讀性為代價。有沒有“不僅基類可以用對象直接賦值給property,而且在派生類中也可以同樣實現,使代碼邏輯更加清晰,也更能體現面向對象的語言特點”的js繼承方式?引號里的說法是多么的誘人啊,繼續學習去了。

        《&.doc》
        将本文的Word文档下载到电脑,方便收藏和打印
        推荐度:
        点击下载文档

        【面向對象編程的javascript基礎】相關文章:

        javascript面向對象中的對象怎么理解09-02

        2016年java面向對象編程題庫及答案10-24

        JavaScript 基礎教學09-29

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

        javascript克隆對象深度介紹07-25

        JavaScript中的三種對象10-24

        使用ajax操作JavaScript對象的方法09-28

        關于javascript的基礎知識06-13

        javascript基礎知識大全08-22

        JAVA面向對象的三大特性06-14

        在线咨询
        国产高潮无套免费视频_久久九九兔免费精品6_99精品热6080YY久久_国产91久久久久久无码
      3. <sub id="h4knl"><ol id="h4knl"></ol></sub>
        <sup id="h4knl"></sup>
          <sub id="h4knl"></sub>

          <sub id="h4knl"><ol id="h4knl"><em id="h4knl"></em></ol></sub><s id="h4knl"></s>
          1. <strong id="h4knl"></strong>

          2. 亚洲综合成人AV一区在线观看 | 亚洲欧美日韩国产一区二区三区 | 午夜福利观看视频1色小妹 天天躁久久躁中文字字幕 亚洲一级高清在线观看 | 在线播放免费人成视频观 | 色综合久久中文字幕综合网 | 一区二区三区在线|欧 |

            面向對象編程的javascript基礎

              我們看到這里繼承的概念是多么的直白,“拷貝一個類的prototype 到另外一個類”,好,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,不考慮構造函數,兩個類是等價的。

              隨后,又通過prototype給class2賦予了兩個額外的方法。所以class2是在class1的基礎上

              增加了屬性和方法,這就實現了類的繼承。

              */

              function test() {

              var obj = new class2();

              // JavaScript提供了instanceof 操作符來判斷一個對象是否是某個類的實例

              alert(obj instanceof class2); // true

              alert(obj instanceof class1); // ?

              }

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

              // 定義class1

              function class1() {

              // 構造函數

              }

              // 定義class1 的成員

              class1.prototype = {

              m1: function () { // 方法1

              alert( " class1 method1 " );

              }

              }

              // 定義class2

              function class2() {

              // 構造函數

              }

              // 讓class2 繼承于class1

              class2.prototype = class1.prototype;

              // 給class2 重復定義方法method

              class2.prototype.method = function () {

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

              }

              // 創建兩個類的實例

              var obj1 = new class1();

              var obj2 = new class2();

              function test() {

              // 分別調用兩個對象的method 方法

              obj1.method();

              obj2.method();

              }

              從代碼執行結果看,method方法在class1,2中運行的結果是相同的。

              由此可見,當對class2 進行prototype 的改變時,class1的prototype也隨之改變,即使對class2 的prototype 增減一些成員,class1的成員也隨之改變。所以class1 和class2 僅僅是構造函數不同的兩個類,它們保持著相同的成員定義。說到這里,相信讀者已經發現了其中的奧妙:class1 和class2 的prototype 是完全相同的,是對同一個對象的引用。其實從這條賦值語句就可以看出來:

              //讓class2 繼承于class1

              class2.prototype=class1.prototype;

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

              function class1() {

              // 構造函數

              }

              class1.prototype = {

              method: function () {

              alert( " method1 " );

              },

              method2: function () {

              alert( " method2 " );

              }

              }

              function class2() {

              // 構造函數

              }

              // 讓class2 繼承于class1

              for ( var p in class1.prototype) {

              class2.prototype[p] = class1.prototype[p]; // 利用反射機制和prototype實現繼承

              }

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

              class2.prototype.method = function () {

              alert( " class2 new method1 " );

              }

              // 創建兩個類的實例

              var obj1 = new class1();

              var obj2 = new class2();

              function test() {

              // 分別調用兩個對象的method 方法

              obj1.method();

              obj2.method();

              // 分別調用兩個對象的method2 方法

              obj1.method2();

              obj2.method2();

              }

              從運行結果可見,obj2中重復定義的method 已經覆蓋了繼承的method方法,同時method2 方法未受影響。而且obj1中的method 方法仍然保持了原有的定義。這樣,就實現了正確意義的類的繼承。為了方便開發,可以為每個類添加一個共有的方法,用以實現類的繼承:

              // 為類添加靜態方法inherit表示繼承于某類

              Function.prototype.inherit = function (baseClass) {

              for ( var p in baseClass.prototype) {

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

              }

              }

              function class1() {

              // 構造函數

              }

              class1.prototype = {

              method: function () {

              alert( " method1 " );

              },

              method2: function () {

              alert( " method2 " );

              }

              }

              function class2() {

              // 構造函數

              }

              // 讓class2 繼承于class1

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

              // class2.prototype[p] = class1.prototype[p]; // 利用反射機制和prototype實現繼承

              // }

              class2.inherit(class1); // 等價于上面注釋掉的那一個for循環

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

              class2.prototype.method = function () {

              alert( " class2 new method1 " );

              }

              // 創建兩個類的實例

              var obj1 = new class1();

              var obj2 = new class2();

              function test() {

              // 分別調用兩個對象的method 方法

              obj1.method();

              obj2.method();

              // 分別調用兩個對象的method2 方法

              obj1.method2();

              obj2.method2();

              }

              上面的代碼使邏輯變的更加清楚,也更容易理解。通過這種方法實現的繼承,有一個缺點,就是在class2 中添加類成員定義時,不能給prototype 直接賦值,而只能對其屬性進行賦值,例如不能為:

              class2.prototype={

              //成員定義

              }

              而只能為:

              class2.prototype.propertyName=someValue;

              class2.prototype.methodName=function(){

              //語句

              }

              由此可見,這樣實現繼承仍然要以犧牲一定的代碼可讀性為代價。有沒有“不僅基類可以用對象直接賦值給property,而且在派生類中也可以同樣實現,使代碼邏輯更加清晰,也更能體現面向對象的語言特點”的js繼承方式?引號里的說法是多么的誘人啊,繼續學習去了。