摘要:如下代碼示例刪除刪除方法每個對象中都會具有一個方法,該方法用來判斷一個對象是否是一個對象的原型屬性上述代碼說明對象存在一個指向構造函數的原型,這個鏈接被叫做屬性需要注意的是屬性與屬性并不等價。
原型
在JavaScript中,函數是一個包含屬性和方法的Function類型的對象。而原型(Prototype)就是Function類型對象的一個屬性
在函數定義時就包含prototype屬性,它的初始值是一個空對象。在JavaScript中并沒有定義函數的原型類型,所以原型可以是任何類型
原型是用于保存對象的共享屬性和方法的,原型的屬性和方法并不會影響函數本身的屬性和方法
function foo(a,b){ return a+b; } console.log(typeof foo.prototype);//object獲取原型
通過如下兩種方式可以獲取對象的原型,從而設置共享的屬性和方法:
通過構造函數的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));原型的屬性和方法
通過如下兩種方式可以設置原型的屬性和方法:
原型的屬性和方法多帶帶進行定義
構造函數.prototype.屬性名=屬性值;
構造函數.prototype.方法名=function(){}
直接為原型定義一個新對象
構造函數.prototype={
屬性名:屬性值, 方法名:function(){}
}
自有屬性與原型屬性自有屬性:通過對象的引用添加的屬性。其它對象可能無此屬性;即使有,也是彼此獨立的屬性
原型屬性:從原型對象中繼承來的屬性,一旦原型對象中屬性值改變,所有繼承自該原型的對象屬性均改變
function Emp(ename,salary){ this.ename=ename; this.salary=salary; } Emp.prototype={city:"北京市",dept:"研發部"} 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);擴展屬性或方法
通過原型可以為指定構造函數或對象擴展其屬性或方法,如下代碼示例:
function Hero(){} Hero.prototype={ name:"Mary", salary:3800 } var hero=new Hero(); console.log(hero.name);//Mary重寫原型屬性
通過構造函數或對象的自有屬性可以重寫原型的屬性,如下代碼示例:
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對象存在一個指向構造函數Hero的原型,這個鏈接被叫做__proto__屬性
需要注意的是:__proto__屬性與prototype屬性并不等價。__proto__屬性只能在調試時使用
__proto__屬性是指定對象的屬性
prototype屬性是指定構造函數的屬性
擴展內建對象JavaScript中的內置對象有些也具有prototype屬性,利用內置對象的prototype屬性可以為內置對象擴展屬性或方法
通過原型擴展內置對象的屬性和方法非常靈活,根據個性化要求制定JavaScript語言的具體內容。一般建議慎用這種方式,如果JavaScript的版本更新時可能會提供個性化的屬性或方法,導致沖突。
Array.prototype.inArray=function(color){ for(var i=0,len=this.length;i繼承 原型鏈 構造函數或構造器具有prototype屬性,對象具有__proto__屬性,這就是之前學習的原型
原型鏈實現繼承
如果構造函數或對象A,A的原型指向構造函數或對象B,B的原型再指向構造函數或對象C,以此類推,最終的構造函數或對象的原型指向Object的原型。由此形成一條鏈狀結構,被稱之為原型鏈。
按照上述的描述,在B中定義的屬性或方法,可以直接在A中使用并不需要定義。這就是繼承,它允許每個對象來訪問其原型鏈上的任何屬性或方法
原型鏈是ECMAScript標準中指定的默認實現繼承的方式。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();只繼承于原型出于對效率的考慮,盡可能地將屬性和方法添加到原型上。可以采取以下方式:
不要為繼承關系多帶帶創建新對象
盡量減少運行時的方法搜索
只繼承于原型根據上述方式進行更改后,代碼如下:
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};原型鏈雖然很強大,用它可以實現JavaScript中的繼承,但同時也存在著一些問題。
原型鏈實際上是在多個構造函數或對象之間共享屬性和方法
創建子類的對象時,不能像父級的構造函數傳遞任何參數
綜上所述,在實際開發中很少會多帶帶使用原型鏈
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108266.html
摘要:首先,需要來理清一些基礎的計算機編程概念編程哲學與設計模式計算機編程理念源自于對現實抽象的哲學思考,面向對象編程是其一種思維方式,與它并駕齊驅的是另外兩種思路過程式和函數式編程。 JavaScript 中的原型機制一直以來都被眾多開發者(包括本人)低估甚至忽視了,這是因為絕大多數人沒有想要深刻理解這個機制的內涵,以及越來越多的開發者缺乏計算機編程相關的基礎知識。對于這樣的開發者來說 J...
摘要:在節中,我們學習到了通過構造函數創建對象的三個重要步驟,其中的一步是把構造函數的對象設置為創建對象的原型。利用而不是直接用創建一個實例對象的目的是,減少一次調用父構造函數的執行。 JavaScript語言不像面向對象的編程語言中有類的概念,所以也就沒有類之間直接的繼承,JavaScript中只有對象,使用函數模擬類,基于對象之間的原型鏈來實現繼承關系,ES6的語法中新增了class關鍵...
摘要:這正是我們想要的太棒了毫不意外的,這種繼承的方式被稱為構造函數繼承,在中是一種關鍵的實現的繼承方法,相信你已經很好的掌握了。 你應該知道,JavaScript是一門基于原型鏈的語言,而我們今天的主題 -- 繼承就和原型鏈這一概念息息相關。甚至可以說,所謂的原型鏈就是一條繼承鏈。有些困惑了嗎?接著看下去吧。 一、構造函數,原型屬性與實例對象 要搞清楚如何在JavaScript中實現繼承,...
摘要:前言作為中最重要的內容之一,繼承問題一直是我們關注的重點。如果一個類別繼承自另一個類別,就把這個稱為的子類,而把稱為的父類別也可以稱是的超類。 前言 作為 JavaScript 中最重要的內容之一,繼承問題一直是我們關注的重點。那么你是否清晰地知道它的原理以及各種實現方式呢 閱讀這篇文章,你將知道: 什么是繼承 實現繼承有哪幾種方式 它們各有什么特點 這里默認你已經清楚的知道構造函...
摘要:綜上所述有原型鏈繼承,構造函數繼承經典繼承,組合繼承,寄生繼承,寄生組合繼承五種方法,寄生組合式繼承,集寄生式繼承和組合繼承的優點于一身是實現基于類型繼承的最有效方法。 一、前言 繼承是面向對象(OOP)語言中的一個最為人津津樂道的概念。許多面對對象(OOP)語言都支持兩種繼承方式::接口繼承 和 實現繼承 。 接口繼承只繼承方法簽名,而實現繼承則繼承實際的方法。由于js中方法沒有簽名...
摘要:原型對象是由創建的,因此原型對象的構造函數是構造函數也可以是稱為對象,原型對象也就繼承了其生父構造函數中的數據,也同時繼承了原型對象的數據。當然這條原型鏈中的數據,會被還是還是這類構造函數繼承,但是不會被這些繼承,他們不處于同一個鏈條上。 js中,Function的本質是什么?Object的本質又是什么?js中有幾條原型鏈? showImg(https://segmentfault.c...
閱讀 711·2021-11-16 11:44
閱讀 3541·2019-08-26 12:13
閱讀 3236·2019-08-26 10:46
閱讀 2352·2019-08-23 12:37
閱讀 1180·2019-08-22 18:30
閱讀 2526·2019-08-22 17:30
閱讀 1835·2019-08-22 17:26
閱讀 2284·2019-08-22 16:20