国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

詳解js中的繼承(一)

Object / 2481人閱讀

摘要:構(gòu)造函數(shù),實(shí)例構(gòu)造函數(shù),是用來創(chuàng)建對(duì)象的函數(shù),本質(zhì)上也是函數(shù)。這里剛好解釋一下時(shí),說到的,可以通過實(shí)例的訪問構(gòu)造函數(shù),但是本質(zhì)上是原型對(duì)象的屬性。

前言

最近在學(xué)vue,到周末終于有空寫一些東西了(想想又能騙贊,就有點(diǎn)小激動(dòng)!)。在javascript基礎(chǔ)中,除了閉包之外,繼承也是一個(gè)難點(diǎn)。因?yàn)榭紤]到篇幅較長(zhǎng),所以打算分成兩個(gè)部分來寫。同樣基于《javascript高級(jí)程序設(shè)計(jì)》,做一個(gè)詳細(xì)的講解,如果有不對(duì)的地方歡迎指正。

準(zhǔn)備知識(shí)

為了更好的講解繼承,先把一些準(zhǔn)備知識(shí)放在前面。

1.構(gòu)造函數(shù),實(shí)例

構(gòu)造函數(shù),是用來創(chuàng)建對(duì)象的函數(shù),本質(zhì)上也是函數(shù)。與其他函數(shù)的區(qū)別在于調(diào)用方式不同:

如果通過new操作符來調(diào)用的,就是構(gòu)造函數(shù)

如果沒有通過new操作符來調(diào)用的,就是普通函數(shù)
例子:

function Person(name, age) {
   this.name = name;
   this.age = age;
 }
 //當(dāng)做構(gòu)造函數(shù)調(diào)用
 var person1 = new Person("Mike",10);
 
 //當(dāng)做普通函數(shù)調(diào)用,這里相當(dāng)于給window對(duì)象添加了name和age屬性,這個(gè)不是重點(diǎn),只要注意調(diào)用方式
 Person("Bob",12);
 
 console.log(person1)//Person {name: "Mike", age: 10}
 console.log(name)//Bob
 console.log(age)//12

var person1 = new Person("Mike",10);中,通過new操作符調(diào)用了函數(shù)Person,并且生成了person1,
這里的Person就稱為構(gòu)造函數(shù)person1稱為Person函數(shù)對(duì)象的一個(gè)實(shí)例。實(shí)可以通過實(shí)例的constructor訪問對(duì)應(yīng)的構(gòu)造函數(shù)(但是其實(shí)上這個(gè)constructor不是實(shí)例的屬性,后面會(huì)解釋為什么),看下面的例子:

 function Person(name, age) {
    this.name = name;
    this.age = age;
  }
 var person1 = new Person("Mike",10);
 var person2 = new Person("Alice",20);
 console.log(person1.constructor)//function Person(){省略內(nèi)容...}
 console.log(person2.constructor)//function Person(){省略內(nèi)容...}
2.原型對(duì)象

當(dāng)我們每次創(chuàng)建一個(gè)函數(shù)的時(shí)候,函數(shù)對(duì)象都會(huì)有一個(gè)prototype屬性,這個(gè)屬性是一個(gè)指針,指向它的原型對(duì)象原型對(duì)象的本質(zhì)也是一個(gè)對(duì)象。初次看這句話可能有點(diǎn)難以理解,舉個(gè)例子,還是剛剛那個(gè)函數(shù):

     function Person(name, age) {
        this.name = name;
        this.age = age;
     }
     console.log(Person.prototype)//object{constructor:Person}

可以看到Person.prototype指向了一個(gè)對(duì)象,即Person的原型對(duì)象,并且這個(gè)對(duì)象有一個(gè)constructor屬性,又指向了Person函數(shù)對(duì)象。是不是有點(diǎn)暈?沒關(guān)系,接下來我們就上比舉例子更好的手段--畫圖。

3.構(gòu)造函數(shù),原型對(duì)象和實(shí)例的關(guān)系

在前面,我們剛剛介紹過了構(gòu)造函數(shù),實(shí)例和原型對(duì)象,接下來我們用一張圖來表示這三者之間的關(guān)系(用ps畫這種圖真是麻煩的要死,大家有好的工具推薦一下):

從圖上我們可以看到:

函數(shù)對(duì)象的prototype指向原型對(duì)象,原型對(duì)象的constructor指向函數(shù)對(duì)象

實(shí)例對(duì)象的[Protoptype]屬性指向原型對(duì)象,這里的[Protoptype]內(nèi)部屬性,可以先理解為它是存在的,但是不允許我們?cè)L問(雖然在有些瀏覽器是允許訪問這個(gè)屬性的,但是我們先這樣理解),這個(gè)屬性的作用是:允許實(shí)例通過該屬性訪問原型對(duì)象中的屬性和方法。比如說:

    function Person(name, age) {
        this.name = name;
        this.age = age;
      }
      //在原型對(duì)象中添加屬性或者方法
     Person.prototype.sex = "男"; 
     var person1 = new Person("Mike",10);
     var person2 = new Person("Alice",20);
     //只給person2設(shè)置性別
     person2.sex = "女";
     console.log(person1.sex)//"男"
     console.log(person2.sex)//"女"

