国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > JS > 正文

JS學習筆記之原型鏈和利用原型實現繼承詳解

2024-05-06 16:51:32
字體:
來源:轉載
供稿:網友

本文實例講述了JS學習筆記之原型鏈和利用原型實現繼承。分享給大家供大家參考,具體如下:

原型鏈

原型鏈是一種關系,實例對象和原型對象之間的關系,關系是通過原型(__proto__)來聯系的

實例對象中有__proto__,是對象,叫原型,不是標準的屬性,瀏覽器使用,并且有的游覽器不支持
構造函數中有prototype屬性,也是對象,叫原型

注意 原型中的方法是可以互相訪問的

實例代碼

 function Animal(name,age){    this.name=name;    thia.age=age;   }   //在原型中添加方法   Animal.prototype.eat=function(){    console.log("動物吃草")    this.play()   }   Animal.prototype.play=function(){    console.log("玩啥呢")   }

原型的簡單語法  

利用原型共享數據

第一種 寫法

 function Student(name,age,sex){      this.name=name;      this.age=age;      this.sex=sex;   }     Student.prototype.height="188"   Student.prototype.weight="55kg"   Student.prototype.study=function(){      console.log("好好學習i")    }  var stu=new Student("小紅",20,"男")  console.dir(stu)

結果

JS,原型鏈,繼承

第二種 寫法

 function Student(name,age,sex){      this.name=name;      this.age=age;      this.sex=sex;   }  Student.prototype={    height:"188",    weight:"55kg",    study:function(){      console.log("好好學習i")    }   }  var stu=new Student("小紅",20,"男")  console.dir(stu)

 

結果

JS,原型鏈,繼承

我們會發現 兩種寫法還是有差別的  ,第二種寫法會導致constructor構造器屬性消失 所以我們得手動修改構造器指向

最終代碼

function Student(name,age,sex){      this.name=name;      this.age=age;      this.sex=sex;   }  Student.prototype={    constructor:Student,    height:"188",    weight:"55kg",    study:function(){      console.log("好好學習i")    }   }  var stu=new Student("小紅",20,"男")  console.dir(stu)

 

好了,這回有了

JS,原型鏈,繼承

實例對象使用屬性或方法的規則

實例對象使用的屬性或方法,現在實例中查找,如果有則使用自身的屬性或方法,
如果沒有,則通過__proto__指向的原型對象 查找方法,找到則使用,
如果找不到則繼續向__proto__尋找,直到未找到時報錯

構造函數和實例對象和原型對象之間的關系

     構造函數可以實例化對象
     構造函數中有一個屬性叫prototype,是構造函數的原型對象
     構造函數的原型對象(prototype)中有一個constructor 構造器,這個構造器指向的就是自己所在的原型對象所在的構造函數
     實例對象的原型對象(__proto__) 指向的是該構造函數的原型對象(prototype)
     構造函數的原型對象(prototype)中的方法是可以被實例對象直接訪問

改變原型是否可以改變?

首先我們得知道構造函數和實例對象中的this 指向的是什么

這里我創建了自定義構造函數 Person ,并在內部輸出了this 

并且在Person 的原型對象上添加了一個eat 方法,也輸出了一個this,

接著我實例化了一個對象,并調用eat方法,

我們執行一下,查看結果如何

JS,原型鏈,繼承

輸出結果

JS,原型鏈,繼承

由此得出

原型對象中方法中的this 就是實例對象

構造函數中的this就是實例對象

接下來我們嘗試改變一下原型的指向

JS,原型鏈,繼承

這段代碼中,首先我定義了一個Person自定義構造函數,并且在原型上添加了一個eat方法

定義了一個Student 函數,在原型上定義了一個sayHi方法,

然后我將 Student的原型指向 了一個 Person的實例對象

接著實例化一個Student,接著分別在stu 實例上 嘗試著調用 eat方法 和 sayHi 方法,

運行結果

JS,原型鏈,繼承

到此我們可以確定,stu實例對象原型指向被下面這條代碼改變了

Student.prototype=new Person(10);

總結

原型指向可以被改變的

實例對象的原型__proto__指向的是該對象所在的構造函數的原型對象

構造函數的原型對象(prototype)指向如果改變了,實例對象的原型(__proto__)指向也會發生改變

實例對象和原型對象之間的關系是通過__proto__ 原型來聯系起來的,這個關系就是原型鏈

如果原型指向改變了,那么就應該再原型改變指向之后添加原型方法

那么sayHi方法則會創建在 new Person(10) 這個實例對象上

原型最終指向了哪里

實例對象中的__proto__指向的是構造函數的prototype

以此代碼為例

JS,原型鏈,繼承

測試一下

JS,原型鏈,繼承

JS,原型鏈,繼承

所以

per實例對象的__proto__ ---指向--->  Person.prototype的__proto__  ---指向--->  Object.prototype的__proto__ 是Null

