一直認爲原型鏈太過複雜,尤爲看過某圖後被繞暈了一整子,今天清理硬盤空間(渣電腦),偶然又看到這圖,勾起了點回憶,因而索性複習一下原型鏈相關的內容,表達能力欠缺邏輯混亂別見怪(爲了防止新人__(此處指我)__被在此繞暈,圖片就放在末尾了。)javascript
如下三點須要謹記前端
1.每一個對象都具備一個名爲__proto__的屬性;java
2.每一個構造函數(構造函數標準爲大寫開頭,如Function(),Object()等等JS中自帶的構造函數,以及本身建立的)都具備一個名爲prototype的方法(注意:既然是方法,那麼就是一個對象(JS中函數一樣是對象),因此prototype一樣帶有__proto__屬性);編程
3.每一個對象的__proto__屬性指向自身構造函數的prototype;segmentfault
思路擴展以下架構
1 function Fun(){ 2 } 3 // 我創造了一個函數Fn 4 // 這個函數由Function生成(Function做爲構造函數) 5 var fn=new Fun() 6 // 我建立了一個函數fn 7 // 這個函數由Fn生成(Fn做爲構造函數) 8 9 10 console.log(fn.__proto__===Fun.prototype) //true 11 // fn的__proto__指向其構造函數Fun的prototype 12 console.log(Fun.__proto__===Function.prototype) //true 13 // Fun的__proto__指向其構造函數Function的prototype 14 console.log(Function.__proto__===Function.prototype) //true 15 // Function的__proto__指向其構造函數Function的prototype 16 // 構造函數自身是一個函數,他是被自身構造的 17 console.log(Function.prototype.__proto__===Object.prototype) //true 18 // Function.prototype的__proto__指向其構造函數Object的prototype 19 // Function.prototype是一個對象,一樣是一個方法,方法是函數,因此它必須有本身的構造函數也就是Object 20 console.log(Fun.prototype.__proto__===Object.prototype) //true 21 // 與上條相同 22 // 此處能夠知道一點,全部構造函數的的prototype方法的__都指向__Object.prototype(除了....Object.prototype自身) 23 console.log(Object.__proto__===Function.prototype) //true 24 // Object做爲一個構造函數(是一個函數對象!!函數對象!!),因此他的__proto__指向Function.prototype 25 console.log(Object.prototype.__proto__===null) //true 26 // Object.prototype做爲一切的源頭,他的__proto__是null 27 28 // 下面是一個新的,額外的例子 29 30 var obj={} 31 // 建立了一個obj 32 console.log(obj.__proto__===Object.prototype) //true 33 // obj做爲一個直接以字面量建立的對象,因此obj__proto__直接指向了Object.prototype,而不須要通過Function了!! 34 35 // 下面是根據原型鏈延伸的內容 36 // 還有一個上文並未提到的constructor, constructor在原型鏈中,是做爲對象prototypr的一個屬性存在的,它指向構造函數(因爲主要講原型鏈,這個就沒在乎、); 37 38 console.log(obj.__proto__.__proto__===null) //true 39 console.log(obj.__proto__.constructor===Object) //true 40 console.log(obj.__proto__.constructor.__proto__===Function.prototype) //true 41 console.log(obj.__proto__.constructor.__proto__.__proto__===Object.prototype) //true 42 console.log(obj.__proto__.constructor.__proto__.__proto__.__proto__===null) //true 43 console.log(obj.__proto__.constructor.__proto__.__proto__.constructor.__proto__===Function.prototype) //true 44 45 46 // 以上,有興趣的能夠一一驗證 F12搞起.
爲了方便記憶能夠得出以下結論(若有錯誤歡迎斧正.....)函數
prototype是構造函數獨有的屬性;this
對象的__prototype__屬性一般與其構造函數的prototype屬性相互對應;spa
全部構造函數的的prototype方法的__都指向__Object.prototype(除了....Object.prototype自身);prototype
須要注意的指向是
Function的__proto__指向其構造函數Function的prototype;
Object做爲一個構造函數(是一個函數對象!!函數對象!!),因此他的__proto__指向Function.prototype;
Function.prototype的__proto__指向其構造函數Object的prototype;
Object.prototype的__prototype__指向null(盡頭);
在文章結構順便附送上倆個與原型鏈相關的方法....歡迎使用
1.
hasOwnProperty判斷一個對象是否有名稱的屬性或對象,此方法沒法檢查該對象的原型鏈中是否具備該屬性,該屬性必須是對象自己的一個成員。
若是該屬性或者方法是該 對象自身定義的而不是器原型鏈中定義的 則返回true;不然返回false;
格式以下:
object.hasOwnProperty(proName);
括號內必需要加引號,而且直接寫入屬性名
2.isPrototypeOf是用來判斷指定對象object1是否存在於另外一個對象object2的原型鏈中,是則返回true,不然返回false。
格式以下:
object1.isPrototypeOf(object2);
object1是一個對象的實例;
object2是另外一個將要檢查其原型鏈的對象。
原型鏈能夠用來在同一個對象類型的不一樣實例之間共享功能。
若是 object2 的原型鏈中包含object1,那麼 isPrototypeOf 方法返回 true。
若是 object2 不是一個對象或者 object1 沒有出如今 object2 中的原型鏈中,isPrototypeOf 方法將返回 false。
某圖在這裏 ps:本文是總結,加我的理解.....圖是很久前留存在電腦的....忘了是在哪看到的...
字數664 閱讀10 評論0 喜歡1
因爲函數也是對象的一種,因此繼承了對象原型,能夠對其添加屬性和方法,構造函數也是函數,因此用自定義函數的方式,並將首字母大寫以明確是構造函數便可,能夠用new操做符建立函數實例驗證。
function Person(name) { this.name = name; this.sayName = function() { console.log(this.name); } }
構造函數
特性:讓全部對象實例共享原型對象所包含的屬性和方法:
function Person(name) { this.name = name; } Person.prototype.sayName = function() { console.log(this.name); } var p1 = new Person('zhao'), p2 = new Person('kevin'); p1.sayName(); p2.sayName();
prototype
<script> function People(name) { this.name = name; this.sayName = function() { console.log('my name is:' + this.name); } } People.prototype.walk = function() { console.log(this.name + 'is walking'); } var p1 = new People('飢人谷'); var p2 = new People('前端'); </script>
原型圖
function People() { var age = 1; this.age = 10; } People.age = 20; People.prototype.age = 30;
var age = 1
:age爲局部變量;this.age = 10
:函數調用時,age爲this指向對象的屬性;People.age = 20
:構造函數的age變爲20;People.prototype.age = 30
:原型添加age屬性;function Car(name, color, status) { this.name = name; this.color = color; this.status = status; } Car.prototype = { constructor : Car, run: function() { this.status = 'run'; }, stop: function() { this.status = 'stop'; }, getStatus: function() { console.log(this.status); } } var car1 = new Car('BMW', 'red', 'stop');
ps:
javascript是基於對象的,換一種說法是基於原型(鏈)的。
每個函數都有一個prototype(原型)屬性,這個屬性是一個對象,它的用途是包含能夠由特定類型的全部實例共享的屬性和方法。prototype是經過調用構造函數來建立的那個對象的原型(屬性)對象。
Javascript中對象的prototype屬性,能夠返回對象的 原型對象 的引用。
怎麼理解原型(鏈)?
圖1
函數(對象)有prototype屬性->對應了一個原型對象->每一個原型對象都有一個constructor屬性->包含一個指向prototype屬性所在函數的指針
每個實例都有一個內部屬性__proto__->指向原型對象
這裏提到的幾個屬性或對象: Person.prototype;//->原型對象 Person.prototype.constructor;//->指向構造函數 p.__proto__;//->指向原型對象