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

資訊專欄INFORMATION COLUMN

理清javascript中的面向?qū)ο螅ㄒ唬屠^承

beita / 690人閱讀

摘要:有一函數(shù)若是用來(lái)生成對(duì)象,則稱為構(gòu)造函數(shù)名。屬性指定了使用該構(gòu)造函數(shù)生成的對(duì)象實(shí)例繼承了哪個(gè)對(duì)象實(shí)例。因此,只要利用,就能在構(gòu)造函數(shù)中,為未來(lái)利用此構(gòu)造函數(shù)生成的對(duì)象實(shí)例,添加成員屬性和成員方法了。

與其它編程語(yǔ)言不一樣的是,javascript的面向?qū)ο蟛⒎且蕾囉诔橄蟮?strong>類,而是通過原型鏈,將一個(gè)個(gè)具體的對(duì)象實(shí)例進(jìn)行連接,位于原型鏈下游的對(duì)象實(shí)例可以讀取/使用位于上游的對(duì)象實(shí)例的屬性/方法。
下文由簡(jiǎn)及深,試圖一步步理清javascript面向?qū)ο蟮谋举|(zhì)。

萬(wàn)物之源:javascript的原生類型——Object

javascript定義了最基礎(chǔ)的對(duì)象類型Object,并且為這一對(duì)象類型定義了許多成員方法。其它許多原生對(duì)象類型,實(shí)際上都是繼承自Object,比如說(shuō)Function、Date等。想要生成一個(gè)Object對(duì)象類型的對(duì)象實(shí)例也不是一件什么難事:

var obj = {a: 2333};
//又或者是利用Object()這一構(gòu)造函數(shù)
var obj = new Object();

實(shí)際上,更符合面向?qū)ο笏枷氲膽?yīng)該是利用構(gòu)造函數(shù)來(lái)生成對(duì)象實(shí)例。

生成對(duì)象實(shí)例的運(yùn)算符new,以及構(gòu)造函數(shù)constructor 如何使用new這一運(yùn)算符來(lái)生成對(duì)象實(shí)例

在其它編程語(yǔ)言中,new往往也是用來(lái)生成對(duì)象實(shí)例的,用法一般是這樣:new ClassName[([arguments])],而生成出來(lái)的對(duì)象實(shí)例也被冠以“ClassName對(duì)象”這樣的稱謂;而javascript則大不相同,由于原生沒有這一概念,因此構(gòu)造函數(shù)便取而代之:new constructor[([arguments])],而稱謂也改為“constructor對(duì)象”或"constructor類型的對(duì)象",構(gòu)造函數(shù)名直接就等同于數(shù)據(jù)類型了。

function A() {}    //有一函數(shù)(若是用來(lái)生成對(duì)象,則稱為構(gòu)造函數(shù))名A。
var obj = new A();    //使用構(gòu)造函數(shù)A來(lái)生成實(shí)例對(duì)象obj
console.dir(obj);    //打印實(shí)例對(duì)象obj

從上圖可知,利用構(gòu)造函數(shù)A生成的實(shí)例對(duì)象obj的數(shù)據(jù)類型為A,另外,我們留意到obj有且只有一個(gè)__proto__屬性,這是什么呢?先別急,下面就說(shuō)到。

詳述構(gòu)造函數(shù)constructor

從上文可知,要想生成對(duì)象實(shí)例,必須使用構(gòu)造函數(shù)(constructor),即便是var arr = [];var obj = {}這樣的形式,javascript也會(huì)在內(nèi)部調(diào)用Function()Object()這樣預(yù)設(shè)的構(gòu)造函數(shù)(由于是預(yù)設(shè)的構(gòu)造函數(shù)/數(shù)據(jù)類型,因此不需顯式指定)。

繼續(xù)沿用上述例子,這次我們把構(gòu)造函數(shù)A打印出來(lái)看看長(zhǎng)什么樣兒:

function A() {}   
var obj = new A(); 
console.dir(A); 

實(shí)際上,構(gòu)造函數(shù)跟普通的函數(shù)并無(wú)二致,只是因?yàn)橛猛荆ㄓ脕?lái)生成對(duì)象實(shí)例),因此才冠以“構(gòu)造函數(shù)”的大名。從上圖看,我們略過一些與面向?qū)ο鬅o(wú)關(guān)的屬性(arguments/caller/length/name),以及其函數(shù)作用域(),剩下的就是與面向?qū)ο笙⑾⑾嚓P(guān)的倆屬性了:prototype__proto__。這__proto__分外眼熟,赫然也出現(xiàn)在對(duì)象實(shí)例obj里,不過這里還是先跳過,我們先說(shuō)這prototype屬性。

構(gòu)造函數(shù)中的prototype屬性