查看了一下html的dom對象,這有很有意思的原型鏈

JS,原型鏈,繼承

這里祭出祖傳JPG

JS,原型鏈,繼承

實現繼承

小知識---->instanceof的判斷方法:

從左邊操作數的__proto__路線出發,從右邊操作數的prototype出發,如果兩條路線最終指向一個引用就是true了

1.利用 call 借用構造函數繼承

優點:實現了繼承屬性,但值都不相同

缺點: 無法繼承父級類別中原型上的方法

function Person(name,age,sex,weight){  this.name=name;  this.age=age;  this.sex=sex;  this.weight=weight;}Person.prototype.sayHi=function(){  console.log("您好")}function Student(name,age,sex,weight,score){  //將當前實例對象傳入Person 借過來使用一次來達到繼承效果  Person.call(this,name,age,sex,weight);  this.score=score;}var stu1=new Student("小明",10,"男","10kg","100")

2.  prototype 實現繼承

利用prototype,將Student 的prototype 指向 Person 來達到繼承效果,

優點:繼承了父級原型上的方法

缺點:   實例化多個Student 都必須共用相同的name 和 age 

Student.prototype.constructor=Student

注意:   使用原型繼承時,需要將構造器的指向更改回正確的指向

function Person(name,age){    this.name=name;    this.age=age;   }   Person.prototype.eat=function(){    console.log("Person 吃飯")   }   function Student(num,score){    this.num=num    this.score=score   }   //繼承  Student.prototype=new Person("小紅",10)  Student.prototype.constructor=Student  var stu =new Student(2016002288,80)  stu.eat()//Person 吃飯

3.組合繼承

組合繼承其實就是結合了上述的兩種方法來實現繼承,擁有兩種方法的優點

function Person(name,age,sex){    this.name=name;    this.age=age;    this.sex=sex;   }   Person.prototype.sayHi=function(){    console.log("你好")   }   function Student(name,age,sex,score){    //借用構造函數    Person.call(this,name,age,sex)    this.score=score   }   // 改變了原型指向   Student.prototype=new Person();//不傳值   Student.prototype.eat=function(){    console.log("吃東西");   }   var stu=new Student("小黑",20,"男","100分")   console.log(stu.name,stu.age,stu.sex,stu.score);   stu.sayHi()//你好   stu.eat()//吃東西

4.拷貝繼承

類似于復制,把一個對象中的屬性和方法直接復制到另一個對象中

function Person(){  }  Person.prototype.name="小紅"  Person.prototype.age=18  function Student(){  }    var p=Person.prototype;  var s=Student.prototype;  for(key in p){    s[key]=p[key]  }  console.dir(Student)

console

JS,原型鏈,繼承

每次都要for in 好累 ,  可以進行優化封裝一下

function extend(Child,Parent) {    var p = Parent.prototype;    var c = Child.prototype;    for (var i in p) {      c[i] = p[i];      }        //這個屬性直接指向父對象的prototype屬性,可以直接調用父對象的方法,為了實現繼承的完備性,純屬備用性質    c.par = p;  }

5. 直接繼承prototype

優點 : 效率比較高

缺點 : 因為相當于是個傳址過程 所以修改Student的屬性 Person 的也會被更改 

  function Person(){};  Person.prototype.name="小紅";  Person.prototype.age=18;  function Student(){};  Student.prototype=Person.prototype;  console.dir(Student);  console.dir(Person);  Student.prototype.age=25;

console

JS,原型鏈,繼承

6.利用空對象作中介實現繼承

用這種方式修改 Student 的prototype 不會影響到 Person的prototype

function Person(){};  Person.prototype.name="小紅";  Person.prototype.age=11;  function Student(){};  var F=function(){};  F.prototype=Person.prototype;  Student.prototype=new F();  Student.prototype.constructor=Student;  Student.prototype.age=25;  console.dir(Person)  console.dir(Student)

console

JS,原型鏈,繼承

封裝一下

function extend(Child,Parent) {    var F = function(){};    F.prototype = Parent.prototype;    Child.prototype = new F();    Child.prototype.constructor = Child;    Child.par = Parent.prototype;  }

 

希望本文所述對大家JavaScript程序設計有所幫助。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 桂东县| 汉源县| 涞源县| 阳东县| 色达县| 宿州市| 伊金霍洛旗| 屏东市| 峡江县| 虹口区| 内丘县| 金昌市| 沙雅县| 慈利县| 张家界市| 天峨县| 德令哈市| 张家港市| 祥云县| 小金县| 娱乐| 苍梧县| 四会市| 浪卡子县| 岗巴县| 灵寿县| 科技| 江陵县| 德庆县| 杭锦后旗| 丰台区| 板桥市| 平南县| 高清| 山东省| 麦盖提县| 昭平县| 株洲市| 綦江县| 新龙县| 崇明县|