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

資訊專(zhuān)欄INFORMATION COLUMN

JavaScript繼承的思想實(shí)現(xiàn)

PingCAP / 490人閱讀

摘要:本質(zhì)上是摒棄類(lèi),不調(diào)用構(gòu)造函數(shù),而是用,直接讓新對(duì)象繼承舊對(duì)象的屬性。基于類(lèi)型的繼承基于類(lèi)型的繼承是通過(guò)構(gòu)造函數(shù)依賴(lài)于原型的繼承,而非依賴(lài)于對(duì)象。例如需要通過(guò)來(lái)訪(fǎng)問(wèn)基類(lèi)的構(gòu)造函數(shù)繼承自。

JavaScript作為一門(mén)語(yǔ)法比較松散的語(yǔ)言,在ES6之前并沒(méi)有像C++/Java等傳統(tǒng)OO語(yǔ)言一樣有class關(guān)鍵字,也不能通過(guò)private,public等關(guān)鍵字來(lái)限定權(quán)限。本篇就介紹一下JavaScript是如何實(shí)現(xiàn)繼承的(js的繼承說(shuō)白了只是一種思想上的繼承,在代碼級(jí)別并沒(méi)有像java的天然繼承,在編寫(xiě)js的時(shí)候采用oo思想,能更簡(jiǎn)單的優(yōu)化和擴(kuò)展代碼)。

JavaScript的繼承可以分為兩類(lèi):
? 基于對(duì)象的繼承
? 基于類(lèi)型的繼承

基于對(duì)象的繼承
基于對(duì)象的繼承也叫原型繼承。我們知道通過(guò)JavaScript字面量創(chuàng)建的對(duì)象都會(huì)連接到Object.prototype,因此我們用Object.prototype來(lái)實(shí)現(xiàn)繼承。本質(zhì)上是摒棄類(lèi),不調(diào)用構(gòu)造函數(shù),而是用Object.create(),直接讓新對(duì)象繼承舊對(duì)象的屬性。例如:

</>復(fù)制代碼

  1. var person = {
  2. name: "Jack",
  3. getName: function () { return this.name; }
  4. }
  5. var p1 = Object.create(person);
  6. console.log(p1.getName()); //Jack

代碼很簡(jiǎn)單,person有一個(gè)屬性和一個(gè)方法。對(duì)象p1通過(guò)Object.create()來(lái)繼承,第一個(gè)參數(shù)prototype指向person的prototype,這樣對(duì)象p1就繼承了person的屬性和方法。
Object.create()還可以指定第二個(gè)參數(shù),即數(shù)據(jù)屬性,將其添加到新對(duì)象中。數(shù)據(jù)屬性可設(shè)4個(gè)描述符value, writable,enumerable,configurable 。后3個(gè)看名字也能猜出意思,不指定的話(huà)默認(rèn)為false。因?yàn)楹捅酒P(guān)系不大,就不跑題了,只看看設(shè)置value的情況:

</>復(fù)制代碼

  1. var p2 = Object.create(person, {
  2. name: {
  3. value: "Zhang"
  4. }
  5. });
  6. console.log(p2.getName()); //Zhang

用Object.create()相當(dāng)于創(chuàng)建了一個(gè)全新的對(duì)象,你可以給該對(duì)象任意新增,重載它的屬性和方法:

</>復(fù)制代碼

  1. var person = {
  2. name: "Jack",
  3. getName: function () { return this.name; },
  4. getAge: function() { return this.age; } //注意并沒(méi)有age這個(gè)成員變量,依賴(lài)子類(lèi)實(shí)現(xiàn)
  5. }
  6. var p3 = Object.create(person);
  7. p3.name = "Rose";
  8. p3.age = 17;
  9. p3.location = "上海";
  10. p3.getLocation = function() { return this.location; }
  11. console.log(p3.getName()); //Rose
  12. console.log(p3.getAge()); //17
  13. console.log(p3.getLocation()); //上海

在person中并沒(méi)有age這個(gè)屬性,因此你調(diào)用person.getAge();將得到undefined。但在對(duì)象p3里新定義了age這個(gè)屬性,于是就能正確地調(diào)用基類(lèi)的getAge方法。另外子類(lèi)重載了name的值,且新定義了location屬性和getLocation方法。結(jié)果如上所示,不贅述。

