JS Object和Function的區別
阿新 • • 發佈:2019-02-17
接下來看看第二個問題
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__是Function的prototype是Object。
- 在Function中__proto__是Function的prototype也是Object。
- 現在讓我們再來結合第三行的圖看一看。有如下關係。
Function.__proto__就是(===)Function.prototype
Object.__proto__就是(===)Function.prototype - Function的__proto__和prototype就是一個,擴充套件任何一個都是相同的效果。Object的__proto__就是Function.prototype。當我們擴充套件Object.__proto__時,就相當於擴充套件了Function.prototype和__proto__,反之亦然。
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的內容。