成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Javascript面向?qū)ο髲娜腴T到重新入門--關(guān)于繼承

3fuyu / 1032人閱讀

摘要:這個(gè)構(gòu)造函數(shù)的不管從調(diào)用方式還是內(nèi)部寫法就都很有的感覺,但是從用途上來(lái)說(shuō),它其實(shí)更靠近的概念是中的工廠方法。到這里,所有關(guān)于繼承的東西講完了,接下來(lái)準(zhǔn)備準(zhǔn)備說(shuō)說(shuō)當(dāng)中的封裝

所謂的對(duì)象,就是抽象化的數(shù)據(jù)本身
一個(gè)面向?qū)ο筠D(zhuǎn)向面向原型的困惑

我發(fā)現(xiàn)Javascript這門語(yǔ)言每次翻開都會(huì)帶給人新感受,尤其是看完其他語(yǔ)言的面向?qū)ο笤賮?lái)看它,但是如果你也是過(guò)來(lái)人就一定記得教科書里面冗長(zhǎng)乏味的面向?qū)ο?,所有的書上都?huì)跟你這么說(shuō):面向?qū)ο笫菍?duì)要解決的問(wèn)題的一種抽象,比如很經(jīng)典的Java或者C++,class就是根基,然后類實(shí)例化出對(duì)象balabala....初學(xué)者來(lái)看的話其實(shí)是很難接受的,但是挺過(guò)這個(gè)時(shí)期,就會(huì)產(chǎn)生一種理所應(yīng)當(dāng)?shù)母杏X,就會(huì)覺得:面向?qū)ο螽?dāng)然需要類啦當(dāng)然需要實(shí)例化啦,不然怎么繼承的之類的。當(dāng)然基本上主流的面向?qū)ο笳Z(yǔ)言都會(huì)提供基本相同的概念。但是有個(gè)異類就是JavaScript,如果你用其他語(yǔ)言的概念來(lái)理解這個(gè)世界里的對(duì)象可能會(huì)找不著北。因?yàn)檫@個(gè)世界里沒(méi)有“類”這個(gè)東西,所有的東西都是對(duì)象。
朝下看的時(shí)候,我建議學(xué)過(guò)面向?qū)ο蟮娜送簟邦悺边@個(gè)東西,不然很容易就會(huì)搞混。

什么是對(duì)象?

那到底什么是對(duì)象呢?這個(gè)問(wèn)題問(wèn)淺了是個(gè)傻問(wèn)題問(wèn)深了又變成了一個(gè)哲學(xué)問(wèn)題,每個(gè)語(yǔ)言甚至每個(gè)人都有不同的答案,但是如果你只有十天來(lái)設(shè)計(jì)一門語(yǔ)言的話,你肯定也是想把這個(gè)東西設(shè)計(jì)的越簡(jiǎn)單越好,所以對(duì)JavaScript來(lái)說(shuō),對(duì)象就是屬性+方法,簡(jiǎn)單來(lái)說(shuō)就是這樣:

var Person={
    name :"XXX",
    age:18,
    address:"YYY",
    gender:0,
    eat:function(){
        console.log("食");
    },
    wear:function(){
        console.log("衣");
    },
    live:function(){
        console.log("住");
    },
    walk:function(){
        console.log("行");
    }
}
Person.eat();

這樣一個(gè)對(duì)象就寫好了,不僅如此,我們?cè)谶\(yùn)行時(shí)還可以動(dòng)態(tài)的修改內(nèi)部對(duì)象的屬性,以及增加方法等等非常自由。第一眼看上去非常的直觀,但是仔細(xì)想想看,問(wèn)題其實(shí)很多,比如,屬性這樣無(wú)限制的訪問(wèn)一點(diǎn)安全性都沒(méi)有,再比如我想再要生成一個(gè)人但是名字叫小紅的,就很費(fèi)勁,再再比如我怎么實(shí)現(xiàn)繼承?問(wèn)題很多我們一個(gè)一個(gè)來(lái)說(shuō)

純對(duì)象怎么完成繼承?

其實(shí)繼承說(shuō)白了,要做的事情就是把兩個(gè)毫不相干的人建立父子關(guān)系,但是怎么建立呢?Javascript語(yǔ)言的對(duì)象生來(lái)都有一個(gè)特殊屬性叫__proto__,我們可以用這個(gè)屬性來(lái)關(guān)聯(lián)其他對(duì)象,就像這樣:

var Teacher={
    //這里添加老師的屬性和方法
    __proto__:Person
}
Teacher.eat();

這樣,兩個(gè)對(duì)象之間就建立了聯(lián)系,人類(對(duì)象)是老師(對(duì)象)的原型,用圖表示就是:

這樣一條鏈條把對(duì)象之間聯(lián)系起來(lái),這樣使用Teacher調(diào)用eat方法的時(shí)候找不到就順著鏈子朝上找一直找到頭如果沒(méi)有就報(bào)錯(cuò),看起來(lái)很完美。

怎么欺騙其他世界的程序員?

但是大家都知道高級(jí)語(yǔ)言都是要吸引別人來(lái)用的,這個(gè)方式實(shí)在是和其他語(yǔ)言不太一樣,怎么吸引其他人來(lái)用呢?本著不行就封裝一層的原則于是語(yǔ)言提供了構(gòu)造函數(shù),但是這個(gè)構(gòu)造函數(shù)到這里為止還是和其他語(yǔ)言有完全不同的意義(當(dāng)然使用上區(qū)別不大)。

function Person(){
    this.name=name;
    this.eat=function(){
        console.log(this.name+" eat food now");
    }
}

ming =new Student("xiaoming");
hong =new Student("xiaohong");

這個(gè)構(gòu)造函數(shù)的不管從調(diào)用方式還是內(nèi)部寫法就都很有Java Class的感覺,但是從用途上來(lái)說(shuō),它其實(shí)更靠近的概念是Java中的工廠方法。而且使用的時(shí)候還使用了new這個(gè)關(guān)鍵字,同時(shí)解決了上面的那個(gè)不用生成一個(gè)對(duì)象就寫一大串代碼的尷尬。同時(shí)還很靈活,你還是可以在ming或者h(yuǎn)ong這個(gè)對(duì)象上動(dòng)態(tài)添加方法。

但是上面的操作有個(gè)很操蛋的問(wèn)題就是,因?yàn)檫@個(gè)語(yǔ)言沒(méi)有類只有對(duì)象,所以你構(gòu)造函數(shù)里寫的方法會(huì)原封不動(dòng)的出現(xiàn)在新生成的對(duì)象當(dāng)中,這意味著每個(gè)新生成的對(duì)象都有相同的函數(shù),這就很浪費(fèi)而且對(duì)象多了還吃內(nèi)存。設(shè)計(jì)者當(dāng)然也想到了這個(gè)問(wèn)題,他用純對(duì)象的思考方式想了一個(gè)解決辦法,舉個(gè)例子:
現(xiàn)在有一個(gè)Person構(gòu)造函數(shù)(上面那樣的),通常使用它來(lái)生成新的對(duì)象(小紅小明等等)來(lái)通過(guò)原型鏈來(lái)訪問(wèn)父對(duì)象的方法,基于這個(gè)模型那我索性就再生成一個(gè)對(duì)象掛在Person下面,用一個(gè)屬性指向它(大家都知道我說(shuō)的就是prototype這個(gè)屬性啦),公共的方法完全可以都放在這個(gè)對(duì)象里面,但是怎么調(diào)用這些方法呢?其實(shí)大家既然都是對(duì)象,小明小紅的__proto__里面寫的只要是Person.prototype就完事了呀,說(shuō)了這么多用一個(gè)圖來(lái)標(biāo)識(shí)一下:


對(duì)我們來(lái)說(shuō)只需要關(guān)注橫著一排的原型鏈就行了,至于Person構(gòu)造函數(shù)是一個(gè)函數(shù)自然也是一個(gè)對(duì)象(函數(shù)也是對(duì)象),同樣自然有自己的原型鏈但是這里和主體無(wú)關(guān)就不體現(xiàn)在圖上了。

如果原型鏈的知識(shí)都差不多了的話我覺得就可以放出下面這張廣為人知的圖來(lái)記憶一番了:


然后寫了這么多,你就發(fā)現(xiàn)其實(shí)繼承在Javascript當(dāng)中原來(lái)也是一個(gè)謊言--只要把新的對(duì)象掛上原型鏈就算是“繼承”了。那問(wèn)題就變成了怎么構(gòu)建原型鏈,我們還是放上道爺發(fā)明的一種方式來(lái)實(shí)現(xiàn)繼承(方法多種多樣,我覺得道爺?shù)倪@種橋接并且不污染上下文環(huán)境的方式相當(dāng)好用)

//父類
function Student(props){
    this.name=props.name||"unnamed";
}
Student.prototype.hello=function(){
    console.log("Hello, " + this.name + "!");
}
//子類
function PrimaryStudent(props) {
    Student.call(this, props);
    this.grade = props.grade || 1;
}
//使用一個(gè)空構(gòu)造函數(shù)來(lái)橋接
function F(){}