特別注明是“構(gòu)造函數(shù)中的prototype屬性”,是因?yàn)?,?duì)于一般的函數(shù)來(lái)說(shuō),prototype屬性沒什么意義。prototype屬性指定了使用該構(gòu)造函數(shù)生成的對(duì)象實(shí)例繼承了哪個(gè)對(duì)象實(shí)例。
如上述的function A()prototype屬性指向了一個(gè)默認(rèn)的Object類型的對(duì)象實(shí)例(在javascript中,變量只是對(duì)象實(shí)例的一個(gè)引用,因此此處用“指向”比較準(zhǔn)確),那么,用function A()作為構(gòu)造函數(shù)實(shí)例化的obj實(shí)際上就是繼承了那默認(rèn)的Object類型的對(duì)象實(shí)例,雖然obj本身并沒有自定義的屬性/方法,但是能通過obj調(diào)用繼承回來(lái)的所有屬性/方法。

對(duì)象繼承的單向鏈條:原型鏈

既然構(gòu)造函數(shù)的prototype屬性能指定繼承的對(duì)象實(shí)例,那么只要我們修改這prototype屬性,使其指向其它對(duì)象實(shí)例,那么就可以達(dá)到實(shí)現(xiàn)繼承任意對(duì)象的效果了,看下面代碼:

var car = {    //一個(gè)普通的Object類型實(shí)例對(duì)象
    status: "stop"
}
function audi() {}    //構(gòu)造函數(shù)audi
audi.prototype = car;    //修改構(gòu)造函數(shù)audi的prototype屬性,使其指向car
console.dir(audi);
var audiQ3 = new audi();    //利用構(gòu)造函數(shù)audi生成的數(shù)據(jù)類型為audi的實(shí)例對(duì)象
console.dir(audiQ3);

先來(lái)看看構(gòu)造函數(shù)audi打印出來(lái)的結(jié)果:

從audi.prototype.status可以看出,此時(shí)的audi.prototype的確是指向{status: "stop"}這個(gè)對(duì)象實(shí)例了。
那么接下來(lái)看看利用修改后的構(gòu)造函數(shù)audi所生成的對(duì)象實(shí)例audiQ3:

我們可以發(fā)現(xiàn)audiQ3這一實(shí)例對(duì)象的數(shù)據(jù)類型是audi(與構(gòu)造函數(shù)同名),另外,audiQ3其下只有__proto__這唯一一個(gè)成員屬性,繼續(xù)查看__proto__,赫然發(fā)現(xiàn),里面竟然有status: "stop"。沒錯(cuò),__proto__屬性正是指向{status: "stop"}這個(gè)對(duì)象實(shí)例的一個(gè)引用。

原型鏈的接點(diǎn):__proto__

通過對(duì)象實(shí)例中的__proto__屬性,繼承的對(duì)象實(shí)例得以與被繼承的對(duì)象實(shí)例鏈接起來(lái),于是,一環(huán)扣一環(huán),形成了一條由對(duì)象實(shí)例、指向被繼承對(duì)象實(shí)例的引用所構(gòu)成的鏈條:原型鏈。

由于__proto__是由構(gòu)造函數(shù)的prototype屬性決定的(也可以說(shuō)是prototype直接賦值給__proto__),因此我們可以通過修改prototype屬性來(lái)操縱這條原型鏈

再談構(gòu)造函數(shù)

構(gòu)造函數(shù),主要用來(lái)在創(chuàng)建對(duì)象時(shí)初始化對(duì)象, 即為對(duì)象成員變量賦初始值,那么,javascript里的構(gòu)造函數(shù),是怎么實(shí)現(xiàn)這樣的功能的呢?以下面的DEMO作為示例說(shuō)明:

function car() {    //定義了一個(gè)名為car的構(gòu)造函數(shù)
    this.status = "stop";    //為日后使用car這一構(gòu)造函數(shù)來(lái)生成的對(duì)象實(shí)例添加個(gè)status成員變量,并賦初始值"stop"
    this.start = function() {    //為對(duì)象實(shí)例添加一個(gè)名為start的成員方法
        this.status = "running";
    }
}
var audiQ3 = new car();    //利用car生成一個(gè)對(duì)象實(shí)例,并將其賦給變量audiQ3
console.dir(audiQ3);
audiQ3.start();    //調(diào)用audiQ3的start方法
console.dir(audiQ3);

首先來(lái)看構(gòu)造函數(shù)car,我們看到this.status = "stop";,這this是指代car這一function嗎?不是的,這個(gè)this實(shí)際上是指向當(dāng)前函數(shù)執(zhí)行時(shí)的上下文環(huán)境,用在構(gòu)造函數(shù)時(shí),指的則是新生成的對(duì)象實(shí)例(在本DEMO中指的是audiQ3)。因此,只要利用this,就能在構(gòu)造函數(shù)中,為未來(lái)利用此構(gòu)造函數(shù)生成的對(duì)象實(shí)例,添加成員屬性和成員方法了。

