javascript __proto___ prototype和Function原始碼狂想

iteye_3829發表於2013-05-20

----我以為的Function----

1 function Function ( ) {
2      this.prototype = new this() ; /*這就導致了所有的函式的原型都是物件;如:alert(typeof(Array.prototype));輸出:object */
3      this.prototype.constructor = this ; // 由上一條推想可得
4      //... ...
5      //[native code]
6      //... ...
7  } 

所有的函式:

預定義: 
1 function Function () { [native code] }
2 function Object () { [native code] } // Global、Arguments、Math和JSON是Object構建的;
3 function Array () { [native code] }
4 function Date () { [native code] }
5 function String () { [native code] }
6 function Boolean () { [native code] }
7 function Number () { [native code] }
8 function RegExp () { [native code] }
自定義:
1 function Fn () { /*... ...*/ }

 

所謂的狂想

無論是預定義的(包括Function本身)還是自定義的函式都是由Function new出來的。我們知道,函式new出來的都是物件,那麼Function是函式,它new出來的東西(函式)自然也會是物件,所以函式也是物件。

Function new出來的物件是函式,叫“函式物件”(簡稱“函式”);這跟

Array new出來的物件叫“陣列物件”(簡稱“陣列”);

Object new出來的物件是“物件物件”(簡稱“物件”)是一樣的道理。

傳說的癲瘋

__proto__(血緣 或說DNA):

當用new操作符構造物件時,會在物件和建構函式之間建立__proto__鏈,該鏈應該是對外不可見的 (Firefox、chrome可以讓我們訪問到,但並不建議這樣做)。它的引用是恆定的:物件.__proto__ = 該物件建構函式.prototype;但它的值是可變的,這明顯取決於:該物件建構函式.prototype的值(廢話!)。

prototype:

所有的物件都有__proto__,但只有函式物件(預設)擁有prototype,非函式物件(預設)沒有也沒必要擁有prototype,這是prototype本身的職能所決定的:Javascript利用prototype實現擴充套件、共享和繼承。

__proto__鏈、prototype鏈圖:

關於null:注意沒有,指向null的箭頭有一半是黑色的,這個箭頭表示:Object.prototype.__proto__;

為什麼是null?

如果根據我猜想的Function構造Object函式,那麼:Object.prototype = new Object();

1 alert(Object.prototype)//輸出:[ obje Object ]

那麼應該是這樣的才對啊:Object.prototype.__proto__ = Object.prototype;

看出問題沒有?!如果是這樣的話物件檢索不存在的屬性在到達Object的時候就會掉入死迴圈:

1 Object.prototype.__proto__=Object.prototype;
2 var obj={};
3 alert(obj.say)

chrome javascript 控制檯 :

Uncaught Error: Cyclic __proto__ value 

 所以我認為:Object.prototype.__proto__ = null 是特定定義的:

1 alert(Object.prototype.__proto__);
2 //firfox 和 chrome 輸出:null
3 //IE9輸出:undefined

無論是null還是undefined目的都是一樣的,就是為了終止檢索。

後遺症:

利用Function.prototype或者Object.prototype可以將方法或屬性分享給所有的對像(不僅僅是“物件物件”哦)。原理,看圖!

注意:物件檢索自身屬性無果時會去訪問其__proto__而非其prototype(這有點像廢話),函式物件的prototype只有由它構建的物件在檢索自身屬性無果時才會去訪問:

1 Array.prototype.selfCheck = "Are you sure?";
2 alert(Array.selfCheck);// 輸出:undefined;  自定義的函式亦是如此

FunctionObject會有所不同:

Function.prototype.selfCheck = "Yes!"
alert(Function.selfCheck) ; // 輸出:"Yes!",原因如圖:Function  __proto__  Function
Object.prototype.selfCheck = "Yes!"
alert(Object.selfCheck);// 輸出:"Yes!",原因如圖:Object __proto__ Function,Function.prototype是Object

更有意思的:

1 Function.prototype.sayHello="Hi,F";
2 Object.prototype.sayHello="Hi,O";
3 alert(Object.sayHello);//輸出:Hi.F

追本溯源:(再說函式也是物件!)

把“函式物件”比作受驚L,那麼Function就像是LZ,Function內的“this.prototype = new this()”就像是LZ內的一根JZ啊,受驚L同時擁有LZ和JZ的DNA,“函式物件”就這樣同時具備了函式和物件的特性啊!!!

最後說一下constructor屬性:

1 //alert("constructor" in 任意物件)  都是ture;
2 //但 任意“物件物件”.hasOwnProperty("constructor")都是fale;

物件的檢索到的constructor屬性值都是從它們的建構函式那裡繼承來的,從猜想的Function裡面的this.property.constructor = this就可以看出。

相關文章