F.prototype=Student.prototype; //把原本指向Function.prototype的指針指向父類
PrimaryStudent.prototype=new F();//橋接子類對(duì)象到一個(gè)F的匿名對(duì)象上
PrimaryStudent.prototype.constructor=PrimaryStudent;//糾正構(gòu)造函數(shù)指向

PrimaryStudent.prototype.getGrade=function(){
        return this.grade;
}

// 開始測(cè)試
var xiaoming=new PrimaryStudent({
    name:"xiaoming",
    grade:2
});
console.log(xiaoming.__proto__===PrimaryStudent.prototype);
console.log(xiaoming.__proto__.__proto__===Student.prototype);
console.log(xiaoming instanceof PrimaryStudent);
console.log(xiaoming instanceof Student);

使用一張圖展示上面的代碼做了什么:

done!關(guān)系就是這么橋接好的,我們?nèi)绻僭谕饷姘粚雍瘮?shù)就完全可以做工具函數(shù)來(lái)用

ES6標(biāo)準(zhǔn)下的語(yǔ)法糖

很明顯,上面的這個(gè)做法很費(fèi)勁,或者說(shuō),不直觀沒(méi)法吸引別人來(lái)用,所以ES6標(biāo)準(zhǔn)里加了一個(gè)很Java的語(yǔ)法糖,就像下面這么寫:

class Person {
    constructor(name){
        this.name=name;
    }
    hello(){
        console.log(`${this.name} say hello to you!`);
    }
}
class Teacher extends Person{
    constructor(name,gender){
        super(name);
        this.gender=gender;
    }
    myGender(){
        console.log(`${this.name}"s gender is ${this.gender}`);
    }
}

var x=new Teacher("niuguangzhe","nan");
x.myGender();

可以說(shuō)是Java味道十足,但是別忘了,其實(shí)語(yǔ)言的內(nèi)部仍然是原型鏈。

到這里,所有關(guān)于繼承的東西講完了,接下來(lái)準(zhǔn)備準(zhǔn)備說(shuō)說(shuō)Javascript當(dāng)中的封裝

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/89975.html

相關(guān)文章

  • 【連載】前端個(gè)人文章整理-基礎(chǔ)入門

    摘要:個(gè)人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現(xiàn)在已經(jīng)一年的時(shí)間了,由于工作比較忙,更新緩慢,后面還是會(huì)繼更新,現(xiàn)將已經(jīng)寫好的文章整理一個(gè)目錄,方便更多的小伙伴去學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個(gè)人前端文章整理 從最開始萌生寫文章的想法,到著手...

    madthumb 評(píng)論0 收藏0
  • D1.Nodejs 入門

    摘要:上下文切換上下文最直觀的表現(xiàn)就是代碼塊中的,通常在面向?qū)ο蟮木幊讨杏玫?,?lái)指代當(dāng)前類生成的對(duì)應(yīng)實(shí)例,與其他語(yǔ)言的一致。咦,是干嘛的,有沒(méi)有其他方式實(shí)現(xiàn),請(qǐng)自行谷歌。 分享第一篇,關(guān)于 NodeJS —— Javascript 的常用知識(shí)以及如何從 Javascript 開發(fā)者過(guò)渡到 NodeJS 開發(fā)者(不會(huì)介紹具體的框架)。在讀本文前,希望你對(duì) javascript 有一些初步的認(rèn)識(shí)...

    Rango 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.40 - 2018,來(lái)學(xué)習(xí)一門新的編程語(yǔ)言吧!

    摘要:入門,第一個(gè)這是一門很新的語(yǔ)言,年前后正式公布,算起來(lái)是比較年輕的編程語(yǔ)言了,更重要的是它是面向程序員的函數(shù)式編程語(yǔ)言,它的代碼運(yùn)行在之上。它通過(guò)編輯類工具,帶來(lái)了先進(jìn)的編輯體驗(yàn),增強(qiáng)了語(yǔ)言服務(wù)。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺已經(jīng)到來(lái)了,總結(jié)過(guò)去的 2017,相信小伙們一定有很多收獲...

    caspar 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.40 - 2018,來(lái)學(xué)習(xí)一門新的編程語(yǔ)言吧!

    摘要:入門,第一個(gè)這是一門很新的語(yǔ)言,年前后正式公布,算起來(lái)是比較年輕的編程語(yǔ)言了,更重要的是它是面向程序員的函數(shù)式編程語(yǔ)言,它的代碼運(yùn)行在之上。它通過(guò)編輯類工具,帶來(lái)了先進(jìn)的編輯體驗(yàn),增強(qiáng)了語(yǔ)言服務(wù)。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺已經(jīng)到來(lái)了,總結(jié)過(guò)去的 2017,相信小伙們一定有很多收獲...

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

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

0條評(píng)論

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