如下概念請花費必定的時間完全理解,才能進行下一步,思考題必定要思考,這樣才能完全掌握原型鏈的知識點,教程中若是有任何的錯誤不足請指正!編程
由function創造出來的函數,好比:數組
function a(){}; var b=function(){};
系統內置的函數對象ide
Function,Object,Array,String,Number
只有函數對象纔有 prototype屬性 ,重要的事情說三遍!函數
思考: js的引用數據類型都屬於函數對象嗎?prototype
除開函數對象以外的對象都是普通對象設計
var b='qwe'; // b 是字符串類型,屬於普通對象 var c=123;; // c 是數字類型,屬於普通對象
思考:js有五種基本類型:Undefined,Null,Boolean,Number和String,他們都是屬於普通對象嗎?指針
prototype屬性也叫原型對象,主要是爲了實現繼承和共享屬性;code
能夠說咱們的每一次編程,內在都有原型對象來發揮着做用,若是你沒有掌握原型對象的含義,那麼你的js尚未真正的入門!對象
function a(){};
首先對象 a 是由Function創造出來,是函數對象;那麼根據咱們以上的教程,a 就有了prototype屬性,那麼這個原型對象是怎麼創造出來的呢?
來看下面這個例子:繼承
var temp = new a(); a.prototype=new Object(); a.prototype = temp;
那麼a的prototype屬性就是這樣創造出來的;
思考:原型對象prototype 屬於函數對象嗎?
JavaScript中,萬物皆對象!全部的對象obj都具備proto屬性(null和undefined除外),可稱爲隱式原型,一個對象的隱式原型指向構造該對象的構造函數的原型
請看如下例子幫助理解:
function a(){}; var obj=new a(); console.log(a.__proto__===Function.prototype); //true console.log(a.prototype.__proto__===Object.prototype); //true console.log(obj.__proto__===a.prototype); //true
思考一下,var obj={}; obj.prototype.proto指向誰?
假設 obj 是由函數對象 a 由new運算創造出來的,那麼obj的constructor 的屬性就存放着一個對 a 的引用,經過這個構造函數,咱們還能夠爲 a添加其餘屬性和方法,
這個屬性的最初設計是爲了檢測對象的數據類型,不事後來人們經過此屬性的特性作了更多的事情
請看如下例子:
function a(){}; var obj=new a(); obj.constructor.b=`我是a的新的屬性`; console.log(a.b); //我是a的新的屬性 console.log(a.constructor===Function); //true console.log(a.prototype.constructor===a); //true console.log(obj.constructor===a); //true
函數a是由Function創造出來,那麼它的constructor指向的Function,obj是由new a()方式創造出來,那麼obj.constructor理應指向a
思考:a.prototype.proto.constructor指向誰?
思考: js的引用數據類型都屬於函數對象嗎?
引用類型值:指的是那些保存在堆內存中的對象,意思是,變量中保存的實際上只是一個指針,這個指針執行內存中的另外一個位置,由該位置保存對象
那麼數組,普通對象,函數對象都算是引用數據類型,引用數據類型範圍包含函數對象的範圍
思考:js有五種基本類型:Undefined,Null,Boolean,Number和String,他們都是屬於普通對象嗎?
基本類型值:指的是保存在棧內存中的簡單數據段;除開函數對象以外的對象都是普通對象,那麼普通對象範圍是包含基本數據類型的
事實上(函數對象,普通對象)以及(基本數據類型,引用數據類型)是在不一樣角度對js變量進行的定義
思考:原型對象prototype 屬於函數對象嗎?
事實上 這個問題要進行分別回答:
Function.prototype 屬於函數對象,其餘對象的prototype屬於普通對象
function a(){}; console.log(typeof Function.prototype); // function console.log(typeof a.prototype); //object
前面說過prototype的創造過程
var temp = new a(); a.prototype = temp;
這裏temp固然就是普通對象啦,可是看下Function的prototype創造過程
var a = new Function(); Function.prototype = a;
看明白了把,Function的prototype爲何是函數對象了吧?回憶一下函數對象的定義吧!
思考一下,var obj={}; obj.prototype.proto指向誰?
這裏分步思考:
1, obj只是一個普通對象
2, 什麼類型的對象是有prototype屬性的?固然是函數對象
3, 因此obj是沒有prototype屬性的
4, 因此obj.prototype===undefined
5, 因此此題的最終問題是:undefined.proto指向什麼
6, 全部的對象obj都具備proto屬性(null和undefined除外)!因此答案是 js報錯(有沒有一種被我坑了的感受)
思考:a.prototype.proto.constructor指向誰?
function a(){};
這裏繼續分解題目:
1, a.prototype指向a的一個實例,咱們已經屢次強調了,並且屬於普通對象
2, proto定義爲:指向創造obj對象的函數對象的prototype屬性,因此看下誰創造了a.prototype,由於a.prototype是普通對象,類型爲object,那麼是Object創造了它,
3, 那麼顯而易見a.prototype.proto指向了Object.prototype
4, 那麼題目簡化爲Object.prototype.constructor指向誰
5, 繼續分解題目,Object.prototype爲基本對象,那麼就是Object創造了它,那麼它的constructor就指向了Object
Object.prototype.constructor===Object //true
不知道你暈不暈,我有點暈,這產生了蛋生雞仍是雞生蛋的問題啦~
放心,仍是有盡頭的 :
Object.prototype.__proto__===null //true
這個例子告訴咱們是 是null創造了一切「「這不就是易經中的:道生一,一輩子二,二生三,三生萬物!