javascript原生支持的原型繼承方式:Object.create

ECMAScript 5定義了一種原生的原型繼承方式:Object.create,我們可以通過這種方式更簡(jiǎn)便地實(shí)現(xiàn)原型繼承。

語(yǔ)法
Object.create(proto, [ propertiesObject ])
參數(shù)
proto 一個(gè)對(duì)象,作為新創(chuàng)建對(duì)象的原型。 
propertiesObject 可選。該參數(shù)對(duì)象是一組屬性與值,該對(duì)象的屬性名稱將是新創(chuàng)建的對(duì)象的屬性名稱,值是屬性描述符(這些屬性描述符的結(jié)構(gòu)與Object.defineProperties()的第二個(gè)參數(shù)一樣)。注意:該參數(shù)對(duì)象不能是undefined,另外只有該對(duì)象中自身?yè)碛械目擅杜e的屬性才有效,也就是說(shuō)該對(duì)象的原型鏈上屬性是無(wú)效的。
示例
var car = {
    status: "stop",
    start: function() {
        this.status = "running"
    }
}
var audiQ3 = Object.create(car);
console.dir(audiQ3);

怎么樣,利用Object.create這種方法是不是很簡(jiǎn)單就實(shí)現(xiàn)了原型繼承呢?實(shí)際上,這是ECMAScript 5給我們做了一下封裝,相當(dāng)于:

function (proto) {
  var constructor = function(){}
  constructor.prototype = proto;
  return new constructor();
}
瀏覽器兼容性修復(fù)

考慮到ECMAScript 5在IE上到IE10才完全支持,因此我們有必要對(duì)低版本的IE瀏覽器進(jìn)行兼容,實(shí)際上也很簡(jiǎn)單,對(duì)上面的代碼稍作修改即可:

if(typeof Object.create !== "function") {
    Object.create = function(proto) {
      var constructor = function(){}
      constructor.prototype = proto;
      return new constructor();
    }
}

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

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

相關(guān)文章

  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你的“對(duì)象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過類的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    李昌杰 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你的“對(duì)象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過類的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    Lyux 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.32 - 七夕將至,你的“對(duì)象”還好嗎?

    摘要:很多情況下,通常一個(gè)人類,即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類是相似對(duì)象的描述,稱為類的定義,是該類對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過對(duì)類的實(shí)體化形成的對(duì)象。一類的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過類的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...

    AaronYuan 評(píng)論0 收藏0
  • 初學(xué)者快速學(xué)會(huì)javascript原型,原型鏈,原型繼承

    摘要:學(xué)習(xí),總繞不開原型,原型鏈,繼承等等這些知識(shí)。對(duì)象那么好,怎么才能找一個(gè)呸,其實(shí)是創(chuàng)建創(chuàng)建對(duì)象的方法對(duì)象字面量工廠模式構(gòu)造函數(shù)模式原型模式等。原型鏈有什么用來(lái)談?wù)劺^承,繼承可以利用構(gòu)造函數(shù),使用屬性等來(lái)實(shí)現(xiàn)。 初學(xué)者學(xué)習(xí)javascript可能會(huì)感覺很困擾,但是你一旦真正了解了它,我相信你會(huì)愛上它。學(xué)習(xí)ECMAScript,總繞不開原型,原型鏈,繼承等等這些知識(shí)。今天把它們放在一塊兒,...

    hiYoHoo 評(píng)論0 收藏0
  • 理解JavaScript的核心知識(shí)點(diǎn):原型

    摘要:首先,需要來(lái)理清一些基礎(chǔ)的計(jì)算機(jī)編程概念編程哲學(xué)與設(shè)計(jì)模式計(jì)算機(jī)編程理念源自于對(duì)現(xiàn)實(shí)抽象的哲學(xué)思考,面向?qū)ο缶幊淌瞧湟环N思維方式,與它并駕齊驅(qū)的是另外兩種思路過程式和函數(shù)式編程。 JavaScript 中的原型機(jī)制一直以來(lái)都被眾多開發(fā)者(包括本人)低估甚至忽視了,這是因?yàn)榻^大多數(shù)人沒有想要深刻理解這個(gè)機(jī)制的內(nèi)涵,以及越來(lái)越多的開發(fā)者缺乏計(jì)算機(jī)編程相關(guān)的基礎(chǔ)知識(shí)。對(duì)于這樣的開發(fā)者來(lái)說(shuō) J...

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

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

0條評(píng)論

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