這里我們沒有給person1實(shí)例設(shè)置sex屬性,但是因?yàn)?b>[Protoptype]的存在,會(huì)訪問原型對(duì)象中對(duì)應(yīng)的屬性;
同時(shí)我們給person2設(shè)置sex屬性后輸出的是"女",說明只有當(dāng)實(shí)例本身不存在對(duì)應(yīng)的屬性或方法時(shí),才會(huì)去找原型對(duì)象上的對(duì)應(yīng)屬性或方法

補(bǔ)充一下:ECMA-262第五版的時(shí)候這個(gè)內(nèi)部屬性叫[Prototype],而_proto_Firefox,Chrome和Safari瀏覽器提供的一個(gè)屬性,在其他的實(shí)現(xiàn)里面,這個(gè)內(nèi)部屬性是沒法訪問的。所以我們能從控制臺(tái)看到的是_proto_屬性,但是我在文中用的還是[Prototype],個(gè)人認(rèn)為這樣較符合它的本質(zhì)。

tips:這里剛好解釋一下console.log(person1.constructor)時(shí),說到的,可以通過實(shí)例的constructor訪問構(gòu)造函數(shù),但是constructor本質(zhì)上是原型對(duì)象的屬性。

繼承 原型鏈

在js中,繼承的主要思路就是利用原型鏈,因此如果理解了原型鏈,繼承問題就理解了一半。在這里可以稍微休息一下,如果對(duì)前面的準(zhǔn)備知識(shí)已經(jīng)理解差不多了,就開始講原型鏈了。

原型鏈的原理是:讓一個(gè)引用類型繼承另一個(gè)引用類型的屬性和方法。
先回顧一下剛剛講過的知識(shí):

原型對(duì)象通過constructor屬性指向構(gòu)造函數(shù)

實(shí)例通過[Prototype]屬性指向原型對(duì)象

那現(xiàn)在我們來思考一個(gè)問題:如果讓原型對(duì)象等于另一個(gè)構(gòu)造函數(shù)的實(shí)例會(huì)怎么樣?
例如:

    function A() {
     
    }
    //在A的原型上綁定sayA()方法
    A.prototype.sayA = function(){
            console.log("from A")
    }
    function B(){

    }
    
     //讓B的原型對(duì)象指向A的一個(gè)實(shí)例
     B.prototype = new A();
     
     //在B的原型上綁定sayB()方法
     B.prototype.sayB = function(){
            console.log("from B")
     }
     //生成一個(gè)B的實(shí)例
     var a1 = new A();
     var b1 = new B();
     
     //b1可以調(diào)用sayB和sayA
     b1.sayB();//"from B"
     b1.sayA();//"from A"

為了方便理解剛剛發(fā)生了什么,我們?cè)偕弦粡垐D:

現(xiàn)在結(jié)合圖片來看代碼:

首先,我們創(chuàng)建了A和B兩個(gè)函數(shù)對(duì)象,同時(shí)也就生成了它們的原型對(duì)象

接著,我們給A的原型對(duì)象添加了sayA()方法
* 然后是關(guān)鍵性的一步B.prototype = new A();,我們讓函數(shù)對(duì)象B的protytype指針指向了一個(gè)A的實(shí)例,請(qǐng)注意我的描述:是讓函數(shù)對(duì)象B的protytype指針指向了一個(gè)A的實(shí)例,這也是為什么最后,B的原型對(duì)象里面不再有constructor屬性,其實(shí)B本來有一個(gè)真正的原型對(duì)象,原本可以通過B.prototype訪問,但是我們現(xiàn)在改寫了這個(gè)指針,使它指向了另一個(gè)對(duì)象,所以B真正的原型對(duì)象現(xiàn)在沒法被訪問了,取而代之的這個(gè)新的原型對(duì)象是A的一個(gè)實(shí)例,自然就沒有constructor屬性了

接下來我們給這個(gè)B.prototype指向的對(duì)象,增加一個(gè)sayB方法

然后,我們生成了一個(gè)實(shí)例b1

最后我們調(diào)用了b1的sayB方法,可以執(zhí)行,為什么?
因?yàn)閎1有[Prototype]屬性可以訪問B prototype里面的方法;

我們調(diào)用了b1的sayA方法,可以執(zhí)行,為什么?
因?yàn)閎1沿著[Prototype]屬性可以訪問B prototype,B prototype繼續(xù)沿著[Prototype]屬性訪問A prototype,最終在A.prototype上找到了sayA()方法,所以可以執(zhí)行

