咱們本次的解釋,主要經過下圖java
粗看該圖,估計你不必定能看明白。不過接下來讓我逐行向你解釋。函數
- 最左側:意思是,有兩個對象f1和f2,他們是經過new Foo()出來的。
- 中間:Foo()就是最左側用到的Foo()
- 最右側:表示,函數Foo()的prototype屬性!
JS_Object和Function的區別javascript
咱們本次的解釋,主要經過下圖java
粗看該圖,估計你不必定能看明白。不過接下來讓我逐行向你解釋。函數
function Foo() { } var f1 = new Foo(); alert(f1.__proto__ == Foo.prototype);?function Object(){[native code]}//Javascript自帶,不是自定義的,能夠近似認爲是基類
function Function(){[native code]}//Javascript自帶,不是自定義的,能夠近似認爲是基類prototype
?code
這裏的這兩個function,分別走兩個方向,
Object做爲了衆多object(實例,new出來的)的基類型
Function做爲衆多function(主要是那些function出來的,就是定義出來的函數)的基類型htm
?對象
在開始下面更細緻的解釋先,咱們約定一些內容,Object表明這裏所說的Object,object表明實例對象
,Function表明這裏說的Function,function是關鍵字。對於Object與object的區別很好理解,一個是function,一個是new出來。blog
?ip
如今讓咱們思考兩個問題:
第一個,當咱們擴展Object原型時,new出來的Function,是否會被擴展?
第二個,當咱們擴展Function原型時,因爲Object也是個Function,那麼其實例object是否會被擴展get
?
先看第一個問題.eg.
?
Object.prototype.test4extend="123";//擴展Object的原型 document.write("Function:"+Function.test4extend);//在Function中出現了test4extend屬性 document.write("<br>") document.write("Object:"+Object.test4extend);//在Object中出現了test4extend屬性,此時Object仍是個Function document.write("<br>") var obj=new Object; document.write("Object instance:"+obj.test4extend);//在obj中擴展了test4extend,此時的obj是object document.write("<br>") function Foo() { } var foo = new Foo; document.write("foo object:"+foo.test4extend);//foo對象上擴展上了test4extend屬性 document.write("<br>") document.write("Foo Function:"+Foo.test4extend);//函數上也擴展上了test4extend屬性 document.write("<br>") console.log("Object", Object); console.log("Function", Function);?註釋已經寫得很清晰了,經過以上幾點咱們很容易發現如下幾點:
?
一、Object擴展了全部的object(obj,foo),與object擴展自Object是相符的。在這裏更加驗證了。接下來看看第二個問題
Function.prototype.test4extend="123";//擴展Function的原型 document.write("Function:"+Function.test4extend);//在Function中出現了test4extend屬性 document.write("<br>") document.write("Object:"+Object.test4extend);//在Object中出現了test4extend屬性,注意此時Object是個Function document.write("<br>") var obj=new Object; document.write("Object instance:"+obj.test4extend);//在obj中沒有擴展上test4extend,此時的obj是object document.write("<br>") function Foo() { } var foo = new Foo; document.write("foo object:"+foo.test4extend);//foo對象上沒有擴展上test4extend document.write("<br>") document.write("Foo Function:"+Foo.test4extend);//Function擴展上了test4extend屬性 document.write("<br>")
??
?這說明Function只管沒有被實例化得,被實例化的,他是沒有辦法管的。與Object不一樣,Object是不管是否實例化都管的。
接下來解釋這個圖:
先看最左側的__proto__虛線,表示Foo.__proto__至關於Function.prototype,這裏和Object狀況差很少,只是屬性一致而已,並非指真正的那個Function
中間的下部的__proto__虛線,表明Function.__proto__等於Function.prototype,這裏但是真的就是,和前面的至關於不一樣。
alert(Function.__proto__===Function.prototype);//true
?右側左上的__proto__虛線,表明Object.__proto__等於Function.prototype,這裏但是真的就是,和前面的至關於不一樣。
alert(Object.__proto__===Function.prototype);//true
?
?右側右上的__proto__虛線,表明Function.prototype.__proto__至關於Object.prototype,只是屬性一致而已,並非真的。
先讓咱們總結下__proto__和prototype的區別和關係。
區別:從實際效果上來講,能夠認爲__proto__是用來擴展Function的,擴展出來的函數,能夠直接調用,不須要new出對象才能用,同時對象是不會擴展經過__proto__擴展的方法或屬性的
function Foo() { } Foo.__proto__.test = "__proto__ test property found";// 經過__proto__擴展 Foo.__proto__.addextend = function() { document.write("Foo add extend by __proto__"); document.write("<br>"); } Foo.addextend();// 能夠執行 var foo = new Foo; document.write("Foo:" + Foo.test);// 能夠訪問 document.write("<br>"); document.write(foo.addextend);// 未定義 document.write("<br>"); document.write("Foo instance:" + foo.test);// 未定義 document.write("<br>");?
?
?對於prototype來講,它是針對對象的,也就是Function是沒法使用的,只有new出來的纔能有效
?
function Foo() { } Foo.prototype.test="prototype test property found"; Foo.prototype.addextend=function(){ document.write("Foo add extend by prototype"); document.write("<br>");} document.write(Foo.addextend());//未定義 document.write("<br>") var foo=new Foo; document.write("Foo:"+Foo.test);//沒法訪問 document.write("<br>") foo.addextend();//能夠執行 document.write("foo instance:"+foo.test);//找到了 document.write("<br>"?
?
Object.__proto__.test4extend="123";//擴展Object的原型 ? alert("Function:"+Function.test4extend);//在Function中出現了test4extend屬性 ? alert("Object:"+Object.test4extend);//在Object中出現了test4extend屬性,此時Object仍是個Function ? var obj=new Object; alert("Object instance:"+obj.test4extend);//未定義 ? function Foo() { ? } ? var foo = new Foo; alert("foo object:"+foo.test4extend);//未定義 ? alert("Function:"+Foo.test4extend);//函數上也擴展上了test4extend屬性?
?【總結】
Function擴展自Object,可是Function對Object又有影響,這是經過Object.__proto__就是(===)Function.prototype創建的聯繫。記住這個聯繫後,咱們還要記住__proto__和prototype的區別,前者擴展的只能夠被Function直接調用,後者擴展的只能夠經過其實例調用。另外,還要注意__proto__和prototype的鏈的概念,這是由於,他們能夠互相關聯,訪問到Function或Ojbect的內容。