中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript繼承方式介紹

發布時間:2021-08-12 16:44:51 來源:億速云 閱讀:106 作者:chen 欄目:web開發

本篇內容介紹了“JavaScript繼承方式介紹”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

1、構造函數方式寫類,通過方法調用復制父類屬性/字段到子類 實現繼承

這里父類,子類都采用構造函數方式寫,不用原型。子類調用父類函數來復制父類的屬性。

/**   * 父類Polygon:多邊形   * @param {Object} sides   */ function Polygon(sides) {      this.sides = sides;      this.setSides = function(s) {this.sides=s;}  }   /**   * 子類Triangle:三角形   */ function Triangle() {      this.tempfun = Polygon;//父類引用賦值給子類的一個屬性tempfun      this.tempfun(3);//調用      delete this.tempfun;//刪除該屬性      this.getArea = function(){};  }   //new個對象   var tri = new Triangle();  console.log(tri.sides);//繼承的屬性  console.log(tri.setSides);//繼承的方法  console.log(tri.getArea);//自有的方法   //缺點是對于Triangle的實例對象用instanceof為父類Polygon時是false  console.log(tri instanceof Triangle);//true  console.log(tri instanceof Polygon);//false

因為 JavaScript中具名函數的多種調用方式 ,子類還可以有以下的多種實現方式。只是在子類中調用父類方法不同而已。

function Triangle() {      Polygon.call(this,3); //call方式調用父類      this.getArea = function(){};      }  function Triangle() {      Polygon.apply(this,[3]); //apply方式調用父類      this.getArea = function(){};  }  function Triangle() {      var temp = new Polygon(3); //new方式調用父類      for(atr in temp) { //全部復制給子類          this[atr] = temp[atr];      }         this.getArea = function(){};  }

這種方式的缺點是子類的實例對象用instanceof檢查父類時總是false。這與java中繼承"is a "的關系是違背的。

2、原型方式寫類,原型方式繼承

core JS自身的對象系統就是采用原型方式(prototype based)繼承的。或者說core JS沒有采用常見的類繼承(class based)系統,而是使用原型繼承來實現自己的對象系統。工作中我們也可以用原型方式來實現繼承,代碼復用以構建自己的功能模塊。

/**   * 父類Polygon:多邊形   *    */ function Polygon() {}  Polygon.prototype.sides = 0;  Polygon.prototype.setSides = function(s) {this.sides=s;}   /**   * 子類Triangle:三角形   */ function Triangle() {}  Triangle.prototype = new Polygon(); //這是原型繼承關鍵的一句  Triangle.prototype.getArea = function(){}   //new個對象  var tri = new Triangle();  console.log(tri.sides);//繼承的屬性  console.log(tri.setSides);//繼承的方法  console.log(tri.getArea);//自有方法   //instanceof測試  console.log(tri instanceof Triangle);//true,表明該對象是三角形  console.log(tri instanceof Polygon);//true,表明三角形也是多邊形

雖然從輸出可以看出子類繼承了父類Polygon的屬性sides和方法setSides,但sides是0,怎么會是三角形呢。還得調用下tri.setSides(3)使之成為三角形。這樣似乎很不方便。不能傳參數,即是原型方式的缺點。優點是正確的維護了"is a"的關系。

3、組合構造函數/原型方式寫類,采用前面種方式繼承

這種方式父類,子類的屬性都掛在構造函數里,方法都掛在原型上。

/**   * 父類Polygon:多邊形   */ function Polygon(sides) {      this.sides = sides;  }  Polygon.prototype.setSides = function(s) {this.sides=s;}   /**   * Triangle 三角形   * @param {Object} base 底   * @param {Object} height 高   */ function Triangle(base,height) {      Polygon.call(this,3);//復制父類屬性給自己      this.base = base;      this.height = height;  }  Triangle.prototype = new Polygon();//復制父類方法給自己   Triangle.prototype.getArea = function(){ //***定義自己的方法      return this.base*this.height/2;  }   //new個對象  var tri = new Triangle(12,4);  console.log(tri.sides);//繼承的屬性  console.log(tri.setSides);//繼承的方法  console.log(tri.base);//自有屬性  console.log(tri.height);//自有屬性  console.log(tri.getArea);//自有方法   //instanceof測試,表明正確的維護了"is a"的關系  console.log(tri instanceof Triangle);//true,表明該對象是三角形  console.log(tri instanceof Polygon);//true,表明三角形也是多邊形

這篇開始寫幾個工具函數實現類的擴展。每個工具函數都是針對特定的寫類方式(習慣)。這篇按照構造函數方式寫類:屬性(字段)和方法都掛在this上。以下分別提供了個類,分別作為父類和子類。

//  父類Person  function Person(nationality) {      this.nationality = nationality;      this.setNationality = function(n) {this.nationality=n;};      this.getNationality = function() {return this.nationality;};  }   // 類Man  function Man(name) {      this.name = name;      this.setName = function(n){this.name=n;};      this.getName = function(){return this.name;};  }

繼承工具函數一

/**   * @param {Function} subCls 子類   * @param {Function} superCls 父類   * @param {Object} param 父類構造參數   */ function extend(subCls,superCls,param) {      superCls.call(subCls.prototype,param);  }

使用如下

extend(Man,Person,'China');  var m = new Man('jack');  console.log(m.nationality);//China  console.log(m.setNationality('Japan'));  console.log(m.getNationality('Japan'));//Japan

輸出可以看到Man繼承了Person的屬性及所有方法。這種繼承方式于java的很不一樣哦,

class Animal {      int legs;         Animal(int l) {          legs = l;      }      int getLegs() {          return legs;      }  }  public class Person extends Animal{      //屬性(字段)      String name;          //構造方法(函數)      Person(int legs, String name) {          super(legs);//調用父類構造器          this.name = name;      }         //方法      String getName() {          return this.name;      }      public static void main(String[] args) {                    Person p = new Person(2,"jack");                  System.out.println(p.legs);      }  }

Java中,子類Person在自身構造方法中調用父類構造方法super(legs),創建對象的時候直接將父類構造參數legs:2傳進去,不僅僅只傳自己的name:jack。上面JavaScript繼承是在extend時傳父類構造參數(extend函數的第三個參數),而不是在new Man時將父類構造參數傳過去。好,模擬Java來實現下extend,這里巧妙的在子類上暫存了父類引用。

繼承工具函數二

/**   * @param {Function} subCls   * @param {Function} superCls   */ function extend(subCls,superCls) {        subCls.supr = superCls;  }

還是以Person為父類,來實現子類Woman

function Woman(nationality,name) {      Woman.supr.call(this,nationality);//和java有點類似哦,在子類中調用父類構造器      this.name = name;      this.setName = function(n){this.name=n;};      this.getName = function(){return this.name;};  }<br>extend(Woman,Person);<br>

***,創建對象的方式和java也類似,即new的時候同時將父類構造參數(nationality:Japan)傳進去。

var w = new Woman('Japan','lily');  console.log(w.nationality);//Japan  w.setNationality('U.S.A');  console.log(w.getNationality());//U.S.A

繼承工具函數三

/**   * @param {Function} subCls   * @param {Function} superCls   */ function extend(subCls,superCls) {      subCls.prototype = new superCls();    }

父類,按原型方式寫,即屬性和方法都掛在原型上。

/**   *  父類Person   */ function Person(){}  Person.prototype.nationality = 'China';  Person.prototype.getNationality = function() {return this.nationality;}  Person.prototype.setNationality = function(n) { this.nationality = n;}

子類繼承與父類

function Man() {}  extend(Man,Person);

繼承父類的屬性和方法后,再添加子類自有屬性,方法

Man.prototype.name = 'jack';  Man.prototype.getName = function() { return this.name;}  Man.prototype.setName = function(n) { this.name=n;}

測試如下,

var m = new Man();  console.log(m);  console.log(m instanceof Person);

可以看到這種寫類方式,繼承方式完全采用原型機制。

繼承工具函數四

這種方式是目前比較流行的,51ditu網站的開發就是按照這種模式的。

/**   * @param {Function} subCls 子類   * @param {Function} superCls 父類   */ function extend(subCls,superCls) {        //暫存子類原型      var sbp = subCls.prototype;      //重寫子類原型--原型繼承      subCls.prototype = new superCls();      //重寫后一定要將constructor指回subCls      subCls.prototype.constructor = subCls;      //還原子類原型      for(var atr in sbp) {          subCls.prototype[atr] = sbp[atr];      }      //暫存父類        subCls.supr = superCls;  }

按 構造函數+原型 方式寫類,即屬性掛在this上,方法掛在prototype上。

/**   *  父類Person   */ function Person(nationality){      this.nationality = nationality;  }  Person.prototype.getNationality = function() {return this.nationality;}  Person.prototype.setNationality = function(n) { this.nationality = n;}   /**   *  子類Man   */ function Man(nationality,name) {      Man.supr.call(this,nationality); //很重要的一句,調用父類構造器      this.name = name;  }  Man.prototype.getName = function() {return this.name;}  Man.prototype.setName = function(n) {this.name=n;}

注意子類Man中要顯示的調用父類構造器已完成父類的屬性/字段拷貝。

extend調用,創建Man的實例

extend(Man,Person);  var m = new Man('USA','jack');  console.log(m);  m.setName('lily');  console.log(m.name);

繼承工具函數五

/**   * @param {String} className   * @param {String/Function} superClass   * @param {Function} classImp   */ function $class(className, superClass, classImp){      if(superClass === "") superClass = Object;      var clazz = function(){          return function(){              if(typeof this.init == "function"){                  this.init.apply(this, arguments);              }          };      }();      var p = clazz.prototype = new superClass();      var _super = superClass.prototype;      window[className] = clazz;      classImp.apply(p, [_super]);  }

定義父類Person

/**   * 父類 Person   */ $class('Person','',function(){      this.init = function(name){          this.name = name;      };      this.getName = function(){          return this.name;      };      this.setName = function(name){          this.name = name;      }  });

子類Man

/**   * 子類 Man   */ $class('Man', Person, function(supr){      this.init = function(name, age){          supr.init.apply(this,[name]); // 該句很重要          this.age = age;      };      this.getAge = function(){          return this.age;      };      this.setAge = function(age){          this.age = age;      };  });  var m = new Man('Jack',25);  console.log(m.name); // Jack  console.log(m.age); // 25

從輸出看可以看到子類Man的確繼承了父類的屬性和方法。

“JavaScript繼承方式介紹”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

桃源县| 包头市| 会理县| 沂水县| 舟曲县| 长沙市| 平原县| 沭阳县| 衡水市| 清河县| 邹城市| 五台县| 龙川县| 合阳县| 金山区| 金堂县| 高阳县| 威远县| 台中县| 赞皇县| 化德县| 新绛县| 扶余县| 林州市| 什邡市| 安达市| 神农架林区| 柳江县| 乌兰察布市| 安化县| 武宣县| 云阳县| 施秉县| 陆良县| 周至县| 东乌珠穆沁旗| 湛江市| 洞口县| 通化县| 敦煌市| 保康县|