基于類(lèi)型的繼承
基于類(lèi)型的繼承是通過(guò)構(gòu)造函數(shù)依賴(lài)于原型的繼承,而非依賴(lài)于對(duì)象。例如:

</>復(fù)制代碼

  1. function Person(name) {
  2. this.name = name;
  3. this.getName = function () { return this.name; };
  4. }
  5. function Student(name, age) {
  6. Person.call(this, name);
  7. this.age = age;
  8. this.getAge = function () { return this.age; };
  9. }
  10. Student.prototype = new Person(); //需要通過(guò)new來(lái)訪(fǎng)問(wèn)基類(lèi)的構(gòu)造函數(shù)
  11. var p = new Person("Cathy");
  12. var s = new Student("Bill", 23);
  13. console.log(p.getName()); //Cathy
  14. console.log(s.getName()); //Bill
  15. console.log(s.getAge()); //23

Student繼承自Person。name雖然是在基類(lèi)Person里被定義的,但用new調(diào)用Person的構(gòu)造函數(shù)后,this將被綁定到子類(lèi)Student對(duì)象上,因此name最終是定義在子類(lèi)Student對(duì)象上的。結(jié)果如上所示,不贅述。
保護(hù)隱私
之所以定義getName,getAge等方法就是不想讓用戶(hù)直接訪(fǎng)問(wèn)name,age等屬性。可惜上面兩種繼承均無(wú)法保護(hù)隱私,均可像p.name,p.age這樣直接訪(fǎng)問(wèn)屬性。如果認(rèn)為這些屬性的隱私非常重要,希望模擬出OO語(yǔ)言中private屬性的效果,可以用函數(shù)模塊化。
所謂函數(shù)模塊化,本質(zhì)上就是在函數(shù)內(nèi)新建一個(gè)對(duì)象,新對(duì)象的方法里使用參數(shù)對(duì)象的屬性,然后將新對(duì)象返回。此時(shí)新對(duì)象里是沒(méi)有參數(shù)對(duì)象的屬性的,達(dá)到了保護(hù)隱私的目的。代碼如下:

</>復(fù)制代碼

  1. var person = function(spec) {
  2. var that = {}; //新對(duì)象
  3. that.getName = function () { return spec.name; }; //使用參數(shù)的屬性
  4. that.getAge = function() { return spec.age; }; //使用參數(shù)的屬性
  5. return that; //返回新對(duì)象
  6. }
  7. var p4 = person({name: "Jane", age: 20});
  8. console.log(p4.name); //undefined
  9. console.log(p4.age); //undefined
  10. console.log(p4.getName()); //Jane
  11. console.log(p4.getAge()); //20

因?yàn)楹瘮?shù)person返回的是新對(duì)象that,而that里并沒(méi)有name和age屬性,因此直接訪(fǎng)問(wèn)會(huì)得到undefined。只能通過(guò)that暴露出的兩個(gè)接口來(lái)獲取name和age。
進(jìn)一步實(shí)現(xiàn)多層繼承也非常方便,效果如下,不贅述:

</>復(fù)制代碼

  1. var student = function(spec) {
  2. var that = person(spec); //新對(duì)象繼承自person
  3. that.getRole = function() { return "student"; }; //新對(duì)象增加方法
  4. that.getInfo = function() {
  5. return spec.name + " " + spec.age + " " + that.getRole();
  6. };
  7. return that; //返回新對(duì)象
  8. };
  9. var p5 = student({name:"Andy", age:12});
  10. console.log(p5.name); //undefined
  11. console.log(p5.getName()); //Andy
  12. console.log(p5.getRole()); //student
  13. console.log(p5.getInfo()); //Andy 12 student

更多資源上:去轉(zhuǎn)盤(pán);或者加我的QQ群參與js,css的討論學(xué)習(xí)(QQ群:512245829)

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

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

