摘要:如下代碼示例刪除刪除方法每個(gè)對(duì)象中都會(huì)具有一個(gè)方法,該方法用來(lái)判斷一個(gè)對(duì)象是否是一個(gè)對(duì)象的原型屬性上述代碼說(shuō)明對(duì)象存在一個(gè)指向構(gòu)造函數(shù)的原型,這個(gè)鏈接被叫做屬性需要注意的是屬性與屬性并不等價(jià)。
原型
在JavaScript中,函數(shù)是一個(gè)包含屬性和方法的Function類型的對(duì)象。而原型(Prototype)就是Function類型對(duì)象的一個(gè)屬性
在函數(shù)定義時(shí)就包含prototype屬性,它的初始值是一個(gè)空對(duì)象。在JavaScript中并沒(méi)有定義函數(shù)的原型類型,所以原型可以是任何類型
原型是用于保存對(duì)象的共享屬性和方法的,原型的屬性和方法并不會(huì)影響函數(shù)本身的屬性和方法
function foo(a,b){ return a+b; } console.log(typeof foo.prototype);//object獲取原型
通過(guò)如下兩種方式可以獲取對(duì)象的原型,從而設(shè)置共享的屬性和方法:
通過(guò)構(gòu)造函數(shù)的prototype屬性
function Person(){ console.log("Person instantiated"); } console.log(Person.prototype);
通過(guò)Object對(duì)象的getPrototypeOf(obj)方法
function Person(){ console.log("Person instantiated"); } console.log(Object.getPrototypeOf(Person));原型的屬性和方法
通過(guò)如下兩種方式可以設(shè)置原型的屬性和方法:
原型的屬性和方法多帶帶進(jìn)行定義
構(gòu)造函數(shù).prototype.屬性名=屬性值;
構(gòu)造函數(shù).prototype.方法名=function(){}
直接為原型定義一個(gè)新對(duì)象
構(gòu)造函數(shù).prototype={
屬性名:屬性值, 方法名:function(){}
}
自有屬性與原型屬性自有屬性:通過(guò)對(duì)象的引用添加的屬性。其它對(duì)象可能無(wú)此屬性;即使有,也是彼此獨(dú)立的屬性
原型屬性:從原型對(duì)象中繼承來(lái)的屬性,一旦原型對(duì)象中屬性值改變,所有繼承自該原型的對(duì)象屬性均改變
function Emp(ename,salary){ this.ename=ename; this.salary=salary; } Emp.prototype={city:"北京市",dept:"研發(fā)部"} var emp1=new Emp("Mary",3800); var emp2=new Emp("Tom",3000);檢測(cè)自有或原型屬性
使用hasOwnPrototype()方法檢測(cè)對(duì)象是否具有指定的自有屬性:
function Hero(){} var hero=new Hero(); console.log(hero.hasOwnPrototype("name"));
使用in關(guān)鍵字檢測(cè)對(duì)象及其原型鏈中是否具有指定屬性:
function Hero(){} var hero=new Hero(); console.log("name" in hero);擴(kuò)展屬性或方法
通過(guò)原型可以為指定構(gòu)造函數(shù)或?qū)ο髷U(kuò)展其屬性或方法,如下代碼示例:
function Hero(){} Hero.prototype={ name:"Mary", salary:3800 } var hero=new Hero(); console.log(hero.name);//Mary重寫原型屬性
通過(guò)構(gòu)造函數(shù)或?qū)ο蟮淖杂袑傩钥梢灾貙懺偷膶傩裕缦麓a示例:
function Hero(){} Hero.prototype={ name:"Mary", salary:3800 } var hero=new Hero(); hero.name="Tom"; console.log(hero.name);//Tom刪除屬性
通過(guò)delete關(guān)鍵字可以刪除對(duì)象的屬性,如果該對(duì)象既具有原型屬性又具有自有屬性的話,先刪除自有屬性,再刪除原型屬性。如下代碼示例:
function Hero(){} Hero.prototype={name:"Mary",salary:3800} var hero=new Hero(); hero.name="Tom"; delete hero.name;//刪除 Tom console.log(hero.name);//Mary delete hero.name;//刪除 Mary console.log(hero.name);//undefinedisPrototypeOf()方法
每個(gè)對(duì)象中都會(huì)具有一個(gè)isPrototypeOf()方法,該方法用來(lái)判斷一個(gè)對(duì)象是否是一個(gè)對(duì)象的原型
var monkey={} function Human(){} Human.prototype=monkey; var man=new Human(); monkey.isPrototypeOf(man);//true__Proto__屬性
function Hero(){} Hero.prototype={ name:"Mary", salary:3800 } var hero=new Hero(); console.log(hero.name);//Mary
上述代碼說(shuō)明hero對(duì)象存在一個(gè)指向構(gòu)造函數(shù)Hero的原型,這個(gè)鏈接被叫做__proto__屬性
需要注意的是:__proto__屬性與prototype屬性并不等價(jià)。__proto__屬性只能在調(diào)試時(shí)使用
__proto__屬性是指定對(duì)象的屬性
prototype屬性是指定構(gòu)造函數(shù)的屬性
擴(kuò)展內(nèi)建對(duì)象JavaScript中的內(nèi)置對(duì)象有些也具有prototype屬性,利用內(nèi)置對(duì)象的prototype屬性可以為內(nèi)置對(duì)象擴(kuò)展屬性或方法
通過(guò)原型擴(kuò)展內(nèi)置對(duì)象的屬性和方法非常靈活,根據(jù)個(gè)性化要求制定JavaScript語(yǔ)言的具體內(nèi)容。一般建議慎用這種方式,如果JavaScript的版本更新時(shí)可能會(huì)提供個(gè)性化的屬性或方法,導(dǎo)致沖突。
Array.prototype.inArray=function(color){ for(var i=0,len=this.length;i繼承 原型鏈 構(gòu)造函數(shù)或構(gòu)造器具有prototype屬性,對(duì)象具有__proto__屬性,這就是之前學(xué)習(xí)的原型
原型鏈實(shí)現(xiàn)繼承
如果構(gòu)造函數(shù)或?qū)ο驛,A的原型指向構(gòu)造函數(shù)或?qū)ο驜,B的原型再指向構(gòu)造函數(shù)或?qū)ο驝,以此類推,最終的構(gòu)造函數(shù)或?qū)ο蟮脑椭赶騉bject的原型。由此形成一條鏈狀結(jié)構(gòu),被稱之為原型鏈。
按照上述的描述,在B中定義的屬性或方法,可以直接在A中使用并不需要定義。這就是繼承,它允許每個(gè)對(duì)象來(lái)訪問(wèn)其原型鏈上的任何屬性或方法
原型鏈?zhǔn)荅CMAScript標(biāo)準(zhǔn)中指定的默認(rèn)實(shí)現(xiàn)繼承的方式。function A(){ this.name="a"; this.toString=function(){return this.name}; } function B(){ this.name="b"; } function C(){ this.name="c"; this.age=18; this.getAge=function(){return this.age}; } B.prototype=new A(); C.prototype=new B();只繼承于原型出于對(duì)效率的考慮,盡可能地將屬性和方法添加到原型上??梢圆扇∫韵路绞剑?/p>
不要為繼承關(guān)系多帶帶創(chuàng)建新對(duì)象
盡量減少運(yùn)行時(shí)的方法搜索
只繼承于原型根據(jù)上述方式進(jìn)行更改后,代碼如下:
function A(){} A.prototype.name="a"; A.prototype.toString=function(){return this.name} function B(){} B.prototype=A.prototype; B.prototype.name="b"; function C(){} C.prototype=B.prototype; C.prototype.name="c"; C.prototype.age=18; C.prototype.getAge=function(){return this.age};原型鏈雖然很強(qiáng)大,用它可以實(shí)現(xiàn)JavaScript中的繼承,但同時(shí)也存在著一些問(wèn)題。
原型鏈實(shí)際上是在多個(gè)構(gòu)造函數(shù)或?qū)ο笾g共享屬性和方法
創(chuàng)建子類的對(duì)象時(shí),不能像父級(jí)的構(gòu)造函數(shù)傳遞任何參數(shù)
綜上所述,在實(shí)際開發(fā)中很少會(huì)多帶帶使用原型鏈
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/108266.html
摘要:首先,需要來(lái)理清一些基礎(chǔ)的計(jì)算機(jī)編程概念編程哲學(xué)與設(shè)計(jì)模式計(jì)算機(jī)編程理念源自于對(duì)現(xiàn)實(shí)抽象的哲學(xué)思考,面向?qū)ο缶幊淌瞧湟环N思維方式,與它并駕齊驅(qū)的是另外兩種思路過(guò)程式和函數(shù)式編程。 JavaScript 中的原型機(jī)制一直以來(lái)都被眾多開發(fā)者(包括本人)低估甚至忽視了,這是因?yàn)榻^大多數(shù)人沒(méi)有想要深刻理解這個(gè)機(jī)制的內(nèi)涵,以及越來(lái)越多的開發(fā)者缺乏計(jì)算機(jī)編程相關(guān)的基礎(chǔ)知識(shí)。對(duì)于這樣的開發(fā)者來(lái)說(shuō) J...
摘要:在節(jié)中,我們學(xué)習(xí)到了通過(guò)構(gòu)造函數(shù)創(chuàng)建對(duì)象的三個(gè)重要步驟,其中的一步是把構(gòu)造函數(shù)的對(duì)象設(shè)置為創(chuàng)建對(duì)象的原型。利用而不是直接用創(chuàng)建一個(gè)實(shí)例對(duì)象的目的是,減少一次調(diào)用父構(gòu)造函數(shù)的執(zhí)行。 JavaScript語(yǔ)言不像面向?qū)ο蟮木幊陶Z(yǔ)言中有類的概念,所以也就沒(méi)有類之間直接的繼承,JavaScript中只有對(duì)象,使用函數(shù)模擬類,基于對(duì)象之間的原型鏈來(lái)實(shí)現(xiàn)繼承關(guān)系,ES6的語(yǔ)法中新增了class關(guān)鍵...
摘要:這正是我們想要的太棒了毫不意外的,這種繼承的方式被稱為構(gòu)造函數(shù)繼承,在中是一種關(guān)鍵的實(shí)現(xiàn)的繼承方法,相信你已經(jīng)很好的掌握了。 你應(yīng)該知道,JavaScript是一門基于原型鏈的語(yǔ)言,而我們今天的主題 -- 繼承就和原型鏈這一概念息息相關(guān)。甚至可以說(shuō),所謂的原型鏈就是一條繼承鏈。有些困惑了嗎?接著看下去吧。 一、構(gòu)造函數(shù),原型屬性與實(shí)例對(duì)象 要搞清楚如何在JavaScript中實(shí)現(xiàn)繼承,...
摘要:前言作為中最重要的內(nèi)容之一,繼承問(wèn)題一直是我們關(guān)注的重點(diǎn)。如果一個(gè)類別繼承自另一個(gè)類別,就把這個(gè)稱為的子類,而把稱為的父類別也可以稱是的超類。 前言 作為 JavaScript 中最重要的內(nèi)容之一,繼承問(wèn)題一直是我們關(guān)注的重點(diǎn)。那么你是否清晰地知道它的原理以及各種實(shí)現(xiàn)方式呢 閱讀這篇文章,你將知道: 什么是繼承 實(shí)現(xiàn)繼承有哪幾種方式 它們各有什么特點(diǎn) 這里默認(rèn)你已經(jīng)清楚的知道構(gòu)造函...
摘要:綜上所述有原型鏈繼承,構(gòu)造函數(shù)繼承經(jīng)典繼承,組合繼承,寄生繼承,寄生組合繼承五種方法,寄生組合式繼承,集寄生式繼承和組合繼承的優(yōu)點(diǎn)于一身是實(shí)現(xiàn)基于類型繼承的最有效方法。 一、前言 繼承是面向?qū)ο螅∣OP)語(yǔ)言中的一個(gè)最為人津津樂(lè)道的概念。許多面對(duì)對(duì)象(OOP)語(yǔ)言都支持兩種繼承方式::接口繼承 和 實(shí)現(xiàn)繼承 。 接口繼承只繼承方法簽名,而實(shí)現(xiàn)繼承則繼承實(shí)際的方法。由于js中方法沒(méi)有簽名...
摘要:原型對(duì)象是由創(chuàng)建的,因此原型對(duì)象的構(gòu)造函數(shù)是構(gòu)造函數(shù)也可以是稱為對(duì)象,原型對(duì)象也就繼承了其生父構(gòu)造函數(shù)中的數(shù)據(jù),也同時(shí)繼承了原型對(duì)象的數(shù)據(jù)。當(dāng)然這條原型鏈中的數(shù)據(jù),會(huì)被還是還是這類構(gòu)造函數(shù)繼承,但是不會(huì)被這些繼承,他們不處于同一個(gè)鏈條上。 js中,F(xiàn)unction的本質(zhì)是什么?Object的本質(zhì)又是什么?js中有幾條原型鏈? showImg(https://segmentfault.c...
閱讀 782·2021-11-16 11:44
閱讀 3635·2019-08-26 12:13
閱讀 3288·2019-08-26 10:46
閱讀 2414·2019-08-23 12:37
閱讀 1254·2019-08-22 18:30
閱讀 2595·2019-08-22 17:30
閱讀 1901·2019-08-22 17:26
閱讀 2351·2019-08-22 16:20