所以,現(xiàn)在的結(jié)果就相當(dāng)于,b1繼承了A的屬性和方法,這種[Prototype]不斷把實(shí)例和原型對(duì)象聯(lián)系起來的結(jié)構(gòu)就是原型鏈。也是js中,繼承主要的實(shí)現(xiàn)方式。

小結(jié)

因?yàn)檫@部分知識(shí)理解起來比較難,所以第一部分先寫到這里(當(dāng)然不是因?yàn)槲蚁攵鄬懸黄獊眚_贊和關(guān)注啦),大家讀到這里也可以歇口氣了,如果這一塊理解深刻,下一部分就會(huì)很輕松。
為了測(cè)試一下大家對(duì)于本文的理解程度,問一下幾個(gè)問題:

在最后一個(gè)例子里,console.log(b1.constructor),結(jié)果是什么?

B.prototype = new A(); B.prototype.sayB = function(){ console.log("from B") }這兩句的執(zhí)行順序能不能交換

最后再思考一下. 在最后一個(gè)例子里,A看似已經(jīng)是原型鏈的最頂層,那A還能再往上嗎?

以上答案在下篇中解答,讀者可以自己先試試,思考一下,有疑問也可以在評(píng)論中提出。最后,如果這篇文章對(duì)你有幫助,請(qǐng)大方的點(diǎn)收藏和推薦吧(每次都是收藏比推薦多!,組織語言,畫圖和排版都很辛苦的),你們的支持會(huì)給我更大的動(dòng)力~以上內(nèi)容屬于個(gè)人見解,如果有不同意見,歡迎指出和探討。請(qǐng)尊重作者的版權(quán),轉(zhuǎn)載請(qǐng)注明出處,如作商用,請(qǐng)與作者聯(lián)系,感謝!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/82081.html

相關(guān)文章

  • js 中的 call / apply 方法詳解和引用類型的繼承

    摘要:也就是說當(dāng)使用后,當(dāng)前執(zhí)行上下文中的對(duì)象已被替換為,后續(xù)執(zhí)行將以所持有的狀態(tài)屬性繼續(xù)執(zhí)行。借用的方法替換的實(shí)例去調(diào)用相應(yīng)的方法。實(shí)現(xiàn)引用類型的繼承其實(shí)沒有類這一概念,我們平時(shí)使用的等嚴(yán)格來說被稱作引用類型。 call 方法:object.method.call(targetObj[, argv1, argv2, .....]) apply 方法:object.method.apply(...

    cod7ce 評(píng)論0 收藏0
  • javaScript原型及原型鏈詳解(二)

    摘要:當(dāng)然這還沒完,因?yàn)槲覀冞€有重要的一步?jīng)]完成,沒錯(cuò)就是上面的第行代碼,如果沒有這行代碼實(shí)例中的指針是指向構(gòu)造函數(shù)的,這樣顯然是不對(duì)的,因?yàn)檎G闆r下應(yīng)該指向它的構(gòu)造函數(shù),因此我們需要手動(dòng)更改使重新指向?qū)ο蟆? 第一節(jié)內(nèi)容:javaScript原型及原型鏈詳解(二) 第一節(jié)中我們介紹了javascript中的原型和原型鏈,這一節(jié)我們來講利用原型和原型鏈我們可以做些什么。 普通對(duì)象的繼承 ...

    widuu 評(píng)論0 收藏0
  • JavaScript深入淺出

    摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點(diǎn)提及,但是只要善于運(yùn)用,其實(shí)基于原型的繼承模型比傳統(tǒng)的類繼承還要強(qiáng)大。中文指南基本操作指南二繼續(xù)熟悉的幾對(duì)方法,包括,,。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。 怎樣使用 this 因?yàn)楸救藢儆趥吻岸耍虼宋闹兄豢炊?8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...

    blair 評(píng)論0 收藏0
  • JavaScript繼承方式詳解

    摘要:可以通過構(gòu)造函數(shù)和原型的方式模擬實(shí)現(xiàn)類的功能。原型式繼承與類式繼承類式繼承是在子類型構(gòu)造函數(shù)的內(nèi)部調(diào)用超類型的構(gòu)造函數(shù)。寄生式繼承這種繼承方式是把原型式工廠模式結(jié)合起來,目的是為了封裝創(chuàng)建的過程。 js繼承的概念 js里常用的如下兩種繼承方式: 原型鏈繼承(對(duì)象間的繼承) 類式繼承(構(gòu)造函數(shù)間的繼承) 由于js不像java那樣是真正面向?qū)ο蟮恼Z言,js是基于對(duì)象的,它沒有類的概念。...

    Yangyang 評(píng)論0 收藏0
  • 前端文檔收集

    摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個(gè)最重要的技術(shù)點(diǎn)常用整理網(wǎng)頁性能管理詳解離線緩存簡(jiǎn)介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實(shí)現(xiàn)的大排序算法一怪對(duì)象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個(gè)最重要的技術(shù)點(diǎn) 常用meta整理 網(wǎng)頁性能管理詳解 HTML5 ...

    jsbintask 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

Object

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<