相關(guān)文章

  • javascript高級(jí)程序設(shè)計(jì)》第六章 讀書(shū)筆記 之 javascript繼承6種方法

    摘要:繼承的是超類(lèi)型中構(gòu)造函數(shù)中的屬性,如上繼承了屬性,但沒(méi)有繼承原型中的方法。上述造成的結(jié)果是子類(lèi)型實(shí)例中有兩組超類(lèi)型的構(gòu)造函數(shù)中定義的屬性,一組在子類(lèi)型的實(shí)例中,一組在子類(lèi)型實(shí)例的原型中。 ECMAScript只支持實(shí)現(xiàn)繼承,主要依靠原型鏈來(lái)實(shí)現(xiàn)。與實(shí)現(xiàn)繼承對(duì)應(yīng)的是接口繼承,由于script中函數(shù)沒(méi)有簽名,所以無(wú)法實(shí)現(xiàn)接口繼承。 一、原型鏈 基本思想:利用原型讓一個(gè)引用類(lèi)型繼承另一個(gè)引用...

    孫吉亮 評(píng)論0 收藏0
  • JavaScript 原型中哲學(xué)思想

    摘要:而作為構(gòu)造函數(shù),需要有個(gè)屬性用來(lái)作為以該構(gòu)造函數(shù)創(chuàng)造的實(shí)例的繼承。 歡迎來(lái)我的博客閱讀:「JavaScript 原型中的哲學(xué)思想」 記得當(dāng)年初試前端的時(shí)候,學(xué)習(xí)JavaScript過(guò)程中,原型問(wèn)題一直讓我疑惑許久,那時(shí)候捧著那本著名的紅皮書(shū),看到有關(guān)原型的講解時(shí),總是心存疑慮。 當(dāng)在JavaScript世界中走過(guò)不少旅程之后,再次萌發(fā)起研究這部分知識(shí)的欲望,翻閱了不少書(shū)籍和資料,才搞懂...

    sugarmo 評(píng)論0 收藏0
  • JavaScript實(shí)現(xiàn)繼承

    摘要:使用原型鏈實(shí)現(xiàn)對(duì)原型屬性和方法的繼承,而通過(guò)借用構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)對(duì)實(shí)例屬性的繼承。總結(jié)實(shí)現(xiàn)繼承有種方式原型鏈繼承借用構(gòu)造函數(shù)繼承組合繼承原型式繼承寄生式繼承寄生組合式繼承寄生組合式繼承是大家公認(rèn)的最好的實(shí)現(xiàn)引用類(lèi)型繼承的方法。 簡(jiǎn)介 本文不準(zhǔn)備深入細(xì)節(jié),主要是對(duì)《JavaScript高級(jí)程序設(shè)計(jì)中》介紹的JS如何實(shí)現(xiàn)繼承做一個(gè)總結(jié),畢竟好記性不如爛筆頭。文末會(huì)附帶一張神圖,搞清楚這張圖,...

    岳光 評(píng)論0 收藏0
  • 再談JavaScript面向?qū)ο?em>思想及繼承

    摘要:面向?qū)ο笾杏腥筇卣鳎庋b,繼承,多態(tài)。這不僅無(wú)法做到數(shù)據(jù)共享,也是極大的資源浪費(fèi),那么引入對(duì)象實(shí)例對(duì)象的屬性指向其構(gòu)造函數(shù),這樣看起來(lái)實(shí)例對(duì)象好像繼承了對(duì)象一樣。實(shí)例對(duì)象的原型指向其構(gòu)造函數(shù)的對(duì)象構(gòu)造器的指向。 前言 為什么說(shuō)是再談呢,網(wǎng)上講解這個(gè)的博客的很多,我開(kāi)始學(xué)習(xí)也是看過(guò),敲過(guò)就沒(méi)了,自以為理解了就結(jié)束了,書(shū)到用時(shí)方恨少啊。實(shí)際開(kāi)發(fā)中一用就打磕巴,于是在重新學(xué)習(xí)了之后分享出來(lái)...

    svtter 評(píng)論0 收藏0
  • JS對(duì)象(1)重新認(rèn)識(shí)面向?qū)ο?/b>

    摘要:對(duì)象重新認(rèn)識(shí)面向?qū)ο竺嫦驅(qū)ο髲脑O(shè)計(jì)模式上看,對(duì)象是計(jì)算機(jī)抽象現(xiàn)實(shí)世界的一種方式。除了字面式聲明方式之外,允許通過(guò)構(gòu)造器創(chuàng)建對(duì)象。每個(gè)構(gòu)造器實(shí)際上是一個(gè)函數(shù)對(duì)象該函數(shù)對(duì)象含有一個(gè)屬性用于實(shí)現(xiàn)基于原型的繼承和共享屬性。 title: JS對(duì)象(1)重新認(rèn)識(shí)面向?qū)ο? date: 2016-10-05 tags: JavaScript 0x00 面向?qū)ο?從設(shè)計(jì)模式上看,對(duì)象是...

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

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

0條評(píng)論

閱讀需要支付1元查看
<