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

資訊專欄INFORMATION COLUMN

詳解js中的繼承(一)

Object / 2480人閱讀

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

前言

最近在學vue,到周末終于有空寫一些東西了(想想又能騙贊,就有點小激動!)。在javascript基礎中,除了閉包之外,繼承也是一個難點。因為考慮到篇幅較長,所以打算分成兩個部分來寫。同樣基于《javascript高級程序設計》,做一個詳細的講解,如果有不對的地方歡迎指正。

準備知識

為了更好的講解繼承,先把一些準備知識放在前面。

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

構(gòu)造函數(shù),是用來創(chuàng)建對象的函數(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;
 }
 //當做構(gòu)造函數(shù)調(diào)用
 var person1 = new Person("Mike",10);
 
 //當做普通函數(shù)調(diào)用,這里相當于給window對象添加了name和age屬性,這個不是重點,只要注意調(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ù)對象的一個實例。實可以通過實例的constructor訪問對應的構(gòu)造函數(shù)(但是其實上這個constructor不是實例的屬性,后面會解釋為什么),看下面的例子:

 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.原型對象

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

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

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

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

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

從圖上我們可以看到:

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

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

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

這里我們沒有給person1實例設置sex屬性,但是因為[Protoptype]的存在,會訪問原型對象中對應的屬性;
同時我們給person2設置sex屬性后輸出的是"女",說明只有當實例本身不存在對應的屬性或方法時,才會去找原型對象上的對應屬性或方法

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

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

繼承 原型鏈

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

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

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

實例通過[Prototype]屬性指向原型對象

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

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

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

為了方便理解剛剛發(fā)生了什么,我們再上一張圖:

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

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

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

接下來我們給這個B.prototype指向的對象,增加一個sayB方法

然后,我們生成了一個實例b1

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

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

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

小結(jié)

因為這部分知識理解起來比較難,所以第一部分先寫到這里(當然不是因為我想多寫一篇來騙贊和關注啦),大家讀到這里也可以歇口氣了,如果這一塊理解深刻,下一部分就會很輕松。
為了測試一下大家對于本文的理解程度,問一下幾個問題:

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

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

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

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

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

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

相關文章

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

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

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

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

    widuu 評論0 收藏0
  • JavaScript深入淺出

    摘要:理解的函數(shù)基礎要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當作缺點提及,但是只要善于運用,其實基于原型的繼承模型比傳統(tǒng)的類繼承還要強大。中文指南基本操作指南二繼續(xù)熟悉的幾對方法,包括,,。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 怎樣使用 this 因為本人屬于偽前端,因此文中只看懂了 8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...

    blair 評論0 收藏0
  • JavaScript繼承方式詳解

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

    Yangyang 評論0 收藏0
  • 前端文檔收集

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

    jsbintask 評論0 收藏0

發(fā)表評論

0條評論

Object

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<