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